我正在将Express App用于带有Nuxt(服务器端渲染)的后端和VueJ。我的问题是,刷新会话时未保存cookie。
服务器:
const express = require('express')
const cookieParser = require('cookie-parser')
const { loadNuxt } = require('nuxt')
const app = express()
app.use(cookieParser())
// Middleware
app.use(async (req, res, next) => {
// ...
if (sessionExpired && refreshTokenIsValid) {
// Generate new session
// ...
res.cookie('sessionToken', token, { maxAge: 86400000, path: '/' })
res.cookie('sessionId', id, { maxAge: 86400000, path: '/' })
res.cookie('refreshToken', refreshToken, { maxAge: 86400000, path: '/' })
return next()
}
})
...
登录路线
router.get('/login', async (req, res, next) => {
// ...
res.cookie('sessionToken', token, { maxAge: 86400000, path: '/' })
res.cookie('sessionId', id, { maxAge: 86400000, path: '/' })
res.cookie('refreshToken', refreshToken, { maxAge: 86400000, path: '/' })
res.status(200).redirect('/')
})
客户:
async asyncData({ $axios }) {
const data = await $axios.get('/something')
},
methods: {
async someMethod() {
let data = await this.$axios.$get('/something')
}
}
答案 0 :(得分:0)
从asyncData()发送请求时未保存cookie。
我通过使用axios帮助器解决了这个问题。
解决方案来源:proxy cookies
// plugins/ssr-cookie-proxy.js
import { parse as parseCookie } from 'cookie';
function parseSetCookies(cookies) {
return cookies
.map(cookie => cookie.split(';')[0])
.reduce((obj, cookie) => ({
...obj,
...parseCookie(cookie),
}), {});
}
function serializeCookies(cookies) {
return Object
.entries(cookies)
.map(([name, value]) => `${name}=${encodeURIComponent(value)}`)
.join('; ');
}
function mergeSetCookies(oldCookies, newCookies) {
const cookies = new Map();
function add(setCookie) {
const cookie = setCookie.split(';')[0];
const name = Object.keys(parseCookie(cookie))[0];
cookies.set(name, cookie);
}
oldCookies.forEach(add);
newCookies.forEach(add);
return [...cookies.values()];
}
export default function ({ $axios, res }) {
$axios.onResponse((response) => {
const setCookies = response.headers['set-cookie'];
if (setCookies) {
// Combine the cookies set on axios with the new cookies and serialize them
const cookie = serializeCookies({
...parseCookie($axios.defaults.headers.common.cookie),
...parseSetCookies(setCookies),
});
$axios.defaults.headers.common.cookie = cookie; // eslint-disable-line no-param-reassign
// If the res already has a Set-Cookie header it should be merged
if (res.getHeader('Set-Cookie')) {
const newCookies = mergeSetCookies(
res.getHeader('Set-Cookie'),
setCookies,
);
res.setHeader('Set-Cookie', newCookies);
} else {
res.setHeader('Set-Cookie', setCookies);
}
}
});
}