express+mySql实现用户注册、登录和身份认证

express+mySql实现用户注册、登录和身份认证

注册

注册时需要对用户密码进行加密入库,提高账户的安全性。用户登录时再将密码以相同的方式进行加密,再与数据库中存储的密码进行比对,相同则表示登录成功。

安装加密依赖包bcryptjs

cnpm install -S bcryptjs

在注册接口中添加加密功能

// 引入对密码进行加密的包
const bcryptjs = require("bcryptjs");
class User {
  register(req, res) {
    let { username, nick_name,  password } = req.body;
    // 先查找注册的用户名是否在数据库中已存在
    const sql = "select * from sys_user where user_name=?";
    pool.query(sql, username, (err, results) => {
      if (err) return res.sendError(err);
      // 找到了要注册的用户名
      if (results.length >= 1) return res.sendError("当前用户名已被占用!");
      // 对密码进行加密,第二个参数可以提高密码的安全性为任意数字
      const password1 = bcryptjs.hashSync(password, 10);
      const SQl = `Insert into sys_user (user_name,password,nick_name) values('${username}', '${password1}', '${nick_name}')`
      pool.query(SQl, (err, data) => {
        if (err) return res.sendError(err);
        if (data.affectedRows !== 1) {
          res.sendError('用户注册失败"');
        } else {
          res.sendSuccess(data);
        }
      })
    })
  }
}

效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

登录

安装加密依赖包jsonwebtoken

jsonwebtokenuaokeyi生成用户登录需要的token信息。

cnpm install -S jsonwebtoken

增加全局token配置文件

在项目根目录的config文件夹下新增taken.js文件,并加入如下配置。

// 全局的配置文件
module.exports = {
  // 设置token加密和解密用到的密钥
  jwtSecretKey: 'qwertyuiop',
  // 设置token的有效期
  expiresIn: '10h',
}

在这里插入图片描述

在登录接口中返回taken信息

// 导入jsonwebtoken
const jwt = require("jsonwebtoken");
// 导入全局配置文件
const taken = require("../config/taken");
class User {
  login(req, res) {
    const { username, password } = req.body;
    // 先查找用户名是否在数据库中,定义sql语句
    const sql = "select * from sys_user where user_name=?";
    pool.query(sql, username, (err, results) => {
      if (err) return res.sendError(err);
      if (results.length !== 1) return res.sendError("当前用户不存在!");
      // 比较密码  compareSync(客户端的密码,数据库中存储的经过加密后的密码)会返回true或false
      const compareResult = bcryptjs.compareSync(password, results[0].password);
      if (!compareResult) {
        return res.sendError("用户密码错误,登录失败!");
      }
      // 密码比对正确,在服务端根据用户信息(用户密码需置空)生成token信息
      const user = { ...results[0], password: "" };
      // 对用户的信息进行加密,生成token字符串
      const tokenStr = jwt.sign(user, taken.jwtSecretKey, {
        expiresIn: taken.expiresIn,
      });
      // 调用res.send将token响应给客户端
      res.sendSuccess("Bearer " + tokenStr)
    })
  }
}

效果展示

在这里插入图片描述

配置系统白名单

白名单是指那些接口不需要提供token信息。

安装解析token的依赖包express-jwt

express-jwt 包需要使用和生成token时相同的密钥。

cnpm install -S express-jwt

修改app.js文件设置系统白名单

// 在路由之前配置解析token的中间件
const { expressjwt: jwt } = require("express-jwt")
// 解析token时需要token的密钥
const taken = require("./config/taken");
// 定义中间件,
// .unless指定哪些接口不需要进行token身份认证(过滤掉swagger页面和login接口)
app.use(
  jwt({ secret: taken.jwtSecretKey, algorithms: ["HS256"] }).unless({
    path: [/^\/api-docs/, '/user/login', '/user/register'],
  })
)

效果展示

在这里插入图片描述
在这里插入图片描述

在其他接口中通过token获取具体的用户信息

在接口中通过req.auth中获取:具体代码如下:

class mineSeam {
	getAll(req, res) {
		console.log(req.auth)
	}
}

