koa+jwt实现token验证与刷新

更新日期: 2019-05-31阅读: 3.7k标签: token

JWT

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

本文只讲Koa2 + jwt的使用,不了解JWT的话请到这里)进行了解。


koa环境

要使用koa2+jwt需要先有个koa的空环境,搭环境比较麻烦,我直接使用koa起手式,这是我使用koa+typescript搭建的空环境,如果你也经常用koa写写小demo,可以点个star,方便~


安装koa-jwt

koa-jwt主要作用是控制哪些路由需要jwt验证,哪些接口不需要验证:

import  *  as  koaJwt  from  'koa-jwt';

//路由权限控制 除了path里的路径不需要验证token 其他都要
app.use(
    koaJwt({
        secret:  secret.sign
    }).unless({
        path: [/^\/login/, /^\/register/]
    })
);

上面代码中,除了登录、注册接口不需要jwt验证,其他请求都需要。


使用jsonwebtoken生成、验证token

执行npm install jsonwebtoken安装jsonwebtoken
相关代码:

import  *  as  jwt  from  'jsonwebtoken';

const secret = 'my_app_secret';
const payload = {user_name:'Jack', id:3, email: '1234@gmail.com'};
const token = jwt.sign(payload, secret, { expiresIn:  '1h' });

上面代码中通过jwt.sign来生成一个token,
参数意义:

  • payload:载体,一般把用户信息作为载体来生成token
  • secret:秘钥,可以是字符串也可以是文件
  • expiresIn:过期时间 1h表示一小时


在登录中返回token

import * as crypto from 'crypto';
import * as jwt from 'jsonwebtoken';

async login(ctx){

  //从数据库中查找对应用户
  const user = await userRespository.findOne({
    where: {
      name: user.name
    }
  });

  //密码加密
  const psdMd5 = crypto
    .createHash('md5')
    .update(user.password)
    .digest('hex');

  //比较密码的md5值是否一致 若一致则生成token并返回给前端
  if (user.password === psdMd5) {
    //生成token
    token = jwt.sign(user, secret, { expiresIn:  '1h' });
    //响应到前端
    ctx.body = {
      token
    }
  }

}


前端拦截器

前端通过登录拿到返回过来的token,可以将它存在localStorage里,然后再以后的请求中把token放在请求头的Authorization里带给服务端。
这里以axios请求为例,在发送请求时,通过请求拦截器把token塞到header里:

//请求拦截器
axios.interceptors.request.use(function(config) {
    //从localStorage里取出token
    const token = localStorage.getItem('tokenName');
    //把token塞入Authorization里
    config.headers.Authorization = `Bearer ${token}`;
    
    return config;
  },
  function(error) {
    // Do something with request error
    return Promise.reject(error);
  }
);


服务端处理前端发送过来的Token

前端发送请求携带token,后端需要判断以下几点:

  1. token是否正确,不正确则返回错误
  2. token是否过期,过期则刷新token 或返回401表示需要从新登录

关于上面两点,需要在后端写一个中间件来完成:

app.use((ctx, next) => {
  if (ctx.header && ctx.header.authorization) {
    const parts = ctx.header.authorization.split(' ');
    if (parts.length === 2) {
      //取出token
      const scheme = parts[0];
      const token = parts[1];
      
      if (/^Bearer$/i.test(scheme)) {
        try {
          //jwt.verify方法验证token是否有效
          jwt.verify(token, secret.sign, {
            complete: true
          });
        } catch (error) {
          //token过期 生成新的token
          const newToken = getToken(user);
          //将新token放入Authorization中返回给前端
          ctx.res.setHeader('Authorization', newToken);
        }
      }
    }
  }

  return next().catch(err => {
    if (err.status === 401) {
      ctx.status = 401;
      ctx.body =
        'Protected resource, use Authorization header to get access\n';
    } else {
      throw err;
    }});
 });   

上面中间件是需要验证token时都需要走这里,可以理解为拦截器,在这个拦截器中处理判断token是否正确及是否过期,并作出相应处理。


后端刷新token 前端需要更新token

后端更换新token后,前端也需要获取新token 这样请求才不会报错。
由于后端更新的token是在响应头里,所以前端需要在响应拦截器中获取新token。
依然以axios为例:

//响应拦截器
axios.interceptors.response.use(function(response) {
    //获取更新的token
    const { authorization } = response.headers;
    //如果token存在则存在localStorage
    authorization && localStorage.setItem('tokenName', authorization);
    return response;
  },
  function(error) {
    if (error.response) {
      const { status } = error.response;
      //如果401或405则到登录页
      if (status == 401 || status == 405) {
        history.push('/login');
      }
    }
    return Promise.reject(error);
  }
);


原文链接:https://segmentfault.com/a/1190000019338195  

链接: https://fly63.com/article/detial/3495

深入理解令牌认证机制(token)

以前的开发模式是以MVC为主,但是随着互联网行业快速的发展逐渐的演变成了前后端分离,若项目中需要做登录的话,那么token成为前后端唯一的一个凭证。token即标志、记号的意思,在IT领域也叫作令牌。

深度理解token

Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库

axios如何利用promise无痛刷新token

最近遇到个需求:前端登录后,后端返回token和token有效时间,当token过期时要求用旧token去获取新的token,前端需要做到无痛刷新token,即请求刷新token时要做到用户无感知。

axios如何利用promise无痛刷新token?

前端登录后,后端返回token和token有效时间段tokenExprieIn,当token过期时间到了,前端需要主动用旧token去获取一个新的token,做到用户无感知地去刷新token。

前后端分离:使用 token 登录解决方案

这篇文章写一下前后端分离下的登录解决方案,目前大多数都采用请求头携带 Token 的形式。首次登录时,后端服务器判断用户账号密码正确之后,根据用户id、用户名、定义好的秘钥、过期时间生成 token

vue+axios设置token,增加请求拦截器

第一次登录的时候,前端调后端的登陆接口,发送用户名和密码,后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token,前端拿到token,将token存储到localStorage和vuex中

Vue 消除Token过期时刷新页面的重复提示

页面长时间未操作,再刷新页面时,第一次弹出“token失效,请重新登录!”提示,然后跳转到登录页面,接下来又弹出了n个“Token已过期”的后端返回消息提示。当前页面初始化,有多个向后端查询系统参数的调用,代码如下:

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!