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 創(chuàng)建一個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/]
}))