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 相关文章推荐
NodeJS学习笔记之FS文件模块
Jan 13 NodeJs
ubuntu下安装nodejs以及升级的办法
May 08 NodeJs
Nodejs进阶:核心模块net入门学习与实例讲解
Nov 21 NodeJs
nodejs入门教程五:连接数据库的方法分析
Apr 24 NodeJs
Nodejs--post的公式详解
Apr 29 NodeJs
NodeJS实现微信公众号关注后自动回复功能
May 31 NodeJs
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
Jan 05 NodeJs
nodejs结合socket.io实现websocket通信功能的方法
Jan 12 NodeJs
nodejs中密码加密处理操作详解
Mar 20 NodeJs
Nodejs实现多文件夹文件同步
Oct 17 NodeJs
详解nodejs解压版安装和配置(带有搭建前端项目脚手架)
Dec 06 NodeJs
详解利用nodejs对本地json文件进行增删改查
Sep 20 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
咖啡店都有些什么常规豆子呢?有什么风味在里面
2021/03/04 咖啡文化
限制ckeditor上传图片文件大小的方法
2013/11/15 PHP
ThinkPHP 3.2 数据分页代码分享
2014/10/14 PHP
PHP实现文件上传功能实例代码
2017/05/18 PHP
thinkphp中U方法按路由规则生成url的方法
2018/03/12 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
在Javascript操作JSON对象,增加 删除 修改的简单实现
2016/06/02 Javascript
微信小程序 网络API 上传、下载详解
2016/11/09 Javascript
jQuery中DOM节点的删除方法总结(超全面)
2017/01/22 Javascript
vue实现验证码输入框组件
2017/12/14 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
2018/02/03 Javascript
vue通过点击事件读取音频文件的方法
2018/05/30 Javascript
js实现左右两侧浮动广告
2018/07/09 Javascript
Node.js Koa2使用JWT进行鉴权的方法示例
2018/08/17 Javascript
angular 数据绑定之[]和{{}}的区别
2018/09/25 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
2019/01/18 jQuery
JS+CSS实现动态时钟
2021/02/19 Javascript
Python中最常用的操作列表的几种方法归纳
2015/04/24 Python
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
Python入门_浅谈字符串的分片与索引、字符串的方法
2017/05/16 Python
Python中extend和append的区别讲解
2019/01/24 Python
Pytorch Tensor基本数学运算详解
2019/12/30 Python
Python爬虫HTPP请求方法有哪些
2020/06/03 Python
Python虚拟环境的创建和包下载过程分析
2020/06/19 Python
ubuntu16.04升级Python3.5到Python3.7的方法步骤
2020/08/20 Python
CSS3用@font-face实现自定义英文字体
2013/09/23 HTML / CSS
我的applet原先好好的, 一放到web server就会有问题,为什么?
2016/05/10 面试题
AOP的定义以及作用
2013/09/08 面试题
科室工作的个人自我评价
2013/10/30 职场文书
护理职业生涯规划书
2014/01/24 职场文书
农村优秀教师事迹材料
2014/08/27 职场文书
一年级数学上册复习计划
2015/01/17 职场文书
中职班主任培训心得体会
2016/01/07 职场文书
闭幕词的写作格式与范文!
2019/06/24 职场文书
CentOS7和8下安装Maven3.8.4
2022/04/07 Servers