Nodejs中的JWT和Session的使用


Posted in NodeJs onAugust 21, 2018

最近的项目需要在node服务端做一个用户登录的校验以及权限拦截,专业一点叫用户认证与授权,经过一番收集资料,目前常用的有两种——JWT和Session

使用JWT

JWT是JsonWebTokens的简写形式,具体是啥我就不详细写了,可以查看资料。
这里引入两个插件,express-jwt和JsonWebTokens,-

  1. JsonWebTokens:用作生成token
  2. express-jwt:用作验证指定http请求的JsonWebTokens的有效性,如果有效就将JsonWebTokens的值设置到req.user里面,然后路由到相应的router

express-jwt内部引用了jsonwebtoken,对其封装使用。使用JWT形式进行认证与授权的思路如下。

Nodejs中的JWT和Session的使用

jwt认证流程

在服务端中使用方式如下:

//安装
npm i jsonwebtoken --save
npm i express-jwt --save

//引入
const jwt= require('jsonwebtoken');
const expressJwt = require('express-jwt');

//定义签名
const secret = 'salt';
//生成token
const token = jwt.sign({
  name: 123
}, secret, {
  expiresIn: 60 //秒到期时间
});
//生成的token
//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoxMjMsImlhdCI6MTQ5MTQ3NTQyNCwiZXhwIjoxNDkxNDc1NDg0fQ.hYNC4qFAyhZClmPaLixfN137d41R2CFk1xPlfLK10JU

//使用中间件验证token合法性
app.use(expressJwt ({
  secret: secret 
}).unless({
  path: ['/login', '/getUserInfo'] //除了这些地址,其他的URL都需要验证
}));

//拦截器
app.use(function (err, req, res, next) {
  //当token验证失败时会抛出如下错误
  if (err.name === 'UnauthorizedError') {  
    //这个需要根据自己的业务逻辑来处理( 具体的err值 请看下面)
    res.status(401).send('invalid token...');
  }
});

//定义一个接口,返回token给客户端
app.get('/getUserInfo', function(req, res) {
  res.json({
    token: token
  })
})

客户端中使用token的正确形式应该是把token放在authorization 这个header里, 对应的值以Bearer开头然后空一格

authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiQmluTWFpbmciLCJkYXRhIjoiPT09PT09PT09PT09PSIsImlhdCI6MTUwMTgxNDE4OCwiZXhwIjoxNTAxODE0MjQ4fQ.GoxGlc6E02W5VvqDNawaOrj3MPO-4UYeFdngKR4bVTE

//采用axios可以这么写
const instance = axios.create();
const yourToken = 'sfsgagfdgd';
//设置请求拦截器
instance.interceptors.request.use(function(config) {
  config.headers.authorization = `Bearer ${yourToken}` 
  return config;
})

使用Session

传统的认证和用户识别分别采用如下形式

  • 服务端:创建一个session对象保存用户登录信息和状态,该对象有唯一ID,并返回一个cookie给客户端
  • 客户端:请求api时发送http头部自动带上cookie

这里使用cookie的方式需要引入两个插件:

  • express-session:node端的session中间件,主要用作配置session的属性并生成
  • cookie-parser:node端解析cookie对象

使用思路和JWT差不多,这里主要的区别在于客户端请求资源时不用手动在http请求的header添加标识,浏览器会自动加上cookie,具体使用方式如下

var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('express-session');
 
app.use(cookieParser('sessiontest'));
app.use(session({
  secret: 'sessiontest',//与cookieParser中的一致
  resave: true,  //(是否允许)当客户端并行发送多个请求时,其中一个请求在另一个请求结束时对session进行修改覆盖并保存。
  rolling: true,  //强制在每个响应中重设cookie的过期时间,并重新开始计时
  saveUninitialized:true,  //初始化session时是否保存到存储。默认为true, 但是(后续版本)有可能默认失效,所以最好手动添加。
  cookie: {
    maxAge: 60 * 1000 //过期时间,单位毫秒
  }
}));

/**
 * 资源请求拦截器
 * 用户端若登录状态过期或未登录则自动抛出错误
 */
app.use(function(req, res, next) {
  let url = req.originalUrl;
  req.session.touch(); //刷新session过期时间
  if (url !== '/login' && !req.session.user) {
    res.status(401).send('登录状态已过期');
    return
  }
  next();
})

对比

