最近研究了下基于token的身份验证,并将这种机制整合在个人项目中。现在很多网站的认证方式都从传统的seesion+cookie转向token校验。对比传统的校验方式,token确实有更好的扩展性与安全性。

传统的session+cookie身份验证

由于HTTP是无状态的,它并不记录用户的身份。用户将账号与密码发送给服务器后,后台通过校验,但是并没有记录状态,于是下一次用户的请求仍然需要校验身份。为了解决这一问题,需要在服务端生成一条包含用户身份的记录,也就是session,再将这条记录发送给用户并存储在用户本地,即cookie。接下来用户的请求都会带上这条cookie,若客户端的cookie与服务端的session能对应上,则说明用户身份验证通过。

token身份校验

流程大致如下:

  • 第一次请求时,用户发送账号与密码
  • 后台校验通过,则会生成一个有时效性的token,再将此token发送给用户
  • 用户获得token后,将此token存储在本地,一般存储在localstorage或cookie
  • 之后的每次请求都会将此token添加在请求头里,所有需要校验身份的接口都会被校验token,若token解析后的数据包含用户身份信息,则身份验证通过。

对比传统的校验方式,token校验有如下优势:

  • 在基于token的认证,token通过请求头传输,而不是把认证信息存储在session或者cookie中。这意味着无状态。你可以从任意一种可以发送HTTP请求的终端向服务器发送请求。
  • 可以避免CSRF攻击
  • 当在应用中进行 session的读,写或者删除操作时,会有一个文件操作发生在操作系统的temp 文件夹下,至少在第一次时。假设有多台服务器并且 session 在第一台服务上创建。当你再次发送请求并且这个请求落在另一台服务器上,session 信息并不存在并且会获得一个“未认证”的响应。我知道,你可以通过一个粘性 session 解决这个问题。然而,在基于 token 的认证中,这个问题很自然就被解决了。没有粘性 session 的问题,因为在每个发送到服务器的请求中这个请求的 token 都会被拦截。

下面介绍一下利用node+jwt(jwt教程)搭建简易的token身份校验

示例

当用户第一次登录时,提交账号与密码至服务器,服务器校验通过,则生成对应的token,代码如下:

const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');
//生成token的方法
function  generateToken(data){let created = Math.floor(Date.now() / 1000);let cert = fs.readFileSync(path.join(__dirname, '../config/pri.pem'));//私钥let token = jwt.sign({data,exp: created + 3600 * 24}, cert, {algorithm: 'RS256'});return token;
}//登录接口
router.post('/oa/login', async (ctx, next) => {let data = ctx.request.body;let {name, password} = data;let sql = 'SELECT uid FROM t_user WHERE name=? and password=? and is_delete=0', value = [name, md5(password)];await db.query(sql, value).then(res => {if (res && res.length > 0) {let val = res[0];let uid = val['uid'];let token = generateToken({uid});ctx.body = {...Tips[0], data: {token}}} else {ctx.body = Tips[1006];}}).catch(e => {ctx.body = Tips[1002];});});
复制代码

用户通过校验将获取到的token存放在本地:

store.set('loginedtoken',token);//store为插件
复制代码

之后客户端请求需要验证身份的接口,都会将token放在请求头里传递给服务端:

service.interceptors.request.use(config => {let params = config.params || {};let loginedtoken = store.get('loginedtoken');let time = Date.now();let {headers} = config;headers = {...headers,loginedtoken};params = {...params,_:time};config = {...config,params,headers};return config;
}, error => {Promise.reject(error);
})
复制代码

服务端对所有需要登录的接口均拦截token并校验合法性。

function verifyToken(token){let cert = fs.readFileSync(path.join(__dirname, '../config/pub.pem'));//公钥try{let result = jwt.verify(token, cert, {algorithms: ['RS256']}) || {};let {exp = 0} = result,current = Math.floor(Date.now()/1000);if(current <= exp){res = result.data || {};}}catch(e){}return res;}app.use(async(ctx, next) => {let {url = ''} = ctx;if(url.indexOf('/user/') > -1){//需要校验登录态let header = ctx.request.header;let {loginedtoken} = header;if (loginedtoken) {let result = verifyToken(loginedtoken);let {uid} = result;if(uid){ctx.state = {uid};await next();}else{return ctx.body = Tips[1005];}} else {return ctx.body = Tips[1005];}}else{await next();}
});
复制代码

本示例使用的公钥与私钥可自己生成,操作如下:

  1. 打开命令行工具,输入openssl,打开openssl;
  2. 生成私钥:genrsa -out rsa_private_key.pem 2048
  3. 生成公钥: rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

