问题描述
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
网友评论