在这里插入图片描述

app.js全部代码如下

// 引入express
const express = require("express");
const path = require('path');
const router = require('./routes/index.js');

// 创建服务器的实例对象
const app = express();

// 配置解析表单数据的中间件,内置中间件只能解析application/x-www-form-urlencoded格式的数据
app.use(express.urlencoded({ extended: false }));

// 搭建静态文件服务
app.use(express.static(path.join(__dirname, 'public')));

// 引入swagger配置项
const swaggerSpec = require('./config/swagger')
app.get('/swagger.json', function(req, res) {
  res.setHeader('Content-Type', 'application/json');
  res.send(swaggerSpec);
});

/**
 * 在路由之前封装res.send()
 */
app.use((req, res, next) => {
  // 定义一个输出的函数
  res.sendError = function (err) {
    res.send({
      code: 400,
      msg: err instanceof Error ? err.message : err
    })
  }
  // 定义一个输出的函数
  res.sendSuccess = function (data = null) {
    res.send({
      code: 200,
      msg: '成功',
      data
    })
  }
  next();
})

// 在路由之前配置解析token的中间件
const { expressjwt: jwt } = require("express-jwt");
// 解析token需要token的密钥
const taken = require("./config/taken");
// 定义中间件,需要哪个密钥解析
// algorithms:设置jwt的算法
// .unless指定哪些接口不需要进行token身份认证
app.use(
  jwt({ secret: taken.jwtSecretKey, algorithms: ["HS256"] }).unless({
    path: [/^\/api-docs/, '/user/login', '/user/register'],
  })
)

// 引入路由
router(app);

// 引入校验规则的包,在定义错误级别的中间件时会用到
const joi = require('joi')
// 在所有路由下面调用错误级别的中间件
app.use((err, req, res, next) => {
  // 验证失败导致的错误
  if (err instanceof joi.ValidationError) return res.sendError(err);
  // 未知的错误
  res.sendError(err);
  next();
})

// 启动服务器,3007为端口号,选择一个空闲的端口号
app.listen(3007, () => {
  console.log("Server running at http://127.0.0.1:3007");
})

参考链接

链接1

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Node.js 中实现用户认证和身份验证,可以使用以下步骤来完成: 1. 创建一个后端服务:使用 Node.js 创建一个服务器端应用程序,你可以选择使用 Express、Koa 或者其他适合你的框架来构建。 2. 设置用户数据存储:选择一个数据库系统(如 MongoDB、MySQL、PostgreSQL 等)来存储用户数据。创建一个用户模型,包含用户名、密码等字段,并将用户数据存储在数据库中。 3. 注册新用户:实现用户注册逻辑。当用户注册时,你需要验证用户名是否已存在,并对密码进行加密保存。 4. 用户登录验证:实现用户登录逻辑。当用户登录时,你需要验证用户提供的用户名和密码是否与数据库中的匹配。可以使用加密算法对密码进行比较,比如使用 bcrypt 或者 argon2 进行密码哈希和验证。 5. 生成认证令牌:在用户登录成功后,你可以使用 JSON Web Token(JWT)来生成一个认证令牌。将令牌发送给客户端,并在客户端进行存储(例如在浏览器的本地存储或者 Cookie 中)。 6. 路由保护:在需要进行身份验证的路由上添加中间件来保护这些路由。当客户端发送请求时,验证客户端请求中的令牌是否有效。你可以使用 JWT 库来解析和验证令牌的有效性,确保它没有被篡改。 7. 登出功能:提供登出功能,当用户登出时,删除客户端存储的令牌,并在服务器端使令牌失效。 需要注意的是,用户认证和身份验证的实现可能会涉及到安全性问题,比如密码加密、防止跨站点请求伪造(CSRF)、限制登录尝试次数等。你应该仔细考虑这些问题,并采取适当的安全措施来保护用户数据和系统安全。 同时,建议使用成熟的身份验证库或框架,如 Passport.js、jsonwebtoken 等,来简化开发过程并提供更好的安全性保障。这些库已经提供了许多常见的身份验证和认证功能,可以帮助你更轻松地实现用户认证和身份验证。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值