0


Vue3+nodejs全栈项目(资金管理系统)——后端篇(一)登录、注册

文章目录

初始化

创建项目

  1. 新建node-app文件夹作为项目根目录,并在根目录中运行以下命令,初始化包管理配置文件
npm init -y

在这里插入图片描述

  1. 运行以下命令,安装特定版本express
npm i [email protected]
  1. 在根目录下新建app.js作为项目入口文件,并初始化以下代码:
// 导入express模块const express =require('express')// 导入expressd的服务器实例const app =express()// 调用app.listen方法,指定端口号并启动web服务器
app.listen(3000,()=>{
    console.log(`api server running at http://127.0.0.1:3000`)})

配置跨域

  1. 运行以下命令,安装cors中间件:
npm i [email protected]
  1. app.js 中导入并配置 cors 中间件:
// 导入 cors 中间件const cors =require('cors')// 将 cors 注册为全局中间件
app.use(cors())

配置解析表单数据的中间件

通过如下的代码,配置解析

application/x-www-form-urlencoded

格式的表单数据的中间件:

app.use(express.urlencoded({extended:false}))

安装bodyparser

登录、注册要使用

post

请求 安装

body-parser 
npm install body-parser
const bodyParser =require("body-parser")// 使用body-parse中间件 要放在路由之前//app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

初始化用户路由模块

  1. router 文件夹中,新建 admin.js 文件,作为管理员的路由模块,并初始化代码如下:
const express =require('express')// 创建路由对象const router = express.Router()// 注册
router.post('/register',(req, res)=>{
    res.send('register')})// 登录
router.post('/login',(req, res)=>{
    res.send('login')})// 将路由对象共享出去
module.exports = router
  1. app.js 中,导入并使用管理员路由模块:
// 处理管理员(&用户)登录注册相关的路由const adminRouter =require('./router/admin')
app.use('/api/admin', adminRouter)

抽离用户路由模块中的处理函数

目的:为了保证 路由模块 的纯粹性,所有的 路由处理函数,必须抽离到对应的 路由处理函数模块

  1. /router_handler/admin_handler.js 中,使用 exports 对象,分别向外共享如下两个路由处理函数 :
/**
 * 在这里定义和登录注册相关的路由处理函数
 * 供/router/admin.js模块进行调用
 */// 注册用户的处理函数
exports.register=(req, res)=>{
    res.send('register')}// 登录的处理函数
exports.login=(req, res)=>{
    res.send('login')}
  1. /router/admin.js中的代码修改为如下结构:
const express =require('express')// 创建路由对象const router = express.Router()// 导入登录注册处理函数模块const adminHandler =require('../router_handler/admin_handler')// 注册
router.post('/register', adminHandler.register)// 登录
router.post('/login', adminHandler.login)// 将路由对象共享出去
module.exports = router

登录注册

新建admin表

manage

数据库中,新建

admin

表如下:
在这里插入图片描述

安装并配置mysql模块

在 API 接口项目中,需要安装并配置 mysql 这个第三方模块,来连接和操作 MySQL 数据库

  1. 运行以下命令,安装mysql模块:
npm i [email protected]
  1. 在根目录下中新建/db/index.js文件,在此自定义模块中创建数据库的连接对象:
// 导入mysql模块const mysql =require('mysql')// 创建数据库连接对象const db = mysql.createPool({host:'127.0.0.1',user:'root',password:'IKUN1220',database:'manage'})// 向外共享db数据库连接对象
module.exports = db

注册

检测表单数据是否合法

  1. 判断namepassword是否为空
const adminInfo = req.body
if(!adminInfo.name ||!adminInfo.password){return res.json({status:400,message:'用户名或密码为空'})}

检测用户名是否被占用

  1. 导入数据库操作模块:
const db =require('../db/index')
  1. 定义sql语句:
const sql =`select * from admin where name = ? `
  1. 执行 SQL 语句并根据结果判断用户名是否被占用:
