之前做的美團網項目,需要實現注冊登錄功能,項目地址:
https://github.com/Chenxi-Lau/MeiTuan
主要技術棧:Nuxt.js + Koa + MongoDB + Redis
本地用戶登錄,第三方登錄都需要權限認證,權限認證的思路也極其簡單,不外乎就是登錄,登出,路由守護三部分。
今天要講的權限認證中間件那就是:passport.js,passport目前包括多種登錄策略,比如github登錄,微信登錄,Facebook登錄,google等等。
官網:http://passportjs.org/docs/
本文參考以下博文整理發布:
https://segmentfault.com/a/1190000011557953
1、安裝
koa2中使用的是 koa-passport
這個包。
本地驗證用的是 passport-local
這個策略
npm install -S koa-passport
2、配置
這里使用 passport-local
策略(本地權限認證)為例子。
因為passport使用之前要定義策略及序列化與反序列化操作,所以把 passport
的配置及策略寫到一個文件passport.js
。
// passport.js import passport from 'koa-passport' import LocalStrategy from 'passport-local' import UserModel from '../../dbs/models/users' //MongoDB數據庫 // 新建策略 passport.use(new LocalStrategy(async function (username, password, done) { let where = { username } let result = await UserModel.findOne(where) if (result != null) { if (result.password === password) { return done(null, result) } else { return done(null, false, '密碼錯誤') } } else { return done(null, false, '用戶不存在') } })) // 序列化ctx.login()觸發 passport.serializeUser(function (user, done) { done(null, user) }) // 反序列化 passport.deserializeUser(function (user, done) { return done(null, user) }) export default passport
3、入口載入
然后在 koa
入口 app.js
中載入 passport.js
文件
import passport from './interface/utils/passport'
並在適當位置(看下邊 app.js
)使用passport
中間件
app.use(passport.initialize())
app.use(passport.session())
4、后端路由的編寫
- 登錄接口: POST/signin
router.post('/signin', async (ctx, next) => {
// 調用passport配置的策略 return Passport.authenticate('local', function (err, user, info, status) { if (err) { ctx.body = { code: -1, msg: err } } else { if (user) { ctx.body = { code: 0, msg: '登錄成功', user } return ctx.login(user) } else { ctx.body = { code: 1, msg: info } } } })(ctx, next) })
- 登出接口:GET/exit
router.get('/exit', async (ctx, next) => { await ctx.logout() if (!ctx.isAuthenticated()) { ctx.body = { code: 0 } } else { ctx.body = { code: -1 } } })
- 其他需要權限認證的接口
router.get('/getUser', async (ctx) => { //調用ctx.isAuthenticated()進行權限的認證 if (ctx.isAuthenticated()) { const { username, email } = ctx.session.passport.user ctx.body = { user: username, email } } else { ctx.body = { user: '', email: '' } } })
- 前端頁面的接口請求
login () { let self = this self.$axios .post('/users/signin', { username: window.encodeURIComponent(self.username), password: CryptoJS.MD5(self.password).toString() }) .then(({ status, data }) => { if (status === 200) { if (data && data.code === 0) { location.href = '/' } else { self.error = data.msg } } else { self.error = `服務器出錯` } setTimeout(function () { self.error = '' }, 1500) }) }
到這里,本地權限認證基本完成了,post請求 /signin
並且提交表單user
,和 password
即可登錄一個用戶。
5、總結
passport使用session來維護會話。對於token驗證的來說,並不能用,所以要實現token驗證的話還需要另外編寫策略才行。
更多詳細用法,請自行到官網查看文檔。