栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > Cocos2d-x

(内附源码)Node.js小试——使用Node开发API服务器、登录、注册、加密、表单验证、中间件、异常捕获、JWT认证

Cocos2d-x 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

(内附源码)Node.js小试——使用Node开发API服务器、登录、注册、加密、表单验证、中间件、异常捕获、JWT认证


文章目录
  • 初始化Node.js项目
    • 1.创建项目
    • 2.配置cors跨域
    • 3.配置表单数据解析中间件
    • 4.初始化路由文件夹
    • 5.初始化路由模块
    • 6.启动并测试服务器
    • 7.抽离路由处理函数
  • 注册
    • 1.创建数据库
    • 2.安装并配置mysql模块
    • 3.注册
    • 4.注册测试
  • 优化res.send()
  • 优化表单验证
    • 1.安装包
    • 2.验证规则
    • 4.插入验证中间件
    • 5.捕获验证错误
    • 6.验证测试
  • 登录
    • 1.登录步骤
    • 2.表单验证
    • 3.数据查询
    • 4.密码比较
    • 5.生成token
    • 6.Token解析
  • 获取用户信息
    • 1.基本步骤
    • 2.初始化/router/my.js
    • 3.测试路由配置
    • 4.初始化/router_handler/my.js
    • 5.获取用户信息
    • 6.测试
  • 更新用户信息
    • 1.实现步骤
    • 2.定义路由和处理函数
    • 3.参数验证

源码链接(免积分、不付费)

初始化Node.js项目 1.创建项目
  1. 创建项目文件夹,并再项目根目录初始化npm包管理文件,以ExpressServer为例,代码如下:
mkdir ExpressServer && cd ExpressServer
npm init -y
  1. 运行如下命令安装express:
npm i express
  1. 创建项目入口文件,并初始化内容如下:
//1. 导入express模块
const express = require('express')

//2. 创建express服务器实例
const server = express()

// TODO:在这里编写服务器代码

//3. 监听服务器80端口
server.listen(80, () => {
    console.log('Express server running on http://127.0.0.1:80')
})
2.配置cors跨域
  1. 运行如下命令安装cors中间件:
npm i cors
  1. 在app.js中导入并配置cors中间件:
//1. 导入cors中间件
const cors = require('cors')
//2. 注册cors中间件
server.use(cors())
3.配置表单数据解析中间件
  1. 配置如下代码,解析application/x-www-form-urlencoded格式的表单数据:
server.use(express.urlencoded({ extended: false }))
4.初始化路由文件夹
  1. 项目根目录中,创建router文件夹,用于存放所有的路由模块
  2. 项目根目录中,创建router_handler文件夹,用于存放所有的路由处理模块
mkdir router 
mkdir router_handler
5.初始化路由模块
  1. 在router文件夹中新建auth.js,用于存储所有的用户路由,编写内容如下:
const express = require('express')

//创建路由对象
const router = express.Router()


//用户注册路由
router.post('/register', (req, res) => {
    res.send('POST /register')
})

//用户登录路由
router.post('/login', (req, res) => {
    res.send('POST /login')
})

//共享router对象
module.exports = router
  1. 在app.js中,导入并注册用户路由模块:
//导入用户路由
const authRouter = require('./router/auth')
//注册用户路由
server.use('/api/auth',authRouter)
6.启动并测试服务器
  1. 安装nodemon模块,用于启动服务器(nodemon模块可以在我们修改代码后自动重启服务器):
npm i -g nodemon
  1. 使用nodemon模块启动服务器:
nodemon app.js

如果操作正确,服务器正常启动,将输出如下内容:

