① 思路 :
实现登录注册有三种方式 session和jwt 和oAuth(第三方登录) 我这里选用jwt
② 需要 :
中间件 koa-jwt 权限路由验证
jsonwebtoken 生成token
③ 密码加密:
- uuid —唯一识别码
- sha1 —安全哈希算法
- bcrypt —加密算法
- 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
用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 连接数据库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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文件夹,这里放置数据模型,
1 2 3 4 5 6 7 8 9
| 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实例
1 2 3 4 5
| const router = require('koa-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,设置过期时间,仅前端登出
登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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: '注册失败!' } } })
|
路由鉴权
1 2 3 4 5 6 7 8
| app.js //koa-jwt 路由鉴权 app.use(errorHandle) app.use(jwt({ secret: 'secret' }).unless({ path: [/\/register/, /\/login/] }))
|