node.js+koa+mongodb实现登录注册
思路 实现登录注册有三种方式 session和jwt 和oAuth(第三方登录) 我这里选用jwt
需要 :
中间件 koa-jwt 权限路由验证
jsonwebtoken 生成token
密码加密:
uuid ---唯一识别码
sha1 ---安全哈希算法
bcrypt ---加密算法 地址https://www.npmjs.com/package/bcrypt-nodejs
crypto ---加密算法
md5 --加密算法
json web token 传输方式
用md5/sha1+salt的方法保存密码是不安全的, 保存密码推荐用Bcrypt.
登录的几种实现方式
1.session 接收用户传过来的信息,存在session中,以cookie的方式传回给浏览器,cookie中有sessionId及值,
从http header中提取session Id ,根据session Id 从服务器端的hash中获取请求者身份
2.token 服务端收到信息后,将username转为userId 存储在jwt的payload中, 与头部进行base64编码进行签名,形成jwt,在cookie中保存,返回给浏览器,
浏览器每次请求都携带cookie,服务器对jwt进行解密,与服务器进行比较
项目流程
我使用了koa-generator脚手架, 热更新npm run dev ,服务器可以自动刷新,但是浏览器需要自己刷新
***********连接mongodb***************
0 用powershell运行似乎和cmd运行有点不一样
1 下载 安装
2 创建一个data文件夹来保存文件 目录C:\data\db 这是mongodb的默认路径
运行:C:\mongodb\bin\mongod --dbpath c:\data\db 连接C:\mongodb\bin\mongo.exe
3 一些帮助db.help() db.stats()查看 show dbs
4 切换数据库 use mydb
5 Mongoose是MongoDB的一个对象模型工具,Mongoose,因为封装了对MongoDB对文档操作的常用处理方法,可以高效的操作mongodb象模型工具,Mongoose,
因为封装了对MongoDB对文档操作的常用处理方法,可以高效的操作mongodb,同时可以理解mongoose是一个简易版的orm
6 app.js 连接数据库
var mongoose = require('mongoose')
mongoose.connect("mongodb://127.0.0.1:27017/user", { //mongoose.connect
useNewUrlParser: true
});
// MongoDB连接成功后回调,这里仅输出一行日志
mongoose.connection.on('connected', function () { //mongoose.connection
console.log('sucess 192.168.1.29:27017/user');
});
// MongoDB连接出错后回调,这里仅输出一行日志
mongoose.connection.on('error', function (err) {
console.log(' error: ' + err);
});
// MongoDB连接断开后回调,这里仅输出一行日志
mongoose.connection.on('disconnected', function () {
console.log(' disconnected');
});
7 和koa连接是使用mongoose,根目录下新建一个models文件夹,这里放置数据模型,
models/userinfo.js文件
var mongoose = require('mongoose')
var schema = mongoose.Schema
const userinfo = new schema({
'username': String,
'password': String
})
const user = mongoose.model('userinfo', userinfo)
module.exports = user
**************koa-router 使用**************
//引入和获取一个router实例
router.get('/')
router.post('/')
router.use(userinfo.routes(), userinfo.allowedMethods())
router.use(home.routes(), home.allowedMethods())
这里可以把router分文件写,然后写一个index汇总,在app.js里引入
在router文件夹里面router/user.js
登录注册的主要思路是注册时给密码加密(忽略验证等其他方面的),然后登录时验证如果密码匹配就返回token,然后如果有鉴权的需要,则前端每个http请求需要在header中携带token,
然后node后端中验证token是否有效,这个验证koa-jwt已经在作用了,对于token登出这一块,需要存储token,然后比对,前后端都清除,还有一种是不存储token,设置过期时间,仅前端登出
//登录
router.post('/login', async (ctx, next) => {
const userinfos = await user.findOne({
username: ctx.request.body.username
})
const compare = await bcrypt.compare(ctx.request.body.password, userinfos.password)
if (compare) {
ctx.body = {
code: 1,
msg: '登录成功!',
token: jsonwebtoken.sign({
data: userinfos.username,
exp: Math.floor(Date.now() / 1000) + (60 * 60)
}, 'secret')
}
} else {
ctx.body = {
code: 0,
msg: '登录失败!'
}
}
})
//注册
router.post('/register', async (ctx, next) => {
//判断和唯一识别码
const {
body
} = ctx.request
body.password = await bcrypt.hash(ctx.request.body.password, 10)
const res = await user.create(body)
if (res) {
ctx.body = {
code: 1,
msg: '注册成功!'
}
} else {
ctx.body = {
code: 0,
msg: '注册失败!'
}
}
})
*****路由鉴权*****
app.js
//koa-jwt 路由鉴权
app.use(errorHandle)
app.use(jwt({
secret: 'secret'
}).unless({
path: [/\/register/, /\/login/]
}))