作为一个实践派人士,我把两种都试了一遍,同时结合网上的博客归纳了如下对比

  1. JWT无状态,可扩展和解耦。使用JWT不需要后端进行记录,每个token都是独立的。而session的诞生就是为了解决http无状态的问题,这也就说明服务端是有存储每个用户对应的session对象的,扩展性会更繁琐些
  2. 跨域和CORS。每次发送请求到后端都需要检查JWT,只要验证通过就能处理请求。而Cookie只能在单域和子域中发挥作用
  3. JWT生成消耗一定的内存,而且体积较大,最小的它都比cookie要大,如果JWT里包含了许多声明,那问题就比较严重了,由于每次向服务器发起请求都要携带token,太大了会造成请求缓慢
  4. session比JWT好的地方在于在请求时浏览器会自动带http头部带上cookie,并且在用户持续使用时会不断地刷新session的过期时间,当浏览器关闭时自动清除session。相比之下JWT本身没法做到随着用户的使用而更新或手动清除,只能等自动过期

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
轻松创建nodejs服务器(7):阻塞操作的实现
Dec 18 NodeJs
浅析nodejs实现Websocket的数据接收与发送
Nov 19 NodeJs
使用nodejs下载风景壁纸
Feb 05 NodeJs
初识NodeJS服务端开发入门(Express+MySQL)
Apr 07 NodeJs
nodejs微信扫码支付功能实现
Feb 17 NodeJs
nodejs中密码加密处理操作详解
Mar 20 NodeJs
NodeJS加密解密及node-rsa加密解密用法详解
Oct 12 NodeJs
基于nodejs的雪碧图制作工具的示例代码
Nov 05 NodeJs
手把手教你如何使用nodejs编写cli命令行
Nov 05 NodeJs
nodejs基础之常用工具模块util用法分析
Dec 26 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 NodeJs
nodejs 如何手动实现服务器
Aug 20 #NodeJs
nodejs实现一个word文档解析器思路详解
Aug 14 #NodeJs
NodeJs项目中关闭ESLint的方法
Aug 09 #NodeJs
nodejs之koa2请求示例(GET,POST)
Aug 07 #NodeJs
NodeJS实现自定义流的方法
Aug 01 #NodeJs
nodejs 生成和导出 word的实例代码
Jul 31 #NodeJs
nodejs(officegen)+vue(axios)在客户端导出word文档的方法
Jul 31 #NodeJs
You might like
php桌面中心(四) 数据显示
2007/03/11 PHP
PHP实现对文本数据库的常用操作方法实例演示
2014/07/04 PHP
PHP+MySQL实现无极限分类栏目的方法
2015/12/23 PHP
php生成图片验证码的方法
2016/04/15 PHP
基于jquery的滚动新闻列表
2010/06/19 Javascript
两种常用的javascript数组去重方法思路及代码
2013/03/26 Javascript
在JavaScript里防止事件函数高频触发和高频调用的方法
2014/09/06 Javascript
浅谈javascript中的instanceof和typeof
2015/02/27 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
2015/03/25 Javascript
javascript实现选中复选框后相关输入框变灰不可用的方法
2015/08/11 Javascript
jQuery实现隔行变色的方法分析(对比原生JS)
2016/11/18 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
2017/05/25 Javascript
修改 bootstrap table 默认detailRow样式的实例代码
2017/07/21 Javascript
angular2路由切换改变页面title的示例代码
2017/08/23 Javascript
Hexo已经看腻了,来手把手教你使用VuePress搭建个人博客
2018/04/26 Javascript
基于Vue.js与WordPress Rest API构建单页应用详解
2019/09/16 Javascript
[02:28]DOTA2亚洲邀请赛附加赛 RECAP赛事回顾
2015/01/29 DOTA
python smtplib模块发送SSL/TLS安全邮件实例
2015/04/08 Python
python实现逆波兰计算表达式实例详解
2015/05/06 Python
Python Matplotlib库入门指南
2015/05/18 Python
python获取文件扩展名的方法
2015/07/06 Python
python实现查找两个字符串中相同字符并输出的方法
2015/07/11 Python
Python制作钉钉加密/解密工具
2016/12/07 Python
TensorFlow利用saver保存和提取参数的实例
2018/07/26 Python
python3使用matplotlib绘制条形图
2020/03/25 Python
python-序列解包(对可迭代元素的快速取值方法)
2019/08/24 Python
pytorch实现线性拟合方式
2020/01/15 Python
Python生成器generator原理及用法解析
2020/07/20 Python
英国知名衬衫品牌美国网站:Charles Tyrwhitt美国
2016/08/28 全球购物
公司门卫岗位职责范本
2014/07/08 职场文书
监考失职检讨书
2015/01/26 职场文书
入伍通知书
2015/04/23 职场文书
2015年七年级班主任工作总结
2015/05/21 职场文书
2015年学校团委工作总结
2015/05/26 职场文书
python执行js代码的方法
2021/05/13 Python
Docker 镜像介绍以及commit相关操作
2022/04/13 Servers