【发布时间】:2019-06-07 15:46:00
【问题描述】:
在 Nextjs 存储库中遵循 this example 之后,我想实现 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();
})
/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 = getToken();
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
Cookie: cookies ? cookies : "",
"x-xsrf-token": csrfToken ? csrfToken : ""
}
};
});
/lib/withApollo.js
static async getInitialProps(ctx) {
const {
Component,
router,
ctx: { req, res }
} = ctx;
const apollo = initApollo(
{},
{
getToken: () => parseCookies(req).token,
cookies: req ? req.headers.cookie : "",
csrfToken: res ? res.locals.csrfToken : document.cookie
}
);
有了这个配置,每条路由都被csrf保护了,但是服务器上创建的token经常发生变化,Apollo无法在需要的时候立即检索更新的token,所以第一次加载成功,但是后续页面发生变化(链接)或任何发布请求失败,因为令牌已更改。
【问题讨论】:
-
您找到解决方案了吗?我也面临同样的问题
-
也卡在这里。有什么想法吗??
标签: graphql csrf apollo next.js express-session