基于token的身份验证在nodejs中的应用

token验证大致流程

  • 客户端使用用户名跟密码请求登录
  • 服务端收到请求,去验证用户名与密码
  • 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  • 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  • 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  • 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

代码实践

1、用户名密码校验成功后,生成token并返回

// 登录成功后返回该用户信息
        const result = await this.UserService.login(email, newPas);
        if (result.length > 0) {
          // 校验成功,生成token并返回
          // expiresIn过期时间支持单位 days, hours, etc,例如 "2 days", "10h", "7d",默认使用毫秒单位 “120”或者"120ms"
          const token = this.app.jwt.sign({ userid: result[0].userid, username: result[0].username },
            this.app.config.jwt.secret, { expiresIn: '1h' });
          response = this.ResultResponse.createBySuccessData(token);
        } else {
          response = this.ResultResponse.createByErrorMsg('密码输入不正确');
        }

2、客户端拿到token后将token存储到cookie中,在请求需要权限的接口将token通过header的形式携带过去

// 将token存储到cookie中
          const token = response.data
          Cookies.set('token', token)


getMemberProfile: () => {
    return fetch(`${apiUrl}/api/v2/user/profile`, {
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        Authorization: `Bearer ${Cookies.get('token')}`
      }
    })
      .then(response => response.json())
      .then(response => {
        if (response.code === 0) {
          return response.data
        }
      })
  },

3、编写一个用于校验token的中间件,如果过期或者不合法则跳转到登录页面

module.exports = app => {
  return async function verifyToken(ctx, next) {
    const authorization = ctx.request.header.authorization;
    if (authorization) {
      try {
        // 通过app.jwt.verify验证token合法性
        // iat: 1581434960  token签发时间   exp: 1581438560   token过期时间
        const token = authorization.split(' ')[1];
        app.jwt.verify(token, app.config.jwt.secret);
        // 只有在通过之后才会执行下一个中间件
        await next();
      } catch (error) {
        ctx.body = ctx.response.ResultResponse.createByErrorCodeMsg('10001', error.message);
      }
    } else {
      ctx.body = ctx.response.ResultResponse.createByErrorCodeMsg('10001', 'not allow');
    }
  };
};

4、在路由处使用该中间件

module.exports = app => {
  const verifyToken = app.middleware.verifyToken(app);
  app.router.post('/api/v2/post/add', verifyToken, app.controller.v2.postsController.postsAdd);
};

5、从token中获取用户信息id,然后在需要的地方调用该方法

  getUserid() {
    const authorization = this.ctx.request.header.authorization;
    const token = authorization.split(' ')[1];
    const userid = this.app.jwt.verify(token).userid;
    return userid;
  }

参考阅读

原文地址:https://www.cnblogs.com/fozero/p/12372508.html