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也返回
相关推荐
猜测76 分钟前
新语法在旧设备上的问题
前端·javascript·node.js
2301_815645383 小时前
node.
node.js
下载居4 小时前
Node.js(Javascript运行环境) 26.1
开发语言·javascript·node.js
灵魂学者4 小时前
使用 pkg 打包 Node.js 项目打包构建 .EXE 桌面应用程序
node.js·build·pkg·.exe
坤盾科技7 小时前
Docker 离线地图服务器搭建实战:Node.js + OpenLayers + MBTiles
linux·javascript·arcgis·docker·node.js
北暮城南7 小时前
使用 nvm 安装与管理多版本 Node.js(Windows)
windows·npm·node.js·nvm
fuquxiaoguang8 小时前
CVE-2026-41690深度解析:一个HTTP请求如何击穿Node.js中间件防线
http·中间件·node.js·cve-2026-41690
Hello--_--World8 小时前
Webpack:Webpack 核心配置、什么是 Loader? 什么是plugin?webpack 构建流程
前端·webpack·node.js
Beginner x_u9 小时前
MCP 实践 01|从 0 搭建 MCP Server:读取简历与 JD,并用 MCP Inspector 测试
ai·node.js·mcp
heyCHEEMS1 天前
如何用 Recast 实现静态配置文件源码级读写
前端·node.js