思路:当用户登录的时候去判断数据库中是否有该用户名,如果有,验证用户输入的密码和数据库中存储的是否一致;如果没有,则提醒用户该账号不存在,应该去注册;注册的时候,将密码进行加密(用户的账号和密码要确保其安全性),可用bcrypt进行加密(它的原理输入的明文密码通过10次循环加盐后得到myHash(版本+salt),然后存入数据库。系统在验证用户时,需要从myHash中取出salt跟password进行hash;得到的结果保存在数据库中的hash进行比对,如果一致才算验证通过);登录的时候将生成的token传给前端,在需要的地方验证token。
(1)安装bcrypt进行加密,解密 npm install bcrypt --save
(2)安装jsonwebtoken,生成和验证token npm install jsonwebtoken
(3)使用 bcrypt.hashSync(password, 10) 对密码进行加密
(4)使用 bcrypt.compareSync(password, data.password) 验证密码的正确性
(5)使用 jwt.sign(data, ‘wx’, { expiresIn: 10 1 })* 生成token
(6)使用 jwt.verify(验证的token,自定义密钥,回调) 验证token
//引入express模块
const express = require('express')
//路由
const router = express.Router()
//引入密码加密模块
const bcrypt = require('bcrypt')
//引入生成token
const jwt = require('jsonwebtoken')
//引入数据库模块
const mongoose = require('mongoose')
//连接本地数据库
mongoose.connect('mongodb://localhost:27017/loveHome')
let db = mongoose.connection
//连接的表
let loginCollection = db.collection('login')
//注册
router.post('/register', (req, res) => {
const { username, password, accountNumber } = req.body
if (accountNumber && password) {
// bcrypt.hashSync(密码,10位的盐)
const hashPwd = bcrypt.hashSync(password, 10) // 使用bcrypt.hashSync方法生成密文密码
//hashPwd随机生成的密文密码 $2b$10$jE1hhza0EZaxOyf9RtGVk.m79cA9CKt1Qnmony8cd7xzHoz95JlJq
let obj = { username, password: hashPwd, accountNumber }
//给login表插入要增加的内容
//插入的密码是经过加密的,这样就算程序员也不知道密码是多少,保密性
loginCollection.insertOne(obj, (err, result) => {
if (result) {
res.send({
msg: '注册成功'
})
} else {
res.send({
msg: '注册失败'
})
}
})
} else {
res.send({
code: '111111',
msg: '参数错误'
})
}
})
//登录
router.post('/login', (req, res) => {
const { password, accountNumber } = req.body
if (accountNumber && password) {
//从表中查询账号
loginCollection.findOne({ accountNumber }, (err, data) => {
if (data) {
//该账号存在,验证所输入的密码和数据库中的书否一样
const isPwdValid = bcrypt.compareSync(password, data.password) // 使用bcrypt.compareSync方法验证密码
if (isPwdValid) {
//如果密码正确, 生成token
let token = jwt.sign(data, 'wx', { expiresIn: 10* 1 });
res.send({
msg: '登录成功',
token: token,
success:true,
data:data
})
} else {
res.send({
msg: '密码错误',
success:false,
})
}
}else{
res.send({
msg: '该用户不存在,请注册',
success:false,
})
}
})
} else {
res.send({
success:false,
msg: '参数错误'
})
}
})
module.exports = router
// 引入express模块框架
var express = require('express');
var path = require('path');
// 引入路由模块
const loginRouter = require('./routes/login/login')
const pictureRouter = require('./routes/pictureMsg')
const {jwtCheck} = require('./routes/login/jwt')
// 创建一个express实例
var app = express();
//跨域
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
//res.header('Access-Control-Allow-Headers',"token", 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//登录
app.use('/',loginRouter)
//在想要的地方插入中间件,验证token是否过期
//放在这,是因为想要进入下边的都必须保持登录,token存在的情况下
app.use(jwtCheck)
app.use(pictureRouter)
app.listen('3001', 'localhost', () => {
console.log("启动成功")
})
module.exports = app;
jwt.js文件
// 生成token
const jwt = require('jsonwebtoken')
const jwtKey = 'wx' // token生成的密匙,根据自己需求定义
const jwtSign = (data) => { // token生成函数,有效时间为一个小时
const token = jwt.sign(data, jwtKey, {expiresIn: 10 * 1})
return token
}
const jwtCheck = (req, res, next) => { // token验证函数
const token = req.headers.token
jwt.verify(token, jwtKey, (err, data) => {
if (err) {
res.send({
code: '1111',
msg: 'token无效'
})
} else {
req.jwtInfo = data
next()
}
})
}
module.exports = {
jwtSign,
jwtCheck
}
个人练习,如果有不对的地方,或者我理解错的地方,希望各位可以指正,谢谢。