db.query(sql,[adminInfo.name],(err, results)=>{// 执行sql语句失败if(err){return res.send({status:404,message: err.message
        })}// 用户名被占用if(results.length >0){return res.status(400).json('用户名已被注册,请更改后重新注册!')}// TODO: 用户名可用,继续之后流程})

对密码进行加密处理bcryptjs

为了保证密码的安全性,不建议在数据库以 明文 的形式保存用户密码,推荐对密码进行 加密存储

在当前项目中,使用 bcryptjs 对用户密码进行加密,优点:

  • 加密之后的密码,无法被逆向破解
  • 同一明文密码多次加密,得到的加密结果各不相同,保证了安全性
  1. 运行如下命令,安装指定版本的 bcryptjs
npm i [email protected]
  1. /router_handler/admin.js 中,导入 bcryptjs
const bcrypt =require('bcryptjs')
  1. 在注册用户的处理函数中,确认用户名可用之后,调用bcrypt.hashSync(明文密码, 随机盐的长度)方法,对用户的密码进行加密处理:
// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
adminInfo.password = bcrypt.hashSync(adminInfo.password,10)

插入新用户

  1. 定义插入用户的sql语句
const sqlStr ='insert into admin set ?'
  1. db.query()
    
    执行 SQL 语句,插入新用户:
db.query(sqlStr,{name: adminInfo.name,password: adminInfo.password,identify: adminInfo.identify },(err, results)=>{if(err){return res.send({status:400,message: err.message
       })}if(results.affectedRows !==1){return res.status(400).json('注册用户失败,请稍后再试')}

   res.json({status:200,message:'注册成功',name: adminInfo.name,password: adminInfo.password,identify: adminInfo.identify
   })})})

此时

router_handler/amdin_handler.js

为:

/**
 * 在这里定义和登录注册相关的路由处理函数
 * 供/router/admin.js模块进行调用
 */const db =require('../db/index')const bcrypt =require('bcryptjs')// 注册用户的处理函数
exports.register=(req, res)=>{const adminInfo = req.body
    if(!adminInfo.name ||!adminInfo.password){return res.json({status:400,message:'用户名或密码为空'})}const sql =`select * from admin where name = ? `
    db.query(sql,[adminInfo.name],(err, results)=>{if(err){return res.send({status:404,message: err.message
            })}if(results.length >0){return res.status(400).json('用户名已被注册,请更改后重新注册!')}// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
        adminInfo.password = bcrypt.hashSync(adminInfo.password,10)const sqlStr ='insert into admin set ?'
        db.query(sqlStr,{name: adminInfo.name,password: adminInfo.password,identify: adminInfo.identify },(err, results)=>{if(err){return res.send({status:400,message: err.message
                })}if(results.affectedRows !==1){return res.status(400).json('注册用户失败,请稍后再试')}

            res.json({status:200,message:'注册成功',name: adminInfo.name,password: adminInfo.password,identify: adminInfo.identify
            })})})}// 登录的处理函数
exports.login=(req, res)=>{
    res.send('login')}

测试

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

登录

根据名字查询用户的数据

  1. 接收表单数据:
const adminInfo = req.body
  1. 定义sql语句:
const sql =`select * from admin where name = ?`
  1. 执行sql语句,查询用户的数据:
db.query(sql, adminInfo.name,(err, results)=>{if(err){return res.status(400).json(err)}if(results.length !==1){return res.status(400).json('用户不存在')}})

判断用户输入的密码是否正确

核心实现思路:调用

bcrypt.compareSync(用户提交的密码, 数据库中的密码)

方法比较密码是否一致
返回值是布尔值(true 一致、false 不一致)

// 拿着用户输入的密码,和数据库中存储的密码进行对比const compareResult = bcrypt.compareSync(adminInfo.password, results[0].password)// 如果对比的结果为false,则证明用户输入的密码错误if(!compareResult){return res.status(400).json('用户名或密码输入错误,请重新输入')}

