前端工程小技巧

koa-passport中ctx.isAuthenticated

2019-03-20  本文已影响0人  千茉紫依
问题描述

1.使用koa-passport加载了Strategy之后,测试在koa接口上login函数返回正常,logout函数返回正常,用户可以正常登陆和注销登录

2.但是,在登陆之后,执行一些需要判断登录状态的操作,比如进入个人空间,加入购物车等,调用相关koa接口,一直返回ctx.isAuthenticated()==false ,一直显示用户为未登录状态,无法进行用户状态管理

原因分析

1.经过分析,发现在登录时serializeUser函数会执行,在redis中写入用户数据,但是deserializeUser却没有执行,浏览器中也没有cookie。没有cookie,那么再接下来的请求中,无法和服务器redis中的数据相比对,自然是登录失败

// serializeUser 在用户登录验证成功以后将会把用户的数据存储到 session 中
passport.serializeUser(function (user, done) {
    console.log(user);
    done(null, user)
})
// deserializeUser 在每次请求的时候将从 session 中读取用户对象
passport.deserializeUser(function(user, done) {
    console.log(user);
    return done(null, user)
  });
redis中写入了用户数据 但浏览器中没有cookie

2.造成此现象的原因是前后端分离,使前端请求的cookie被丢弃所致

解决方案

首先封装axios请求包,新建axios.js,添加withCredentials配置项

import axios from 'axios'

const service = axios.create({
  withCredentials: true     // 允许携带cookie
})

export default service

然后在koa服务器index.js中添加如下中间件

const cors = require('koa2-cors')
app.use(cors({
    credentials: true,    // 允许读取cookie
    origin: 'http://127.0.0.1:3000'   // 此处填写前端跨域后被转译的地址
}))

何为前端跨域后被转译的地址(荐读,可跳过)

比如nuxt的热刷新服务器默认地址是 http://localhost:3000,在对外发起链接请求时,本机会根据C:\Windows\System32\drivers\etc\hosts中的配置自动将默认地址修改为http://127.0.0.1:3000,以便进行路由聚合匹配,因而,前端请求从伊始就已经跨域,跨域请求为了保证安全,会把往来的cookie全部丢弃,因而就会出现上述能够登录认证成功,在服务器redis中存在用户信息,而本地cookie中不存在信息的情况。而我们使用cors中的credentials和origin选项,就是保证在传输中能够使用cookie,但这种传输也仅限于服务器与特定的origin地址,即被本机修改成的http://127.0.0.1:3000,如果前后端分离的话,此处origin应填写代理的地址

最后在前端页面,对所有需要进行验证用户的请求,使用上文axios的新封装
这样,后端就可以接收到携带cookie的请求了,类似以下这种

import axios from ' ../util/axios.js ';
 aysnc getCart(){
    let result = await axios.get('/user/userCart', { params: { username } })
 }
注意不要使用this.$axios、ctx.$axios、app.$axios等写法,
他们不能携带cookie,会导致认证失效 
此时浏览器已经存储了cookie
上一篇 下一篇

猜你喜欢

热点阅读