1. 创建项目文件,然后执行初始化命令(会生成package.json项目描述文件,记录项目的信息,安装依赖包信息、相关命令等)
node init -y
2. 安装需要的依赖包
/*
* express: 快速搭建服务器 对于nodejs中http模块的进一步封装
* nodemon: 热重载
* cors: 处理跨域
* @hapi/joi: 请求数据进行验证
* @escook/express-joi: 表单数据进行验证
* express-jwt:解析 Token
* mysql:数据库
* bcryptjs:非对称加密
* jsonwebtoken:生成 Token 字符串
*/
npm add express nodemon cors @hapi/joi@17.1.0 @escook/express-joi express-jwt jsonwebtoken mysql
3. 项目结构
│ config.js
│ index.js
│ package-lock.json
│ package.json
│
├─db
│ index.js
│
├─routerHandle
│ user.js
│ userinfo.js
│
├─routers
│ user.js
│ userinfo.js
│
└─schema
user.js
4. 执行文件 index.js
// 导入模块
const express = require('express');
const cors = require('cors');
// 导入定义验证规则的包
const joi = require('joi');
const app = express();
app.use(cors());
app.use(express.json()) // 解析表单中json数据,不配置的情况下,req.body默认为undefined
app.use(express.urlencoded({ extended: false })) // 解析表单中url-encoded数据,不配置的情况下,req.body默认为 {}
// 失败响应方法中间件
app.use((req, res, next) => {
res.cc = (status, err) => {
res.send({
status,
message: err instanceof Error ? err.message : err
})
}
next()
})
// 路由之前声明中间件
// token 解析中间件
const expressJWT = require('express-jwt')
const config = require('./config')
app.use(expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^\/api/] }))
// 导入用户登录注册路由模块
const userRouter = require('./routers/user')
app.use('/api', userRouter)
// 导入用户信息路由模块
const userInfoRouter = require('./routers/userinfo')
app.use('/my', userInfoRouter)
// 错误级别中间件,需放在所有路由最后
app.use((err, req, res, next) => {
// 表单验证失败
if (err instanceof joi.ValidationError) return res.cc(400, err)
// 身份认证失败
if (err.name === 'UnauthorizedError') return res.cc(401, '身份认证失败')
res.cc(400, err)
})
// 启动服务
app.listen(8081, () => {
console.log('Server is running..., http://127.0.0.1');
})
5. 数据库文件 db/index.js
const mysql = require('mysql')
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: '123456',
database: 'text'
})
module.exports = db
6. 登录注册路由模块 routers/user
// 导入模块
const express = require('express');
const router = express.Router()
// 导入用户路由处理函数模块
const userHandle = require('../routerHandle/user')
// 导入验证表单中间件
const expressJoi = require('@escook/express-joi')
// 导入需要验证的对象
const { registerValidate } = require('../schema/user')
// 用户注册
router.post('/register', expressJoi(registerValidate), userHandle.register)
// 用户登录
router.post('/login', expressJoi(registerValidate), userHandle.login)
module.exports = router
登录注册处理模块 routerHandle/user
// 导入数据库操作模块 const db = require('../db') // 导入加密包 const bcrypt = require('bcryptjs') // 导入生成token的包 const jwt = require('jsonwebtoken') // 导入全局配置文件 const config = require('../config') // 用户注册处理模块 exports.register = (req, res) => { const userinfo = req.body if (!userinfo.username || !userinfo.password) { return res.cc(400, '请输入用户名和密码') } // 用户名查重 const DcSql = 'select * from node_users where username = ?' db.query(DcSql, userinfo.username, (err, results) => { if (err) { return res.cc(500, err) } if (results.length > 0) { return res.cc(400, '用户名已存在') } // 调用bcrypt.hashSync() 对密码进行加密 userinfo.password = bcrypt.hashSync(userinfo.password, 10) // 新增用户 const addSql = 'insert into node_users set ?' db.query(addSql, { username: userinfo.username, password: userinfo.password }, (err, results) => { if (err) { return res.cc(500, err) } if (results.affectedRows !== 1) { return res.cc(400, '注册失败') } // 注册成功 return res.cc(200, '注册成功') }) }) } // 用户登录处理模块 exports.login = (req, res) => { const usesrinfo = req.body; // 查询用户名是否存在 const querySql = 'select * from node_users where username = ?'; db.query(querySql, usesrinfo.username, (err, results) => { if (err) { return res.cc(500, err); } if (results.length !== 1) return res.cc(400, '用户名不存在') // 用户名存在的话校验密码是否正确 const comparPassword = bcrypt.compareSync(usesrinfo.password, results[0].password); if (!comparPassword) return res.cc(400, '密码错误') // 生成token字符串 const user = { ...results[0], password: '', user_pic: '' } const tokenStr = jwt.sign(user, config.jwtSecretKey, { expiresIn: config.expiresin }) // 用户与密码正确则登陆成功 res.send({ status: 200, message: '登陆成功', token: 'Bearer ' + tokenStr }) }) }
登录注册表单校验模块 schema/user
// @ts-nocheck // 导入定义验证规则的包 const joi = require('joi'); // 定义登录注册验证规则 const username = joi.string().alphanum().min(3).max(8).required(); const password = joi.string().pattern(/^(?=.*\d)(?=.*[a-z])[a-zA-Z0-9]{6,12}$/).required(); exports.registerValidate = { body: { username, password } } // 定义用户信息修改验证规则 const id = joi.number().integer().min(1).required(); const nickname = joi.string(); const editUsername = joi.string().alphanum().min(3).max(8); const email = joi.string().email(); exports.updateUserInfoValidate = { body: { id, nickname, username: editUsername, email } } // 定义修改密码验证规则 exports.updatePasswordValidate = { body: { oldPwd: password, newPwd: joi.not(joi.ref('oldPwd')).concat(password), } } // 定义用户头像验证规则 const avatar = joi.string().dataUri().required(); exports.updateAvatarValidate = { body: { avatar } }
2 条评论
情感真挚自然,字里行间传递出强烈的感染力。
《六本木Class》日本剧高清在线免费观看:https://www.jgz518.com/xingkong/58025.html