生成 JWT 的 Token 字符串

核心注意点:在生成 Token 字符串的时候,一定要剔除 密码 的值

通过 ES6 的高级语法,快速剔除 密码的值:

// 剔除完毕之后,admin 中只保留了用户的 id,name, identify 这四个属性的值const admin ={...results[0],password:''}
或者
const admin ={id: results[0].id,name: results[0].name,identify: results[0].identify
}

运行如下的命令,安装生成

Token

字符串的包:

npm i [email protected]

/router_handler/admin_handler.js

模块的头部区域,导入

jsonwebtoken

包:

// 用这个包来生成 Token 字符串const jwt =require('jsonwebtoken')

创建

config.js 

文件,并向外共享 加密 和 还原

Token

 jwtSecretKey

字符串:

module.exports ={jwtSecretKey:'zhanglijun',}

将用户信息对象加密成 Token 字符串(

/router_handler/admin_handler.js

):

// 导入配置文件const config =require('../config')// 生成 Token 字符串const tokenStr = jwt.sign(admin, config.jwtSecretKey,{expiresIn:'10h',// token 有效期为 10 个小时})

将生成的 Token 字符串响应给客户端:

res.json({status:200,message:'登录成功!',// 为了方便客户端使用 Token,在服务器端直接拼接上 Bearer 的前缀token:'Bearer '+ tokenStr,})

测试

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

admin_hadler.js

代码:

/**
 * 在这里定义和登录注册相关的路由处理函数
 * 供/router/admin.js模块进行调用
 */const db =require('../db/index')const bcrypt =require('bcryptjs')const jwt =require('jsonwebtoken')const config =require('../config')// 注册用户的处理函数
exports.register=(req, res)=>{const adminInfo = req.body
    if(!adminInfo.name ||!adminInfo.password){return res.json({status:400,message:'用户名或密码为空'})}const sql =`select * from admin where name = ? `
    db.query(sql,[adminInfo.name],(err, results)=>{if(err){return res.send({status:404,message: err.message
            })}if(results.length >0){return res.status(400).json('用户名已被注册,请更改后重新注册!')}// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
        adminInfo.password = bcrypt.hashSync(adminInfo.password,10)const sqlStr ='insert into admin set ?'
        db.query(sqlStr,{name: adminInfo.name,password: adminInfo.password,identify: adminInfo.identify },(err, results)=>{if(err){return res.send({status:400,message: err.message
                })}if(results.affectedRows !==1){return res.status(400).json('注册用户失败,请稍后再试')}

            res.json({status:200,message:'注册成功',name: adminInfo.name,password: adminInfo.password,identify: adminInfo.identify
            })})})}// 登录的处理函数
exports.login=(req, res)=>{const adminInfo = req.body
    const sql =`select * from admin where name = ?`
    db.query(sql, adminInfo.name,(err, results)=>{if(err){return res.status(400).json(err)}if(results.length !==1){return res.status(400).json('用户不存在')}const compareResult = bcrypt.compareSync(adminInfo.password, results[0].password)if(!compareResult){return res.status(400).json('用户名或密码输入错误,请重新输入')}// const admin = { ...results[0], password: '' }const admin ={id: results[0].id,name: results[0].name,identify: results[0].identify
        }const tokenStr = jwt.sign(admin, config.jwtSecretKey,{expiresIn:'10h',// token 有效期为 10 个小时})// 将生成的 Token 字符串响应给客户端
        res.json({status:200,message:'登录成功!',// 为了方便客户端使用 Token,在服务器端直接拼接上 Bearer 的前缀token:'Bearer '+ tokenStr,})})}

本文转载自: https://blog.csdn.net/weixin_45732235/article/details/128008481
版权归原作者 lalaxuan 所有, 如有侵权,请联系我们删除。

“Vue3+nodejs全栈项目(资金管理系统)——后端篇(一)登录、注册”的评论:

还没有评论