node注册登录到jwt(token)鉴权实现

前言

本内容是在egg框架中的相关实现,主要是在登录注册时利用bcrypt库对密码的处理,和利用egg-jwt实现token的生成和校验

一、登录注册实现

1,注册对密码加

注册主要是把用户提交的信息保存起来,重点是密码的处理,把密码加密后保存在数据库有利于更好地保护我们的用户信息。接下来,我们将使用Bcrypt为我们的用户密码加盐并散列。

Bcrypt早在1996年就存在,并且经过多年的大量网站的使用和验证,鲜有报道出来的问题。可以说他的这一套算法是很安全的。

散列(hash) 的意思是给一段普通文字使用算法加密,使他变成一个固定长度的字符串。不管这段文字有多长,经过算法处理后的最终的结果都将是相同长度。并且每次的结果都将完全相同。

盐 (salt) 是一个随机的字符串。如果你在hash的时候加入盐作为干扰的话,那么结果就不会再保持相同了。盐会被自动加到hash里面

js 复制代码
// 安装bcryptjs
npm install bcryptjs

// 引入
const bcrypt = require('bcryptjs');

// 注册接口
register(params) {
    // bcrypt 库 对密码加密
    const { ctx } = this
    const params = ctx.request.body
    const saltRounds = 10
    var hash = bcrypt.hashSync(params.password, saltRounds);
    var user = await ctx.model.Users.create({ // 数据入库
      name: params.name,
      password: hash,
      ...params
    });
    ctx.success('注册成功')
}

saltRounds。saltRounds 代表加密所需的时间,saltRounds越大,加密所需时间越长,加密后的密码也就越安全。但是我们也不想让用户永远等着我们加密密码,所以一般使用默认值10就可以。

2,登录对密码校验和token下发

密码校验使用 bcrypt.compare(password1, password2) 返回布尔值,如果密码和hash吻合的话,就返回true,反之false。

生成token用 egg-jwt

js 复制代码
// 安装
npm i egg-jwt -S

// 配置config/plugins.js
jwt: {
  enable: true,
  package: 'egg-jwt',
}

// 配置 config/config.default.js
config.jwt = {
    secret: 'xxxxxxxxx', // 自定义 token 的加密条件字符串
    expiresIn: '7d', // 过期时间
}
js 复制代码
login() {
    const { ctx, app } = this
   // 查询数据库是否有该用户
    var targetUser = await ctx.model.Users.findOne({
      where: {
        account: params.account
      }
    });
    if (!targetUser) { // 用户不存在
      return ctx.error('用户或密码错误');
    }
    const params = ctx.request.body
    // 密码一致性校验。password1用户提交的密码,password2是数据库保存的密码(一串hash密文)
    const match = await bcrypt.compare(params.password, targetUser.dataValues.password);
    // 返回**布尔值**,如果密码和hash吻合的话,就返回true,反之false。
    if (match) {
      // 获取config中jwt配置
      const { secret, expiresIn } = app.config.jwt;
      // 生成token,往token里存储用户信息,secret'秘钥,expiresIn 过期时间
      const token = app.jwt.sign(targetUser.dataValues, secret, { expiresIn });
      
      // 把token返回前端
      targetUser.dataValues.token = token;
       // 过滤返回数据 密码,删除时间
      delete targetUser.dataValues.password;
      ctx.success(targetUser)
    } else {
      return ctx.error('用户或密码错误');
    }
}

3,接口需要token校验的话,在路由中间件注入jwt,请求头需要加上Authorization: Bearer + 空格 + token

js 复制代码
// routes/users.js
module.exports = app => {
  const { router, controller, jwt } = app;
  // 获取用户列表
  router.get("xxx/list", jwt, controller.users.getUserList); // jwt以中间件注入,在调用时会触发token校验

4,无感刷新token

1, 使用两个token: accessToken和refreshToken

  • accessToken用来鉴权,其有效期很短,即使被盗,影响也较小
  • refreshToken只用来刷新accessToken的时间.其有效期很长,作用只是用来刷新token,即使被盗影响也不大

新增刷新接口

js 复制代码
// 签发无感刷新使用的token
function generateReFreshToken(user) { 
    const refreshOptions = { 
        expiresIn: '10d'
    }
    const payload = { username: user.username };
    return jwt.sign(payload, secret, refreshOptions); 
}

// 无感刷新token。该接口需要带上refreshToken,jwt会验证refreshToken是否过期
app.get('/refreshToken', jwt, (req,res) => {
  const {username,password} = req.user
  // 新token
  const token = generateToken({username,password})
  // 新refreshToken
  const refreshToken = generateReFreshToken({username,password})
  res.send({
    data: {
      token,refreshToken
    },
    success: true,
  })
})

//登录接口也要改一下 登录时将refreshToken也返回
相关推荐
程序员爱钓鱼5 小时前
Node.js 编程实战:测试与调试 —— Mocha / Jest / Supertest 使用指南
前端·后端·node.js
冴羽7 小时前
JavaScript Date 语法要过时了!以后用这个替代!
前端·javascript·node.js
张洪权8 小时前
node fs 模块核心 api
node.js
天远数科9 小时前
Node.js全栈实战:构建基于天远多头借贷行业风险版API的BFF风控层
大数据·node.js
_Kayo_10 小时前
Node.js 学习笔记6
笔记·学习·node.js
winfredzhang10 小时前
[实战] Node.js + DeepSeek 打造智能档案归档系统:从混乱到有序的自动化之旅
css·node.js·js·deepseek api
亮子AI10 小时前
【Node.js】为什么数据库连接总是中断?
数据库·node.js
亮子AI10 小时前
【MySQL】node.js 如何批量更新数据?
数据库·mysql·node.js
One_Piece_Fu10 小时前
2026年node.js最新版下载(24.12.0LTS)安装教程(详细)
vscode·学习·node.js
之恒君1 天前
Node.js 模块加载 - 4 - CJS 和 ESM 互操作避坑清单
前端·node.js