PS E:ExpressServer> nodemon .app.js
[nodemon] 2.0.16
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node .app.js`
Express server running on http://127.0.0.1:80
  1. 使用postman测试接口是否配置正确,以POST方式分别访问localhost/api/auth/register和localhost/api/auth/login

7.抽离路由处理函数

为了保证路由模块的存粹性,将路由处理函数单独抽离出来放在router_handler文件夹中

  1. 在router_handler文件夹中创建并编辑auth.js文件如下:
//router_handler/auth.js

//注册处理函数
exports.authRegister = (req, res) => {
    res.send('POST /register')
}

//登录处理函数
exports.authLogin = (req, res) => {
    res.send('POST /login')
}
  1. 修改/router/auth.js文件代码如下:
//router/auth.js

const express = require('express')

//创建路由对象
const router = express.Router()

//引入auth处理模块
const authHandler = require('../router_handler/auth')

//用户注册路由
router.post('/register', authHandler.authRegister)

//用户登录路由
router.post('/login', authHandler.authLogin)

//共享router对象
module.exports = router
  1. 使用nodemon启动并使用postman访问localhost/api/auth/register和localhost/api/auth/login,会得到和之前(6.3)相同的结果。
注册 1.创建数据库
  1. 创建MySql数据库,此处以db_node为例:
CREATE SCHEMA `db_node` ;

如果还没有安装MySql,可以在这里下载MySql安装器

  1. 创建t_users数据表,创建表sql指令如下:
CREATE TABLE `db_node`.`t_users` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `username` VARCHAr(255) NOT NULL,
  `password` VARCHAr(255) NOT NULL,
  `nickname` VARCHAr(255) NULL,
  `email` VARCHAr(255) NULL,
  `avatar` TEXT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) VISIBLE,
  UNIQUE INDEX `username_UNIQUE` (`username` ASC) VISIBLE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
2.安装并配置mysql模块
  1. 执行如下指令,安装mysql模块:
npm i mysql
  1. 创建/db/index.js文件,此文件用于存储数据库连接对象:
// db/index.js

//导入mysql模块
const mysql = require('mysql')

//创建数据库连接对象
const db = mysql.createPool({
    host: '127.0.0.1',  //数据库服务器地址,我们使用本机
    user: 'root',       //mysql用户名,替换为你的用户名
    password: '000000', //mysql密码,替换为你的密码
    database: 'db_node',//数据库名称,此处为db_node
})

//导出数据库连接对象
module.exports = db 
3.注册
  1. 注册步骤
  • 检测表单数据
  • 检测用户名是否占用
  • 密码加密处理
  • 插入新用户
  1. 检测表单数据
const userinfo = req.body
    if(!userinfo.username || !userinfo.password){
        return res.send({
            status: 201,
            message:'用户名、密码不能为空!'
        })
    }
  1. 检测用户名是否占用
  • 从db/index.js导入db
const db = require('../db/index')
  • 定义SQL
sqlStr = 'select * from t_users where username = ?'
  • 执行SQL语句,判断是否占用:
db.query(sql, userinfo.username, (err, results) => {
        if (err) return res.send({ status: 201, message: err.message })
        if(results.length > 0){
            return res.send({status:201,message:'用户名已存在'})
        }
        //TODO:插入新用户
    })
  1. 密码加密
  • 执行以下指令,安装bcryptjs模块
npm i bcryptjs
  • 在router_handler/auth.js中,导入bcryptjs
const bcrypt = require('bcryptjs')
  • 插入用户之前,使用bcrypt.hashSync(password,len)进行加密
userinfo.password = bcrypt.hashSync(userinfo.password,10)
  1. 插入用户
  • 定义SQL
sqlStr = 'insert into t_users set ?'
  • 执行SQL,插入用户
db.query(sql, { username: userinfo.username, password: userinfo.password }, (err, results) => {
            if (err) return res.send({ status: 201, message: err.message })
            if (results.affectedRows === 1)
                return res.send({ status: 200, message: 'success' })
            return res.send({ status: 201, message: '注册失败,稍后再试' })
        })
4.注册测试
  1. 使用PostMan发送注册信息,操作如下:

  1. 我们可以查看数据库:

如此,注册方法变成功执行了。

优化res.send()

我们在代码中多次使用到了res.send()方法,非常繁琐,需要封装简化代码。(不优化也没啥)

  1. 在app.js中所有的路由之前定义并注册全局中间件
server.use((req, res, next) => {
    //status = 200 success
    //status = 201 failure
    res.cc = function (err, status = 1) {
        res.send({
            status: status,
            message: err instanceof Error ? err.message : err,
        })
    }
    next()
})

这样在所有的路由中,res都具有一个cc方法,可以方便的向客户端输出结果。

优化表单验证

表单验证,前端为辅,后端为主,永远不相信前端提交的数据

1.安装包

1.安装joi包,为表单项定义验证规则

npm i joi
  1. 安装@escook/express-joi,实现自动验证表单数据
npm i @escook/express-joi
2.验证规则
  1. 新建schema/auth.js用户验证规则模块
mkdir schema
touch schema/auth.js
  1. 初始化如下:
//schema/auth.js
//导入包
const joi = require('joi')


//用户名密码验证规则
const username = joi.string().alphanum().min(1).max(10).required()
const password = joi.string().pattern(/^[S]{6,12}$/).required()

//登录注册验证对象
exports.reg_login_schema = {
    body: {
        username,
        password
    }
}
4.插入验证中间件
  1. 引入验证中间件
//引入验证中间件
const expressJoi = require('@escook/express-joi') //(*)
  1. 引入验证规则
//引入验证规则
const { reg_login_schema } = require('../schema/auth')//(*)
  1. 注册验证中间件
//用户注册路由,添加验证中间件
router.post('/register', expressJoi(reg_login_schema), authHandler.authRegister) //(*)

修改后的route/auth.js,如下:

//router/auth.js

const express = require('express')

//创建路由对象
const router = express.Router()

//引入验证中间件
const expressJoi = require('@escook/express-joi') //(*)

//引入验证规则
const { reg_login_schema } = require('../schema/auth')//(*)

//引入auth处理模块
const authHandler = require('../router_handler/auth')

//用户注册路由,添加验证中间件
router.post('/register', expressJoi(reg_login_schema), authHandler.authRegister) //(*)

//用户登录路由
router.post('/login', authHandler.authLogin)

//共享router对象
module.exports = router

注意以上代码中(*)处是修改的地方。

5.捕获验证错误

在app.js中创建并注册全局错误处理中间件,用于处理验证错误(也可以处理其他错误)。

  1. 引入验证规则
//引入验证规则模块
const joi = require('joi')
  1. 创建并注册全局异常中间件
//引入验证规则模块
const joi = require('joi')

//注册异常捕获中间件
server.use((err, req, res, next) => {
    if (err instanceof joi.ValidationError) return res.cc(err)
    res.cc(err)
})
6.验证测试

登录 1.登录步骤
  1. 表单验证;
  2. 数据查询;
  3. 密码比较;
  4. 生成JWT的Token字符串
2.表单验证
  1. 修改router/auth.js的路由如下:
//用户登录路由
router.post('/login', expressJoi(reg_login_schema), authHandler.authLogin)
3.数据查询

在router_handler/auth.js中的登录处理方法中:

  1. 表单数据接收
const userinfo = req.body
  1. 定义SQL语句
const sqlStr = 'select * from t_users where username=?'
  1. 执行查询SQL
//执行查询
db.query(sqlStr, userinfo.username, (err, results) => {
    //查询失败
    if (err) return res.cc(err)
    //查询结果不合理
    if (results.length !== 1) return res.cc("登录失败")
    //TODO:判断密码
})
4.密码比较

调用bcrypt.compreSync(表单密码,数据库密码)判断密码是否一致,true一致,false不一致

//判断密码
const cmpRes = bcrypt.compare(userinfo.password, results[0].password)
if (!cmpRes) return res.cc('Login Failed')

//TODO:登录成功,生成token
5.生成token
  1. 从查询结果中剔除password和avatar两个值
const usr = { ...results[0], password: '', avatar: '' }
  1. 安装jwt
npm i jsonwebtoken
  1. 在router_handler/auth.js中导入jwt
const jwt = require('jsonwebtoken')
  1. 根目录创建配置文件config.js,并共享jwtSecretKey字符串(用于加密)
//config.js
module.exports = {
    //一个复杂字符串
    jwtSecretKey: "alkjflasngaoieakgbnasdfzxfgasdf",
    expiresIn: '24h',//token有效期24h
}
  1. 加密用户信息,生成token
//导入config
const config = require('../config')

//生成token
const tokenStr = jwt.sign(usr, config.jwtSecretKey, {
            expiresIn: config.expiresIn,//token有效期为24小时
})
  1. 返回客户端
res.send({
    status: 200,
    message: 'login success',
    token: 'Bearer ' + tokenStr
})
  1. 测试登录

6.Token解析
  1. 安装express-jwt模块(注意版本,较新版本不适合本教程)
npm i express-jwt@5.3.3
  1. app.js中注册路由之前配置Token中间件
const config = require('./config')

//导入token中间件
const expressJWT = require('express-jwt')

//注册token中间件,所有以/api开头的路由都需要验证token的正确性
server.use(expressJWT({ secret: config.jwtSecretKey }).unless({ path: [/^/api//] }))
  1. app.js中token认证失败异常捕捉
if (err.name === 'UnauthorizedError') return res.cc('认证失败')
  1. 解析验证

访问非/api开头的路由即可,这里使用/my

想要验证成功,需要在Header中加入Authorization字段,字段的值是登录时返回的Token:

获取用户信息

用户中心功能的一部分,获取用户个人信息,使用/my/info路由的GET请求。

1.基本步骤
  1. 初始化个人中心路由“router/my.js”
  2. 初始化路由处理函数“router_handler/my.js”
  3. 获取用户信息
2.初始化/router/my.js
  1. 创建文件router/my.js,编辑代码如下:
// 引入express模块
const express = require('express')

//创建路由对象
const router = express.Router()

//挂接/info路由
router.get('/info', (req, res) => {
    res.send('ok')
})

//向外分享路由对象
module.exports = router
  1. 在app.js中导入当前路由模块(可以紧贴/api/auth路由向后写)
//导入路由
const myRouter = require('./router/my')
//注册/my路由
server.use('/my', myRouter)
3.测试路由配置
  1. 访问/api/auth/login登录并获取token

复制返回的token字符串。

  1. 访问/my/info

如果你和我的编码相同,返回ok即为正确。

4.初始化/router_handler/my.js
  1. 新建/router_handler/my.js文件,编辑内容如下:
//暴露/my/info路由的处理函数
exports.getInfo = (req, res) => {
    res.send('/my/info handler')
}
  1. 修改/router/my.js文件中代码如下:
// 引入express模块
const express = require('express')

//创建路由对象
const router = express.Router()

const myHandler = require('../router_handler/my') //(*)
//挂接/info路由
router.get('/info', myHandler.getInfo)//(*)

//向外分享路由对象
module.exports = router

注意上述代码中(*)处的改动。

  1. 测试路由处理函数

如果返回的内容和我一样就没有问题了。

5.获取用户信息
  1. 导入/db/index模块
const db = require('../db/index')
  1. 编写SQL语句
const sql = 'select id,username,nickname,email,avatar from t_users where id=?'
  1. 执行查询语句
db.query(sql, req.user.id, (err, results) => {
    if (err) return res.cc(err.message)
    if (results.length !== 1) return res.cc('获取用户信息失败')
    res.send({
        status: 200,
        message: 'Success',
        data: results[0]
    })
});
6.测试

这样就执行成功了。

更新用户信息

使用/my/info的POST请求更新用户个人信息。

1.实现步骤
  1. 定义路由
  2. 验证表单数据
  3. 更新用户信息
2.定义路由和处理函数
  1. 在/router/my.js中新增POST路由
//更新信息
router.post('/info', myHandler.setInfo)
  1. 添加处理函数
//router_handler/my.js
//设置用户信息
exports.setInfo = (req, res) => {
    res.rend('post /my/info handler')
}
  1. 测试路由

3.参数验证
  1. 定义验证规则

新建/schema/my.js文件,编辑如下:

//schema/my.js
//导入验证规则模块
const joi = require('joi')

//定义验证规则
const id = joi.number().integer().min(1).max(10).required()
const nickname = joi.string().required()
const email = joi.string().email().required()

//导出验证规则
exports.update_info_schema = {
    body: {
        id,
        nickname,
        email
    }
}
  1. 引入验证中间件

在/router/my.js中引入express-joi中间件

// 引入验证中间件
const express_joi = require('@escook/express-joi')
  1. 引入验证规则

在/router/my.js中引入joi验证规则

// 引入验证规则
const { update_info_schema } = require('../schema/my')
  1. 在/my/info的POST路由添加验证
//更新信息
router.post('/info', express_joi(update_info_schema), myHandler.setInfo)
  1. 验证测试

如果我们不提供id参数,就会报如下错误。

如果我们提供正确的参数,将获得如下结果:


源码链接(免积分、不付费)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/967941.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号