登陆验证koa-passport中间件的简单使用

社会主义新天地 提交于 2020-02-14 07:06:31

简述

koa-passportkoa的一个中间件,它实际上只是对passport的一个封装。利用koa-passport可以简便的实现登录注册功能,不但包括本地验证,还有很多提供第三方登录的模块可以使用。这篇博客只讲一下登陆验证这块的一些简单内容

配置

安装依赖

npm install -S koa-passport 
npm install -S passport-local 

引包

import passport from 'koa-passport'
import LocalStrategy from 'passport-local'
import UserModel from '../../dbs/models/users'

配置验证策略
koa-passport默认使用usernamepassword做验证

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, '用户不存在')
        }
    }))

序列化
在用户登陆验证成功后将会把用户的数据储存到session中,在调用 ctx.login() 时会触发序列化操作,把用户对象存到 session 里。

passport.serializeUser(function(user, done) {
        done(null, user)
    })

反序列化
每次请求将从session中读取用户对象,session 中如果存在 "passport":{"user":"xxx"} 时会触发定义的反序列化操作

passport.deserializeUser(function(user, done) {
   return done(null, user)
})

别忘了export default passport导出配置好的模块

使用

import Koa from 'koa'
import session from 'koa-generic-session'
import Redis from 'koa-redis'
import passport from './interface/utils/passport'
const app = new Koa()
 // session的加密处理
app.keys = ['mt', 'keyskeys']
app.use(session({
  key: 'mt',
  prefix: 'mt:uid',
  store: new Redis()
}))

//initialzie()函数的作用是为上下文添加passport字段, 会在ctx挂载以下方法
//ctx.state.user 认证用户
//ctx.login(user) 登录用户
//ctx.logout() 用户退出登录
//ctx.isAuthenticated() 判断是否认证
app.use(passport.initialize())
//开启koa-passport对session的支持,passport.session()是使passport能够从session中提取用户信息
app.use(passport.session())

登陆组件

router.post('/signin', async(ctx, next) => {
    return Passport.authenticate('local', function(err, user, info, status) {
        if (err) {
            ctx.body = {
                code: -1,
                msg: err
            }
        } else {
            if (user) {     
         //user是我们在数据库中找到的数据                           
                ctx.body = {
                    code: 0,
                    msg: '登录成功',
                    user
                }
        //可以存储用户的session
                return ctx.login(user)
            } else {
                ctx.body = {
                    code: 1,
        //info是在验证里面判断后的信息,密码错误或者用户不存在
                    msg: info
                }
            }
        }
    })(ctx, next)
})

登陆成功后的组件

router.get('/getUser', async(ctx) => {
    if (ctx.isAuthenticated()) {
        // 策略通过done将user存储到了session中, 并将sessionID写入到客户端的cookie上, 
        //将用户信息附加到请求对象req.session.passport.user上
        const { username, email } = ctx.session.passport.user
        ctx.body = {
            user: username,
            email
        }
    } else {
        ctx.body = {
            user: '',
            email: ''
        }
    }
})

退出登陆的组件

router.get('/exit', async(ctx, next) => {
    //logout方法可以删除用户的session,不带参数
    await ctx.logout()
    if (!ctx.isAuthenticated()) {
        ctx.body = {
            code: 0
        }
    } else {
        ctx.body = {
            code: -1
        }
    }
})
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!