前言

在浏览器和服务端的交互中,http恳求是无状况的,那在web项目中精确无误的保存用户的登录状况是前后端交互中必须要解决的问题。现在在web端解决登录认证的问题分为三种base64 session/cookie token 下面介绍下token中jwt完成登录验证的方法。

基本概念

了解下几种不同的认证方法

  • base64:这种应该是前期用的比较多,适用于安全性要求不高的网站,经过对客户端的用户名/暗码进行base64编码后然后放到服务器

  • session/cookie:服务器会在用户登录时创立一个Session,其间包含用户的身份信息,服务器将Session ID 发送给客户端,客户端在后续恳求中经过Cookie来传递该Session ID,服务器经过该Session ID 来识别用户身份。

  • token:能够称为令牌,一种通用的术语,这种方法是现在运用最广泛的,他也根据不同的事务场景发展出不同的运用方法,现在常用的token方法有oauth和jwt。

    • json web token(jwt):jwt是token认证的一种,它运用 JSON 目标来存储令牌的信息,并运用数字签名或加密等方法确保令牌的可靠性和安全性。jwt由三个部分组成分别为:header payload signature。
      • 运用json目标存储
      • 数字签名和加密
      • 三个部分
    • oauth(没用过简道介绍下):是一种开发标准,用于授权第三方运用程序访问用户数据,而不必想第三方运用程序揭露用户凭证。例如我们常登陆一些网站能够用微信或支付宝登录,虽然登录了但是并没有运用到微信或支付宝的用户名暗码。oauth一般在大型运用下有多个子运用的项目中运用比较广泛。
  • 以下几种方法的对比

    身份校验 安全性 完成难度
    OAuth2
    JWT
    base64
    Session/Cookie
    以上是现在常用的前后端认证方法,下面我们来详细介绍jwt认证方法的完成。

jwt验证流程

  • 客户端认证:一般是客户端用户输入用户名暗码。
  • 服务端验证身份:假如校验客户端传递的用户名暗码经过,则生成jwt token回来给客户端。
  • 客户端保存:客户端获取到服务端回来的jwt token,之后的每次恳求中在恳求头中带jwt token
  • 服务端验证token:服务端收到jwt token后,解析jwt token并验证其有效性,假如验证经过则回来对应的恳求操作。验证失败则回来401并重新认证。

完成

所需依赖介绍

  • express-jwt:express用来解析jwt的中间件,运用方法很简单只用把其加入到恳求前。express-jwt会主动将jwt的payload部分赋值给req.user
const expressJwt = require('express-jwt');
app.use(expressJwt({ secret: 'secret_key', algorithms: ['HS256'] }));
  • jsonwebtoken:用来在验证身份经往后,生成jwt token
const userInfo = {name:"**",phone:"***"}
//jwt token能够存入用户信息 secret需要保密号
jwt.sign(userInfo, 'secret', { expiresIn: '**' });

运用示例

  • 登录用户时验证身份
import userModel from '../../database/model/user';
import jsonwebtoken from 'jsonwebtoken';
const login =async (req,res,next)=>{
    try{
      const data = req.body;
      const user = data?.user;
      const password = data?.password;
      const userInfo = await userModel.findOne({user});
      //核心逻辑:当用户名暗码校验成功后生成jwt
      if(userInfo?.password === password){
          const secrect = '';
          const token = jwt.sign({ userInfo }, secrect, { algorithm: 'HS256' });
          res.json({code:200,msg:"login successfully!",token})
      }else{
        console.log("user or password error!");
        res.json({code:0,msg:"user or password error!"})
      }
    }catch(e){
        console.log('e: ', e);
    }
}
const logout = (req,res,next)=>{
    try{
        console.log('===========');
    }catch(e){
        console.log('e: ', e);
    }
}
export default {login,logout}
  • 客户端获取token值后放入header中
const token = "******"
request.headers['Authorization'] = `Bearer ${token}`;
  • 恳求时服务端校验token
import express from 'express';
import { expressjwt } from 'express-jwt'
import config from './helpper/config';
import './database/mongo';
const env = process.env.NODE_ENV || 'dev'
const app = express();
// 核心逻辑express-jwt校验token是否合法
app.use(expressjwt({ secret: config[env].secret, algorithms: ["HS256"] }).unless({path:["/user/login"]}))
app.use(express.json());
// 404路由捕获
app.get('*', function (req, res) {
  console.log('Not Found');
  res.sendStatus(404);
});
// 全局错误处理
app.use((err, req, res, next) => {
  if (res.headersSent) {
    return next(err);
  }
  res.status(500);
  res.render('error', { error: err });
});
console.log('config[env]: ', config[env]);
app.listen(config[env]?.port, () => {
  console.log("serve is starting  :" + config[env]?.port);
});

总结

身份校验用来确保数据能安全精确的传递。而如何能安全便利的完成身份的校验是软件开发者一直努力的方向,从最开端的session到如今的token,我们只要保持一颗积极的学习与创新才干确保在程序员这个行业中走得的更远。