阅读原文 点此查看node后台代码

点此查看前端代码

node实现基于token的身份验证相关推荐

  1. 基于 Token 的身份验证:JSON Web Token

    最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twitter,Google+,Github 等等, 比起传统的身份验证方法,Token 扩展性更强 ...

  2. 用户数据表设计借鉴 浅谈数据库用户表结构设计,第三方登录 基于 Token 的身份验证

    最近对用户数据表的设计比较感兴趣,看到了两篇比较好的文章. 浅谈数据库用户表结构设计,第三方登录 转载于: https://www.cnblogs.com/jiqing9006/p/5937733.h ...

  3. PHP无状态对象,(PHP)基于Token的身份验证中对无状态的理解

    假设我们设计的Token储存的信息为: 用户名.发行时间.过期时间.签名 在用户登录成功后,我们获取到用户的用户名.此时的时间戳,并将它们和我们设置的过期时间拼接在一起,组成一个字符串,假设为: $i ...

  4. 基于Token进行身份验证

    1.基于服务器的验证 我们都是知道HTTP协议是无状态的,这种无状态意味着程序需要验证每一次请求,从而辨别客户端的身份.  在这之前,程序都是通过在服务端存储的登录信息来辨别请求的.这种方式一般都是通 ...

  5. 基于 Token 的身份验证方法

    基于 Token 的身份验证方法 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的:客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成 ...

  6. 【转】基于Token的身份验证原理

    目录 1 发展史 2 Cookie 3 Session 3.1 cookie和session的区别 4 Token 4.1 传统方式--基于服务器的验证 4.2 基于服务器验证方式暴露的一些问题 4. ...

  7. 基于Token的身份验证——JWT

    原文:基于Token的身份验证--JWT 初次了解JWT,很基础,高手勿喷. 基于Token的身份验证用来替代传统的cookie+session身份验证方法中的session. JWT是啥? JWT就 ...

  8. 基于Token的身份验证的原理

    目录 1 发展史 2 Cookie 3 Session 3.1 cookie和session的区别 4 Token 4.1 传统方式--基于服务器的验证 4.2 基于服务器验证方式暴露的一些问题 4. ...

  9. 基于 Token 的身份验证和安全问题

    1 前言 最近为了学习 Token 知识,博主在网上狂搜资料,其中发现了两篇博文对 Token 的讲解特别详细的,博主看过之后感觉受益匪浅,现将两篇博文整合成一篇博文发布出来,从而分享给大家,希望能够 ...

最新文章

  1. 学习资源:在线学习 Python(二)
  2. 仅用 480 块 GPU 跑出万亿参数!全球首个“低碳版”巨模型 M6 来了
  3. 开发打开设置洁面_用华为手机,这4个功能一定要打开,不然你的手机只会越用越卡!...
  4. vue实现两个数组的合并
  5. linux下使用odbc连接mysql_Linux环境下通过ODBC访问MSSql Server
  6. 什么是COM组件(ZT)
  7. HetSANN:基于注意力模型,自动挖掘异质网络语义信息 AAAI2020
  8. jsp中的四种对象作用域
  9. ios mysql 创建不同的用户表_移动端iOS系统数据库之Realm(二)表的创建增删改查(多表)...
  10. TypeScript入门教程
  11. 【知识科普】嵌入式软件开发是什么?
  12. 基于php的企业公文流转审批系统
  13. 双系统卸载Linux,重装Deepin
  14. JAVA 三种方式计算1加到100的结果
  15. iOS上栈溢出崩溃详解
  16. Springboot项目整合xxl -job
  17. flying-saucer-pdf预览及下载
  18. Mysql期初数和期末数_账户中记录四种核算指标,即期初余额、 本期增加发生额、本期减少发生额和期末余额。其关系式包括( )。_学小易找答案...
  19. 货郎问题和计算复杂度
  20. 如图一显示了用计算机模拟,(全套打包)北京市各区2017年中考模拟试题汇编·数学...

热门文章

  1. https://gogs.io/
  2. 作业4:结对编程项目四则运算
  3. HDU 1358 Period KMP
  4. Linux驱动下的platform总线架构(转)
  5. 类的垂直关系中,如何把握纯虚函数
  6. C++提高部分_C++函数模板的概念---C++语言工作笔记080
  7. Netty工作笔记0047---Http服务程序实例
  8. C#.net工作笔记001---Linq对象查询,排序,分组,去重在工作中的使用_随时更新
  9. VB.NET工作笔记006---用visual studio2017 编写RESTFUL API
  10. RabbitMq学习笔记001---RabbitMq在Windows下安装配置