express使用token实现登录操作

用session实现用户识别 有两缺点
(1)其实session也是通过cookie实现的,大致原理是:当pc向服务器发送请求,服务器就想pc的浏览器发送一个随机字符串来标识这台主机,然后如果pc登录成,服务器就在后台的账本上记住,这个随机字符和对应的用户id,
cookie每次请求会自动携带,所以只要cookie不变,服务器就会知道,这个随机字符串就对应的某个用户。但是由于没次请求就会自动带上cookie,这有一定安全问题,例如:当你之前登录过某个银行网站,他们使用session的方式,你再在某个钓鱼网站点击别人定制的链接,就可能在钓鱼网站登录了银行网站执行某些操作,因为这种不受浏览器同源策略限制,而使用token,他一般不会自动提交,就没有这个问题了,钓鱼网站无法获得token
(2)token是不存储在服务器上的,所以不用存储空间,但是他需要解密,加密,
它实际上token就是一段服务发送给pc加密的有用户id的字符串,只有服务器才能服务器才能解密,而且不是cookie,了解了基本原理就可以知道他的实现步骤了
例如登录:
(1)当用户请求端口的时候,服务器检测是否有token,说登录过,返回相应页面数据
(2)请求登录接口时候,验证用户名和密码是否正确,如果正确,返回 存储用户id或者用户名的加密token,给pc
(3)前端查看有没有token,有的话,存储到localStorage,
(3)之后前端每次请求读取localStorage的token都携带上
只要localStorage在那么就一直是登录状态
代码如下:
token.js

let jwt = require('jsonwebtoken') //生成token
const { expressjwt } = require('express-jwt') // 解码token

let jwtScrect = 'xdfdfsdfdsxfd' //签名

//登录接口 生成token的方法
let setToken = function(user_name, user_id, expiresIn) {
  //expiresln 设置token过期的时间
  //{ user_name: user_name, user_id: user_id } 传入需要解析的值( 一般为用户名,用户id 等)
  return jwt.sign(
    { user_name: user_name, user_id: user_id },
    jwtScrect,
    { expiresIn }
  ) // 返回一个token

}

//各个接口需要验证token的方法
let getToken = function(token) {
  if (!token) {
    console.log('token是空的')
    return 0
  } else {
    //第二种  改版后的

    let info = null
    try {
      info = jwt.verify(token, jwtScrect)
    } catch (e) {
      return 0
    }

    //解析返回的值(sign 传入的值)  返回一个token的明码
    return info
  }
}

// 解析token

let decodeToken = expressjwt({
  credentialsRequired: true, //需要校验
  secret: jwtScrect, // 加密秘钥
  algorithms: ['HS256'] // 加密方式
}).unless({
  path: [
    '/admin',
    '/login',
    /^\/static/,
    '/captcha',
    '/',
    '/userinfo', // 单独校验
    '/favicon.ico',
    /^\/img/,
    /^\/data/
  ] // 不需要校验的路径
  // path: ["/admin","/login"/^(\/admin|\/|\/login)/],
})

// 处理解析错误

// 定义错误中间件
// middleware/errorhandler.js
function errorToken(err, req, res, next) {
  //console.log("token出现错误这一步->>", err, err.name, "《-----");
  let code = 500
  let message = 'Internal Server Error'
  // token解析的错误
  if (err.name === 'UnauthorizedError') {
    code = 401
    message = 'token 解析错误'
  }
  res.statusCode = code
  res.send({
    status: code,
    message
  })
}
//导出
let errorHandler = (module.exports = {
  setToken,
  getToken,
  decodeToken,
  errorToken
})

其中:1.setToken是生成一个加密的token字符串,我这里定义的参数是(用户名,用户id,过期时间) ,
登录成功发送给token前端的时候使用,
2.getToken是将前端发过来的Token,解密为之前的参数(用户名,用户id,过期时间)
这个是用于返回用户id或者用户名这些值的,或者在数据库通过id查询用户更多信息时候使用
3.decodeToken是配置token,及那些路径我们不验证token,配置加密方式,加密的密钥等
4.errorToken就是配置,当需要验证token的路径,没有token,或者token是错的,我们如何错误提示

3.4是中间件,要使用.use安装

// 导入token
let {
  decodeToken,
  errorToken,
} = require("./utility/token");

// 解析toke
app.use(decodeToken);
// 处理错误
// 错误中间件写在最后
app.use(errorToken);

setToken:登录成功后返回token

      res.json({
              code: 1,
              msg: "登陆成功",
              data: results[0].username,
              token: token.setToken(
                results[0].username,
                results[0].id,
                "3600s"
              ), // 设置头
            });

getToken:验证是否登录返回用户名

   // 有登陆过
      res.json({
        code: 1,
        data: {
          username: token.getToken(req.headers["authorization"].split(" ")[1])
            .user_name,
        },
        msg: "已经登陆",
      });
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值