我的应用程序分为客户端和服务器。Client 是托管在 Now.sh 上的前端 Nextjs 应用程序,Server 是其后端使用 Express 创建并托管在 Heroku 上,因此域是 client-app.now.sh 和 server-app.herokuapp.com 。
验证
身份验证系统基于 cookie,我使用 express-session 来实现它。这是我的快速会话配置
app.use(
session({
store:
process.env.NODE_ENV === "production"
? new RedisStore({
url: process.env.REDIS_URL
})
: new RedisStore({
host: "localhost",
port: 6379,
client
}),
name: "sessionID",
resave: false,
saveUninitialized: false,
secret: keys.SESSION,
unset: "destroy",
cookie: {
domain:
process.env.NODE_ENV === "production"
? ".client-app.now.sh"
: "localhost",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
maxAge: 7 * 24 * 60 * 60 * 1000
}
})
); …Run Code Online (Sandbox Code Playgroud) 按照Nextjs 存储库中的这个示例,我想实现 CSRF 保护(可能使用csurf包),因为我使用带有 express-session 的会话 ID cookie。
我尝试在我的自定义服务器中设置 csurf 并将生成的令牌保存在 res.locals.csrfToken 中,可以在第一页加载时通过位于 /lib/withApollo.js 中的静态方法“getInitialProps”获取我的示例链接。一旦我尝试更改页面(带有链接)或尝试使用 apollo 发出发布请求(例如登录),服务器就会更改 csrf 令牌,因此 Apollo 使用的令牌不再有用,所以我得到了“csrf 无效”错误。
带有 csurf 配置的自定义服务器
const csrf = require('csurf');
const csrfProtection = csrf();
////express-session configuration code////
app.use(csrfProtection);
app.use((req, res, next) => {
res.locals.csrfToken = req.csrfToken();
next();
})
Run Code Online (Sandbox Code Playgroud)
/lib/initApollo.js
function create(initialState, { getToken, cookies, csrfToken }) {
const httpLink = createHttpLink({
uri: "http://localhost:3000/graphql",
credentials: "include"
});
const authLink = setContext((_, { headers }) => {
const token …Run Code Online (Sandbox Code Playgroud)