前言
前面大致上將登入方面的介面以及基本的功能都做好了,接下來要來講關於會員密碼的部份
會員密碼加密
要製作會員登入之前必須先來講講 會員密碼加密,那麼什麼是加密呢?
通常我們存入資料庫中比較敏感的東西就會做加密的動作,假使資料庫被害了至少使用者密碼沒辦法被看光,所以在實作之前一定要考慮清楚哪些是屬於必須加密的資料唷
起手式
在這邊將會使用到一個加密套件叫做 bcrypt
,所以先來安裝套件吧
1
| npm install --save bcrypt
|
接下來在 router 中引用 bcrypt
1
| const bcrypt = require('bcryptjs');
|
設置加密的強度,通常會設置長度 10
1
| const salt = bcrypt.genSaltSync(10);
|
最後新增一個 router 專門來接收註冊的資料
1 2 3 4 5 6 7 8 9 10 11 12
| router.post('/signup', async(ctx, next) => { const password = ctx.request.body.password; const newPassword = bcrypt.hashSync(password, salt); var modelDate = { account: ctx.request.body.email, email: ctx.request.body.email, password: newPassword, createdAt: new Date(), }; await models.Account.create(modelDate); ctx.redirect('/admin/login'); })
|
接下來就可以試著註冊帳號看看,成功的話就可以看到資料庫密碼欄位是加密的狀態唷~
![加密]()
登入驗證
那麼驗證部分呢?驗證部分將會使用 bcrypt.compareSync
1 2 3 4 5 6 7 8 9 10 11 12 13
| router.post('/login', async(ctx, next) => { const account = ctx.request.body.email; const password = ctx.request.body.password; models.Account.findOne({ where: {account: account} }).then((result) => { if(bcrypt.compareSync(password ,result.password)) { console.log('密碼正確') } else { console.log('密碼錯誤'); } }) })
|
如果輸入的密碼是正確的就會顯示密碼正確,如果輸入錯誤就會得到密碼錯誤,那麼由於我們密碼是註冊 123456
,如果正確就會得到密碼正確
![密碼正確]()
但是如果我們輸入錯誤的密碼呢?例如 123456789
呢?那麼就會得到密碼錯誤
![密碼錯誤]()
那麼我們就可以來修改成當密碼正確時就紀錄 session 並導向到登入頁面顯示使用者 Email
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| router.post('/login', async(ctx, next) => { const account = ctx.request.body.email; const password = ctx.request.body.password; models.Account.findOne({ where: {account: account} }).then((result) => { if(bcrypt.compareSync(password ,result.password)) { ctx.session.uid = result.email; ctx.redirect('/admin'); } else { console.log('密碼錯誤'); ctx.redirect('/admin/login'); } }) })
|
接下來就可以試著登入看看是否可以進去該頁面哩
![登入成功]()
而這邊的 router 如下
1 2 3 4 5 6 7 8 9 10 11 12
| .get('/', async (ctx, next) => { const uid = ctx.session.uid; console.log(uid); if(uid){ await ctx.render('dashboard',{ title: '登入成功!', uid }) } else { ctx.redirect('/admin/login'); } })
|
但是這邊其實還要做一下修改比對,如果 session 並不存在呢?所以可以搭配資料庫查詢來查詢是否真的有這個使用者存在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| router.get('/', async (ctx, next) => { const uid = ctx.session.uid; if (uid) { await models.Account.findOne({ where: { account: uid } }).then(async (result) => { if (uid === result.account) { await ctx.render('dashboard', { title: '登入成功!', uid }) } else { ctx.redirect('/admin/login'); } }) } else { ctx.redirect('/admin/login'); } })
|
那麼這邊以上就是一個簡易的會員登入與註冊的機制哩~
補充
最後補充一個登出的 router,登出的 router 很簡單,將 session 清空就好哩
1 2 3 4 5 6 7
| router.post('/signout', async (ctx, next) => { ctx.session.uid = ''; ctx.body = { message: '登出成功', url: '/admin/login' } })
|
主要會透過 AJAX 方式登出,所以這邊也提供原生登出&轉址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const signout = document.querySelector('#signout'); signout.addEventListener('click', (e) => { e.preventDefault(); fetch('/admin/signout', { method: 'post' }) .then((response) => { return response.json(); }) .then((result) => { console.log(result); window.location.href = result.url; }) .catch((error) => { console.log(error); }) })
|