Laravel SPA 是不是仍应使用 CSRF 令牌来保证安全?
Posted
技术标签:
【中文标题】Laravel SPA 是不是仍应使用 CSRF 令牌来保证安全?【英文标题】:Should a Laravel SPA still use a CSRF token for security?Laravel SPA 是否仍应使用 CSRF 令牌来保证安全? 【发布时间】:2017-10-29 03:16:51 【问题描述】:在使用 Laravel 和 Vue.js 构建一个小型 SPA 时,我在使用 CSRF 时遇到了很多困难:
我使用index.html
作为唯一视图,其余部分由vue-router
使用单个文件组件(即.vue
文件)处理
因为我没有在前面使用 php 或 Blade,我无法将 csrf_token()
注入到我的视图中。即使我这样做了,令牌最终也会过期,但是由于应用程序没有(或很少)页面刷新,它不会知道令牌是否更改,并且最终无法使用旧的 AJAX 请求令牌
Some answers 建议将令牌传递到 cookie 中,然后用 JS 检索。这种方法存在与上述相同的问题——令牌更改时永远不会通知 SPA
我可以挖掘 Laravel 的内部工作原理,并在每次令牌更改时抛出一个事件;前端可以使用Laravel Echo 来监听变化,但是问题来了,这还值得费心吗?
最后,有人建议我使用 JWT;但是,据我了解,JWT 用于身份验证,而 CSRF 用于每个请求,无论 HTTP 动词或意图如何。
考虑到最后两点,你认为在 Laravel SPA 中使用 CSRF 令牌是否必要/可取?如果是这样,最好的实现是什么(带有令牌的 cookie、返回令牌的专用路由或其他)?如果没有,有什么替代方案?
【问题讨论】:
只是关于你的第三条的想法:如果 Laravel 通过 cookie 更改 CSRF 令牌并且你在 Vue 上有一个interceptor
将始终检索 cookie,它是否仍会检索旧的 CSRF,因为页面没有重装?浏览器不会收到ajax请求的cookie变化吗?
另一个想法:你可以让 Laravel 在每个被 Vue 拦截的请求上添加一个自定义的 HTTP Header 并将其存储起来以供下一个请求使用。应用程序使用 Blade 传递的有效 CSRF 启动。第一个 Ajax 将包含接下来应该使用的令牌。
@MarcoAurélioDeleu 你能用拦截器扩展你的想法吗?我相信它需要vue-resource
包,它实际上已被 Vue 2.0 中的 Axios 取代?你能举一个代码例子吗?将不胜感激
【参考方案1】:
评论没有足够的空间,所以我添加这个作为答案,但这只是一个概念,因为我对 Vue 的经验极少。
From the docs
// Add a request interceptor
axios.interceptors.request.use(function (config)
// Do something before request is sent
return config;
, function (error)
// Do something with request error
return Promise.reject(error);
);
// Add a response interceptor
axios.interceptors.response.use(function (response)
// Do something with response data
return response;
, function (error)
// Do something with response error
return Promise.reject(error);
);
所以这个概念应该是这样的:
Set a custom header from Laravel。 在构建/启动 Vue 应用程序时,获取自定义标头并将其设置在全局位置。发出请求时,拦截它并从全局存储中添加 CSRF 令牌
axios.interceptors.request.use(function (config) // 从你存储它的地方获取你的令牌并添加到请求中 );
拦截响应并存储新令牌
axios.interceptors.response.use(function (response) // 将新的 CSRF 令牌存储在您存储第一个令牌的相同位置。 );
永远循环
【讨论】:
以上是关于Laravel SPA 是不是仍应使用 CSRF 令牌来保证安全?的主要内容,如果未能解决你的问题,请参考以下文章
带有 Sanctum 身份验证的 Laravel 8 (Reactjs SPA)
如何使用 CSRF 令牌测试 Laravel / Sanctum 端点
为啥我的 CSRF 令牌与 Laravel 和 Sanctum 不匹配?