The*_*olf 5 csrf apollo express-session graphql next.js
按照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 = getToken();
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
Cookie: cookies ? cookies : "",
"x-xsrf-token": csrfToken ? csrfToken : ""
}
};
});
Run Code Online (Sandbox Code Playgroud)
/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
}
);
Run Code Online (Sandbox Code Playgroud)
有了这个配置,每条路由都受到了 csrf 的保护,但是服务器上创建的令牌经常变化,Apollo 无法在需要时立即检索更新的令牌,因此第一次加载成功,但随后的页面更改(链接)或任何发布请求失败,因为令牌已更改。
经过这么多浏览,我终于能够发送 csrf cookie。我认为问题在于这个词return。当您使用 return 时,它会排除 cookie。这就是我通过编辑所做的/lib/initApollo.js。
函数创建(initialState,{ getToken,cookies,csrfToken }){
const httpLink = createHttpLink({
uri: "http://localhost:3000/graphql",
凭据:“包括”
});
const authLink = setContext((_, { headers }) => {
const token = getToken();
返回 {
标题:{
...标题,
授权:令牌?`Bearer ${token}` : "",
“x-xsrf-token”:csrfToken ?csrfToken : ""
}
饼干: {
...饼干
}
};
});
});
喂!!但是 SSR 没有 cookie。我认为我们应该有两个来自客户端的端点,另一个用于 SSR。SSR url 可以免 csrf。
这可能不是您正在寻找的答案。我在这里读到,如果您使用 JWT,则不需要 CSRFToken。我不完全确定,但这是目前唯一的办法。
本杰明·M解释如下:
我找到了一些关于CSRF+不使用cookie进行身份验证的信息:
https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/ “由于您不依赖cookie,因此不需要防止跨站点请求”
http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/ “如果我们采用 cookies 方式,您确实需要执行 CSRF 来避免跨站点请求。这是我们可以做到的正如您将看到的,使用 JWT 时会忘记。” (JWT = Json Web Token,无状态应用程序基于令牌的身份验证)
http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services “在不冒 CSRF 漏洞风险的情况下进行身份验证的最简单方法就是避免使用 cookie 来识别用户”
http://sitr.us/2011/08/26/cookies-are-bad-for-you.html “CSRF 的最大问题是 cookie 完全无法防御此类攻击。如果您使用 cookie 身份验证您还必须采取额外的措施来防止 CSRF。您可以采取的最基本的预防措施是确保您的应用程序在响应 GET 请求时不会产生任何副作用。
还有很多页面指出,如果您不使用 cookie 进行身份验证,则不需要任何 CSRF 保护。当然,您仍然可以将 cookie 用于其他所有用途,但避免在其中存储诸如 session_id 之类的任何内容。
完整文章在这里:使用无状态(=无会话)身份验证时需要 CSRF 令牌吗?
| 归档时间: |
|
| 查看次数: |
8498 次 |
| 最近记录: |