【node.js后台api项目】(二)实现注册功能
【node.js后台api项目】(二)实现注册功能
- 一、实现思路
- 二、项目目录
- 三、代码编写
- 1、基本代码
- 2、数据合法性校验
- 3、注册路由处理函数
- 4、密码加密
一、实现思路
注册功能简单来说就是提供一个路由,命中路由后把用户名和密码插入数据库。但是也有一些细节需要注意
- 对前端传过来的值需要先进行合法性校验。
- 规定用户名必须唯一,因此在往数据库插入用户信息前需要先检查用户名是否存在,若存在则响应客户端告知更改用户名。
- 考虑到密码的安全性,我们不直接将密码明文保存在数据库,而是加密以后再存入数据库,可以利用一些第三方的npm包来实现这个需求。
- 我们可以直接在appappapp上挂在路由,但是考虑到我们将来要书写众多的路由,我们可以把路由抽离出来,使用
express.Router()
得到router
对象,在routerrouterrouter对象上挂在路由,然后再通过app.use()
使用该路由对象,从而实现模块化开发。
二、项目目录
项目目录结构如下
---- api_server
---- router
---- user.js
---- router_handler
---- user.js
----app.js
---- schema
---- user.js
router里存放路由关系,router_handler里存放路由处理函数。
schema用于放置数据校验规则的配置文件。
三、代码编写
1、基本代码
---- router
---- user.js
const express = require('express')
// 导入路由处理函数
const userHandler = require('../router_handler/user.js')
//调用express.Router()方法,该方法返回一个对象
const router = express.Router()// 注册路由
router.post('/register', userHandler.register)module.exports = router
---- app.js
// 导入user路由
const userRouter = require('./router/user.js')
// 使用路由,当第一个参数传入一个路由前缀时,会给所有userRouter上的路由路径加上该前缀,即我们访问的是 /api/login、/api/register
app.use('/api', userRouter)
---- router_handler
---- user.js
const register = (req , res) => {res.send('命中注册路由!')
}module.exports = {login
}
到了这一步,我们可以先使用postman等apiapiapi测试工具,访问 http://127.0.0.1/api/login
,如果成功返回 命中注册路由
, 说明接口已经跑通,可以进行接下来的编写了。
2、数据合法性校验
这一步我们通过 req.body(express.urlencoded解析数据后挂在在req.body上的)
可以拿到前端传过来的数据,最简单的就是使用 if...else...
判断使得用户名和密码符合我们的要求。
const register = (req, res) => {const userInfo = req.bodyif(!userInfo.username || !userInfo.password) return res.send({status: 1 , message: '注册失败!'})//其他的条件...
}
上面只是一个示例,验证了用户名或密码为空的情况,但是还有很多其他的校验还没做,如果都用 if...else...
进行判断,代码冗余,可读性变差,因此我们可以借助一些第三方的包来做这个功能。
这里使用joi这个包来实现数据校验功能。
// ./schema/user.js
// 导入joi包用于数据校验
const Joi = require('joi')// 定义登录注册的校验规则
const reg_login_schema = {//string()字符串,alphaum()数字和字母的组合,//min(1)长度最小为1,max(10)最大为10,required()这个值是必须有的username: Joi.string().alphanum().min(1).max(10).required(),password: Joi.string().pattern(/^[\S]{6,12}$/).required()
}
上面的代码导入了joijoijoi这个包,然后定义了一个对象,该对象里分别对用户名和密码做出一些约束。
由于登录和注册都需要对用户名密码进行合法性校验,所有我们可以封装一个自定义的中间件。
// ./schema/user.js
// 定义登录注册数据校验中间件
const joiExpress = (req, res, next) => {//根据文档使用Joi即可const schema = Joi.object(reg_login_schema)const userInfo = req.body ? req.body : {}//当匹配成功时,err的值是undefinedconst { error } = schema.validate(userInfo)if (error) res.cc(error)//自定义中间件一定记得调用next()方法,否则服务可能会在这里停止next()
}// 导出该中间件
module.exports = joiExpress
// ./router/user.js
// 导入自定义的登录注册数据校验中间件
const joiExpress = require('../schema/user')// 在该路由下使用中间件
router.post('/register', joiExpress, userHandler.register)
3、注册路由处理函数
基本代码如下
// ./router_handler/user.js
// 注册路由处理函数
const register = (req, res) => {const userInfo = req.body// 检查用户名是否已存在let sql = `select * from ${usersTable} where username=?`db.query(sql, [userInfo.username], (err, result) => {if (err) return res.send({status: 1 , message: err.message})if (result.length > 0) return res.send({status: 1 , message: '用户名已存在,请更换用户名!'})// 执行注册操作let insertSql = `insert into ${usersTable} set ?`// 将用户信息存入数据库db.query(insertSql, { username: userInfo.username, password: userInfo.password }, (err, result) => {if (err) return res.cc(err)if (result.affectedRows >= 1) res.send({status: 1 , message: '用户名已存在,请更换用户名!'})else res.send({status: 1 , message: '注册失败!请稍后重试~'})})})
}
上面的代码我们重复书写了很多次res.send()
,且返回的数据对象有统一的格式,因此我们可以再进行一层封装,编写一个自定义中间件。
// ./app.js// 自定义处理错误中间件
app.use((req, res, next) => {//在res对象上挂载cc函数,之后的req上都会拥有该cc函数res.cc = (err, status = 1) => {err = err instanceof Error ? err.message : errres.send({status,message: err})}next()
})// 使用路由,上面的中间件必须在下面这一行挂在路由的前面引入
app.use('/api', userRouter)
有了这个中间件,将代码更改一下
// ./router_handler/user.jsconst register = (req, res) => {const userInfo = req.body// 检查用户名是否已存在let sql = `select * from ${usersTable} where username=?`db.query(sql, [userInfo.username], (err, result) => {if (err) return res.cc(err)if (result.length > 0) return res.cc('用户名已存在,请更换用户名!')// 执行注册操作let insertSql = `insert into ${usersTable} set ?`// 将用户信息存入数据库db.query(insertSql, { username: userInfo.username, password: userInfo.password }, (err, result) => {if (err) return res.cc(err)if (result.affectedRows >= 1) res.cc('注册成功!', 1)else res.cc('注册失败,请稍后重试~')})})
}
4、密码加密
// ./router_handler/user.js// 导入bcryptjs用于密码加密
const bcrypt = require('bcryptjs')// 注册路由处理函数
const register = (req, res) => {const userInfo = req.body// 检查用户名是否已存在let sql = `select * from ${usersTable} where username=?`db.query(sql, [userInfo.username], (err, result) => {if (err) return res.cc(err)if (result.length > 0) return res.cc('用户名已存在,请更换用户名!')// 执行注册操作let insertSql = `insert into ${usersTable} set ?`// 将明文密码进行加密userInfo.password = bcrypt.hashSync(userInfo.password, 10)// 将用户信息存入数据库db.query(insertSql, { username: userInfo.username, password: userInfo.password }, (err, result) => {if (err) return res.cc(err)if (result.affectedRows >= 1) res.cc('注册成功!', 1)else res.cc('注册失败,请稍后重试~')})})
}
【node.js后台api项目】(二)实现注册功能相关推荐
- 【node.js后台api项目】(七)更新用户头像接口
[node.js后台api项目](七)更新用户头像接口 1.接口相关信息 2. 定义路由和处理函数 3.验证提交的数据 4.实现更新用户基本信息功能 1.接口相关信息 路由: /my/update/a ...
- Vue项目二 登录注册功能的实现
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.系统注册功能的实现 1.配置注册页面路由 2.注册页面的搭建 3.api下发送ajax请求的文件创建 二.后台数据 ...
- Node.js详解(二):Node.js与JS的关系
一.简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与PHP.Py ...
- Vanilla Node.js REST API示例
A Vanilla Node.js REST API without Frameworks such us Express | Engineering Education (EngEd) Progra ...
- Node.js核心入门(二)
目录: Node.js核心入门(一) 全局对象 常用工具 事件机制 Node.js核心入门(二) 文件系统访问 HTTP服务器与客户端 文件系统 fs fs 模块是文件操作的封装,它提供了文件的读取. ...
- api怎么写_使用Node.js原生API写一个web服务器
Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...
- Node.js Express+Mongodb 项目实战
Node.js Express+Mongodb 项目实战 这是一个简单的商品管理系统的小项目,包含的功能还算挺全的,项目涵盖了登录.注册,图片上传以及对商品进行增.删.查.改等操作,对于新手来说是个很 ...
- node.js 学习笔记(二)模板引擎和C/S渲染
node.js 学习笔记(二)模板引擎和C/S渲染 文章目录 node.js 学习笔记(二)模板引擎和C/S渲染 一.初步实现Apache功能 1.1 使用模板引擎 1.2 在 node 中使用模板引 ...
- 十个书写Node.js REST API的最佳实践(上)
收录待用,修改转载已取得腾讯云授权 原文:10 Best Practices for Writing Node.js REST APIs 我们会通过本文介绍下书写Node.js REST API的最佳 ...
最新文章
- Android No static field XXX of type I in class Lcom/XXX/R$id错
- 几何梯度分析神经网络中不可信预测性
- Python基础概念_10_异常处理
- Github标星3w+,热榜第一,如何用Python实现所有算法
- 创业-程序员独自5大思维障碍
- 第五十九期:如何在Windows 10中执行Windows Defender离线扫描?
- centOS7安装matlab2014a
- PowerDesigner 中的name与comment转换(转)
- 【学时总结】 ◆学时·IV◆ 数位DP
- 程序员的自我修养 - 符号修饰 函数签名 以及一个引申的问题: extern c
- mysql资源限制_超出了MariaDB / MySQL资源限制
- 输出字符串全排列 c语言,41.输出全排列-题解(C语言代码)
- c# 使用winform内嵌浏览器
- 5s管理常用工具汇总
- 越狱相关三:OpenSSH
- 左连接 oracle条件查询,sql 左连接查询条件and与where
- 一款网页游戏外挂开发-数据抓包2
- Windows操作系统名称与版本号汇总
- Timeout waiting for connection from pool
- 深度学习(16):print(torch.cuda.is_available()) False的一个解决流程/思路
热门文章
- 有效解决VS 无法启动 IIS EXPRESS Web 服务器。(ID为xxxxx的进程当前未运行)
- 江苏大学考研805真题C语言程序设计 第五大编程题答案2004-2019
- SCI写作分析篇(一)
- 2022年嵌入式秋招题目及解答
- K_A08_005 基于 STM32等单片机驱动XY-160D模块按键控制直流电机正反转加减速启停
- 计算机音乐乐谱小幸运,田馥甄小幸运尤克里里四线谱
- Redis之数据类型详解分析
- php用户注册功能设计,利用HTML+CSS设计一个简单的用户注册页面【示例】
- 分布式发布订阅消息系统—Apache Kafka
- 『Android安全』版优秀和精华帖分类索引