tl:博士;
節點(express)服務器托管在 Heroku 上,UI 托管在 Netlify 上。當 UI 對服務器進行 REST API 呼叫時,會話不會持續存在(但如果我在本地運行兩者,它會持續存在。localhost:5000在服務器上,localhost:3000在 UI 上。UI 正在使用 代理請求package.json)。
代碼片段
session.ts
export const sessionConfig = {
secret: process.env.SESSION_KEY,
store: new RedisStore({ client: redisClient }),
resave: true,
saveUninitialized: true,
cookie: {
secure: process.env.NODE_ENV === 'production',
sameSite: process.env.NODE_ENV === "production" ? 'none' : 'lax',
},
};
server.ts
const app = express();
app.use(express.json());
app.use(cookieParser());
app.set('trust proxy', 1);
app.use(session(sessionConfig)); // This sessionConfig comes from the file above
app.use(cors({
credentials: true,
origin: process.env.CLIENT_URL,
}));
我用谷歌搜索了類似的東西express session not persist when cross domain request。然后,我看到了類似this和this的執行緒。似乎這app.set('trust proxy', 1)將確保會話資料將為跨域請求保留。顯然,就我而言,仍然缺少一些東西。
有誰看到我做錯了什么?任何建議將被認真考慮!
PS:
我正在使用會話進行驗證碼測驗,看起來像......
captch.ts
CaptchaRouter.get('/api/captcha', async (req: Request, res: Response) => {
const captcha = CaptchaService.createCaptcha();
req.session.captchaText = captcha.text;
res.send(captcha.data);
});
CaptchaRouter.post('/api/captcha', async (req: Request, res: Response) => {
if (req.session.captchaText !== req.body.captchaText) {
throw new BadRequestError('Wrong code was provided');
}
// The client sent the correct captcha
},
);
另一個 PS: 這是回應 heders 的樣子:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://example.netlify.app
Connection: keep-alive
Content-Length: 46
Content-Type: application/json; charset=utf-8
Date: Sun, 09 Jan 2022 00:00:00 GMT
Etag: W/"2e-cds5jiaerjikllkslaxmalmird"
Server: Cowboy
Set-Cookie: connect.sid=s%3ramdon-string-here; Path=/; Expires=Sun, 09 Jan 2022 00:00:00 GMT; HttpOnly; Secure; SameSite=None
Vary: Origin
Via: 1.1 vegur
X-Powered-By: Express
uj5u.com熱心網友回復:
原因是客戶端(托管在 Netlify 上)沒有代理 API 請求。
解決方案是:
- 在客戶端
_redirects下添加public
/api/* https://server.herokuapp.com/api/:splat 200
/* /index.html 200
- 確保來自客戶端的 API 請求將以根 URL 開頭
return axios({ method: 'POST', url: '/api/example', headers: defaultHeaders });
供將來參考,這是我的會話配置
const sessionConfig = {
secret: process.env.SESSION_KEY || 'This fallback string is necessary for Typescript',
store: new RedisStore({ client: redisClient }),
resave: false,
saveUninitialized: true,
cookie: {
secure: process.env.NODE_ENV === 'production', // Prod is supposed to use https
sameSite: process.env.NODE_ENV === "production" ? 'none' : 'lax', // must be 'none' to enable cross-site delivery
httpOnly: true,
maxAge: 1000 * 60
} as { secure: boolean },
};
......這里是 server.ts
const app = express();
const port = process.env.PORT || 5000;
app.use(express.json());
app.set('trust proxy', 1);
app.use(session(sessionConfig));
app.use(cors({
credentials: true,
origin: process.env.CLIENT_URL,
}));
(正如@Matt Davis 指出的那樣,cookieParser沒有必要)
附言
我沒有嘗試在會話配置中設定cookie.domain 。如果將其設定為客戶端 URL(由 Netlify 提供),會話 cookie 是否持續存在?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/414273.html
標籤:
