使用nuxt跟eggjs做的服务端渲染,目前遇到问题了,在about页面刷新,eggjs的中间件拿不到用户的session了,哪位大佬帮看看 - CNode技术社区

使用nuxt跟eggjs做的服务端渲染,目前遇到问题了,在about页面刷新,eggjs的中间件拿不到用户的session了,哪位大佬帮看看
发布于 7 年前 作者 lzq920 5365 次浏览 来自 问答

使用nuxt跟eggjs做的服务端渲染,目前遇到问题了,在about页面刷新,eggjs的中间件拿不到用户的session了,哪位大佬帮看看,不知道是nuxt这边的问题还是eggjs这边的问题

实例地址

中间件定义

const { Nuxt, Builder } = require("nuxt");
let config = require("../../nuxt.config");
module.exports = (options, app) => {
 const nuxtRender = new Nuxt(config);
 let isDev = process.env.NODE_ENV !== "production";
 if (isDev) {
 new Builder(nuxtRender).build();
 }
 return async function(ctx, next) {
 let flag = false;
 let routerArr = [];
 if (!flag) {
 routerArr = app.router.stack.map(el => el.path);
 flag = true;
 }
 if (routerArr.some(el => el === ctx.path)) {
 return await next();
 }
 ctx.status = 200;
 ctx.req.session = ctx.session;
 const { res, req } = ctx;
 return new Promise((resolve, reject) => {
 ctx.res.on("close", resolve);
 ctx.res.on("finish", resolve);
 nuxtRender.render(req, res, promise => {
 promise.then(resolve).catch(reject);
 });
 });
 };
};

about页面请求

export default {
 asyncData({ params }) {
 return axios.get("http://127.0.0.1:7001/api/info").then(res => {
 return { info: res.data };
 });
 }
};

nuxtServerInit定义

export const state = () => ({
 user: null
});
export const mutations = {
 setUser(state, data) {
 state.user = data;
 }
};
export const actions = {
 nuxtServerInit({ commit }, { req }) {
 if (req.session.user) {
 console.log("client", req.session.user);
 commit("setUser", req.session.user);
 }
 }
};
13 回复

有人给看看么???大神求教

nuxt 的模型,跟 Koa 其实不好匹配的,它是 req/res 的,你网上找到的那些,都是把 req, res 直接丢给 render,但其实是跳出了 Koa 的洋葱模型,不走中间件的了。具体哪一步的问题,你要自己一步步排查下看看了。

你只给了仓库,没有给复现步骤。

@atian25 我自己做了排查,前面都是对的,就是在about页面直接刷新,eggjs这边的session就丢失了,感觉是nuxt这边的问题。但是nuxt这边能够拿到session,不知道是不是我对session这些理解不到位。。

session不是本来就在server中进行存取吗?怎么会它自身的中间件拿不到?还是说你禁止了cookie。 如果你是说,server渲染vue页面进行的请求拿session的事情,你可以先在server中请求入口处把session挂到ctx.req对象中,然后可以在nuxtServerInit或者pluginsreq参数中获取

@lzq920 默认的 session 是基于 cookie 的,你可以看下网络通信的内容有没有对。另,egg 的 session 是加密的,如果你在 nuxt 里面有操作的话,有可能导致解密失败从而为空。

@7demo 在nuxtServerInit里面是能够正常拿到session的,哪怕页面刷新都能拿到,就后端授权中间件那里session的自定义字段丢了

@atian25 但是session中存的csrfToken都在,就自己定义的user就没了

@lzq920 断点分析下吧

https://github.com/eggjs/egg/issues/3554

刷新的时候是服务端请求,你的 axios 在服务端侧时,要把 cookie 带过去。

PS:想玩转 SSR,先把请求链路和 HTTP 这套搞明白。

export default {
 asyncData({ params, req }) {
 if(process.server){
 Object.keys(req.headers).map((key)=>{
 axios.defaults.headers.common[key] = req.headers[key];
 });
 }
 return axios.get("http://127.0.0.1:7001/api/info", { withCredentials: true }).then(res => {
 return { info: res.data };
 });
 }
};

@atian25 嗯,受教了。。。感谢

要学习如何快速定位问题:

  • 既然是请求 403 了,说明是 auth 没过
  • auth 判断的是 session,session 是基于 cookie 的
  • 那就在 middleware 那里打印下 cookie,发现没有
  • 说明是前面没有传过来,再去看看为什么没传过来。

就这样,一个个的设立阻断点,是左边的错,还是右边的错,二分查下很快就搞定了。

@atian25 一直陷入了一个误区,就是用户登录了,又设置了withCredentials:true,就会自己把cookie传过去。

回到顶部

AltStyle によって変換されたページ (->オリジナル) /