本文简要的介绍了登录注册功能的实现。
基础储备
express基础使用
- 你可能会用到express-generator脚手架来搭建你的项目。
npm i express
- 你可以选择全局安装express,也可以选择开发时依赖。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"create": "express --view=ejs myapp"
},
如果是开发时依赖,则需要在包管理json文件中,配置启动。全局直接运行create后面的代码即可。
当然,作为一个初级前端,前期可以把重心放在前端,我们可以直接新建一个文件夹。然后再当前文件夹路径下,运行
npm init -y
然后npm安装express即可。然后在文件夹下新建http.js文件
- http.js
//http.js文件
const express = require("express");
const app = new express();
const port = 3000;
app.get('/',(res,req,next)=>{
res.send("测试成功")
}
)
app.listen(port,()=>{
console.log("serve is running")
})
对比以下,如果是原生node是如何实现基础功能的
//http.js文件(原生node)
const http = require("http");
const {parse} = require("querystring");
const fs = require("fs");
const port = 3000;
const app = http.createServer((req,res)=>{
if(req.query !== '/favicon.ico'){
if(req.url.includes("/api")){
//请求数据
dataRequest(req,res)
}else{
// 访问资源
fileRequest(req,res);
}
}
})
function dataRequest(req,res) {
let str = "";
let requestObj = null;
req.on("data",c=>{
str += c;
})
req.on("end",()=>{
if(str){
requestObj = parse(str)
}else{
requestObj = parse(req.url.split("?")[1])
}
})
console.log(requestObj);
res.end();
}
function fileRequest(req,res) {
const myUrl = URL("http://localhost:3000" + req.url).pathname
fs.readFile("./www"+myUrl,"utf-8",(err,data)=>{
if(err){
res.write("404")
}else{
res.write(data)
}
res.end();
})
}
app.listen(port,()=>{
console.log("serve is running")
})
此时超级精简的后台已经成功了,运行node http.js启动一下服务器,浏览器输入地址测试一下;
mongo数据库
在新建的文件夹下面建立一个sql文件夹,里面放两个文件。
目录如下:
- 建立的文件夹
- sql
- db.js
- user.js
- http.js
- sql
这边直接使用mongoose来连接数据库。
npm i mongoose
先连接数据库
//db.js (这个js文件是用来连接数据库的)
const mongoose = require('mongoose')
//连接本地数据库
// mongoose.connect("mongodb://127.0.0.1:27017/mydb",{
// useNewUrlParser: true,
// useUnifiedTopology: true
// });
//连接云数据库(一定要确保云数据库的网速哦,不然发起请求的时候可能会报500错误)
mongoose.connect('mongodb+srv://zlc007:654321QWER@cluster0.hm4nf.mongodb.net/a2012?retryWrites=true&w=majority', {
useNewUrlParser: true,
useUnifiedTopology: true
})
//连接的状态
mongoose.connection.on("connected",()=>{
console.log("success");
})
mongoose.connection.on("disconnected",()=>{
console.log("disconnected");
})
mongoose.connection.on("error",()=>{
console.log("error");
})
module.exports = mongoose;
连接到数据库之后,配置对应的collection。这边的需求是简易的登录注册,所以暂时创建一个users集合。
//引入之前连接的数据库,.js后缀可以省略
const db = require('./db');
//创建一个新的集合
const UserSchema = new db.mongoose.Schema({
mobile: {
type: String, // 类型
required: true // 必填
},
password: {
type: String,
required: true,
}
})
// 集合名要是复数哦 , 当然,你不加mongo会帮你加滴
module.exports = db.mongoose.model('users', UserSchema);
到这里数据库已经连接完毕,而且users集合也已经建好了。接下来直接进入业务逻辑。
功能实现
注册的实现
注册功能的业务逻辑:
- 判断手机号是否注册过
- 如果没有注册过,继续注册,注册完成跳转login页面
- 如果注册过,则返回给前端注册过了
- 使用md5加密技术,将密码加密存储
const express = require("express")
const app = express();
const port = 3000;
// 文件系统模块
const fs = require("fs");
// 加密技术,对密码进行加密
const md5 = require("md5");
// 解析非地址栏传输的数据
const bodyParser = require("body-parser");
app.use(bodyParser.json());
// 第三代会话跟踪技术 token
const jwt = require('jsonwebtoken');
// 引入mongo数据库的users集合
const user = require("./sql/users");
// 处理跨域
let cors = require("cors");
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }))
// 定义一个密码加密函数
const passwdCrypt = (req, res, next) => {
var passwd = req.body.pass;
req.body.passwdCrypted = md5(passwd);
next();
};
//使用局部中间件,先将函数进行加密处理
app.post('/register',passwdCrypt,(req, res) => {
const obj = {
mobile: req.body.mobile,
// password:req.body.password,
pass: req.body.passwdCrypted
}
console.log(req.body);
user.findOne({mobile:req.body.mobile},(err,data)=>{
if(err){
console.log("查询数据库报错啦");
return
}
if(data){
res.send({
code:'409',
message:'已经注册过了'
})
}else{
// 未注册
user.insertMany(obj,(err,data)=>{
if(err) {
console.log('err',err)
}
console.log(data)
//数据库有他就可以进入 /login
res.send({
code:'200',
msg:data,
message:'注册成功'
})
})
}
})
})
app.listen(port, () => console.log(`Server is running at http://127.0.0.1:${port}!`));
登录的实现
登录的业务逻辑:
- 配置/login接口
- 接收到的数据,查询数据库
- 使用第三代会话跟踪技术token
const express = require("express")
const app = express();
const port = 3000;
// 文件系统模块
const fs = require("fs");
// 加密技术,对密码进行加密
const md5 = require("md5");
// 解析非地址栏传输的数据
const bodyParser = require("body-parser");
app.use(bodyParser.json());
// 第三代会话跟踪技术 token
const jwt = require('jsonwebtoken');
// 引入mongo数据库的users集合
const user = require("./sql/users");
// 处理跨域
let cors = require("cors");
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }))
const passwdCrypt = (req, res, next) => {
var passwd = req.body.pass;
req.body.passwdCrypted = md5(passwd);
next();
};
//此处应有register路由代码,节省空间省略了
// 加密因子
const jwt_secret = 'abc'
router.post('/login', passwdCrypt, async (req, res) => {
let { mobile, passwdCrypted } = req.body;
let result = await user.findOne({ mobile, pass: passwdCrypted });
if(result) {
res.send ({
code:'1000',
info:'success',
mobile:mobile,
data: {
// token配置
_token:jwt.sign({
pass:passwdCrypted,
mobile:result.mobile
},
jwt_secret,
{expiresIn: 60*60*60}
)
}
})
}else{
res.send({
code:'9999',
info:'走开 你不是我的用户 '
})
}
})
app.listen(port, () => console.log(`Server is running at http://127.0.0.1:${port}!`));
当然,可能有些小伙伴会觉得将业务逻辑写在一个js文件里面会很冗余,如果你受不了将所有业务逻辑放在一起的冗余状态,也可以使用路由外置。
下面是分开的写法:
在原有的文件夹目录下,新建api文件夹,目录结构如下。
- api
- register.js
- login.js
// http.js
const express = require("express");
const app = new express();
const port = 3000;
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// 处理跨域
let cors = require("cors");
app.use(cors());
const loginRouter = require('./api/login');
const registerRouter = require('./api/register');
app.use('/register', registerRouter);
app.use('/login', loginRouter);
app.listen(port,()=>{
console.log("serve is running")
})
//login.js
var express = require('express');
var router = express.Router();
// 加密技术,对密码进行加密
const md5 = require("md5");
const user = require("../sql/users");
// 第三代会话跟踪技术 token
const jwt = require("jsonwebtoken");
const passwdCrypt = (req, res, next) => {
console.log(req.body);
var passwd = req.body.pass;
req.body.passwdCrypted = md5(passwd);
next();
};
// 加密因子
const jwt_secret = 'abc'
router.post('/', passwdCrypt, async (req, res) => {
let { mobile, passwdCrypted } = req.body;
let result = await user.findOne({ mobile, pass: passwdCrypted });
if(result) {
res.send ({
code:'1000',
info:'success',
mobile:mobile,
data: {
_token:jwt.sign({
pass:passwdCrypted,
mobile:result.mobile
},
jwt_secret,
{expiresIn: 60*60*60}
)
}
})
}else{
res.send({
code:'9999',
info:'走开 你不是我的用户 '
})
}
})
module.exports = router;
//register.js
var express = require('express');
var router = express.Router();
// 解析非地址栏传输的数据
// 加密技术,对密码进行加密
const md5 = require("md5");
const user = require("../sql/users");
const passwdCrypt = (req, res, next) => {
var passwd = req.body.pass;
req.body.passwdCrypted = md5(passwd);
next();
};
router.post('/',passwdCrypt,(req,res)=>{
const obj = {
mobile:req.body.mobile,
// password:req.body.password,
pass:req.body.passwdCrypted
}
user.findOne({mobile:req.body.mobile},(err,data)=>{
if(err){
console.log("查询数据库报错啦");
return
}
if(data){
res.send({
code:'409',
message:'已经注册过了'
})
}else{
// 未注册
user.insertMany(obj,(err,data)=>{
if(err) {
console.log('err',err)
}
console.log(data)
//数据库有他就可以进入 /login
res.send({
code:'200',
msg:data,
message:'注册成功'
})
})
}
})
})
module.exports = router;
到这里为止,后台的登录注册就可以实现啦。
PS:前端的post请求需要的两个属性是pass 和 mobile属性哦(▽)