程序员

Nodejs中的JWT和Session

2018-03-07  本文已影响3647人  单调先生

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

使用JWT

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

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

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

这里使用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();
})

对比

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

上一篇 下一篇

猜你喜欢

热点阅读