经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
koa+jwt实现token验证与刷新功能
来源:jb51  时间:2019/5/31 8:36:07  对本文有异议

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验证,哪些接口不需要验证:

  1. import * as koaJwt from 'koa-jwt';
  2. //路由权限控制 除了path里的路径不需要验证token 其他都要
  3. app.use(
  4. koaJwt({
  5. secret: secret.sign
  6. }).unless({
  7. path: [/^\/login/, /^\/register/]
  8. })
  9. );

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

使用jsonwebtoken生成、验证token

执行npm install jsonwebtoken安装jsonwebtoken

相关代码:

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

上面代码中通过jwt.sign来生成一个token,

参数意义:

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

在登录中返回token

  1. import * as crypto from 'crypto';
  2. import * as jwt from 'jsonwebtoken';
  3. async login(ctx){
  4. //从数据库中查找对应用户
  5. const user = await userRespository.findOne({
  6. where: {
  7. name: user.name
  8. }
  9. });
  10. //密码加密
  11. const psdMd5 = crypto
  12. .createHash('md5')
  13. .update(user.password)
  14. .digest('hex');
  15. //比较密码的md5值是否一致 若一致则生成token并返回给前端
  16. if (user.password === psdMd5) {
  17. //生成token
  18. token = jwt.sign(user, secret, { expiresIn: '1h' });
  19. //响应到前端
  20. ctx.body = {
  21. token
  22. }
  23. }
  24. }

前端拦截器

前端通过登录拿到返回过来的token,可以将它存在localStorage里,然后再以后的请求中把token放在请求头的Authorization里带给服务端。

这里以axios请求为例,在发送请求时,通过请求拦截器把token塞到header里:

  1. //请求拦截器
  2. axios.interceptors.request.use(function(config) {
  3. //从localStorage里取出token
  4. const token = localStorage.getItem('tokenName');
  5. //把token塞入Authorization里
  6. config.headers.Authorization = `Bearer ${token}`;
  7. return config;
  8. },
  9. function(error) {
  10. // Do something with request error
  11. return Promise.reject(error);
  12. }
  13. );

服务端处理前端发送过来的Token
前端发送请求携带token,后端需要判断以下几点:

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

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

  1. app.use((ctx, next) => {
  2. if (ctx.header && ctx.header.authorization) {
  3. const parts = ctx.header.authorization.split(' ');
  4. if (parts.length === 2) {
  5. //取出token
  6. const scheme = parts[0];
  7. const token = parts[1];
  8. if (/^Bearer$/i.test(scheme)) {
  9. try {
  10. //jwt.verify方法验证token是否有效
  11. jwt.verify(token, secret.sign, {
  12. complete: true
  13. });
  14. } catch (error) {
  15. //token过期 生成新的token
  16. const newToken = getToken(user);
  17. //将新token放入Authorization中返回给前端
  18. ctx.res.setHeader('Authorization', newToken);
  19. }
  20. }
  21. }
  22. }
  23. return next().catch(err => {
  24. if (err.status === 401) {
  25. ctx.status = 401;
  26. ctx.body =
  27. 'Protected resource, use Authorization header to get access\n';
  28. } else {
  29. throw err;
  30. }});
  31. });

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

后端刷新token 前端需要更新token
后端更换新token后,前端也需要获取新token 这样请求才不会报错。

由于后端更新的token是在响应头里,所以前端需要在响应拦截器中获取新token。

依然以axios为例:

  1. //响应拦截器
  2. axios.interceptors.response.use(function(response) {
  3. //获取更新的token
  4. const { authorization } = response.headers;
  5. //如果token存在则存在localStorage
  6. authorization && localStorage.setItem('tokenName', authorization);
  7. return response;
  8. },
  9. function(error) {
  10. if (error.response) {
  11. const { status } = error.response;
  12. //如果401或405则到登录页
  13. if (status == 401 || status == 405) {
  14. history.push('/login');
  15. }
  16. }
  17. return Promise.reject(error);
  18. }
  19. );

总结

以上所述是小编给大家介绍的koa+jwt实现token验证与刷新功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对w3xue网站的支持!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号