Rails Rails 开发 SPA 项目

ecloud · 2018年08月09日 · 最后由 ecloud 回复于 2018年08月10日 · 2391 次阅读

我想在 Rails 开发单页面程序,但是 Rails 中的表单使用了 CSRF token,如何在 spa 页面的表单中填入 csrf token?

如果没有前后端分离也就是走的还是 Rails 的 layout 的话,直接用 JS 从 HTML 的 head 里取。

如果前后端分离了不依赖 cookies,也就不需要 CSRF token 了。

虽然前后端分离,但是 cookies 还是用的。

ecloud 回复

cookies 不用来做用户身份验证识别应该就没问题吧

@coderliu 最近开始新的项目,OA 系统,想用 SPA 做,但是目前还没头绪该怎么做。

coderliu 回复

我之前做了一个项目,单独开了一个 API 获取 csrf token,感觉被自己蠢哭了。。。。

ecloud 回复

😆 谁都有犯蠢的时候

这个问题我的具体理解是,传统的 CSRF 针对的是通过 cookies 来验证用户的场景。 前后端分离之后是通过在请求中带上 Token 来验证用户,cookies 不再负责验证用户,即便被跨站请求也没问题,除非 Token 被盗取了,那也就和传统场景下 cookies 被盗取没什么区别了

具体还是看 4 楼 的链接,多一层验证肯定更好

nouse 回复

非常感谢

coderliu 回复

谢谢为我解答,感觉明白不少

我是这样做的:

export default class ApiUtil {
  static apiRequest(method, url, body) {
    const options = {
      method,
      credentials: 'include',
      headers: {
        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      }
    }
    if (body) {
      options['body'] = JSON.stringify(body)
    }
    return fetch(url, options)
    ...

做 SPA 的话,表单应该不是直接提交的吧,而是监听表单的 submit 事件,并且用 event.preventDefault() 阻止表单的默认动作,再调用 api 去提交表单数据。

Rails 那边的 api 的 controller 要继承自 ActionController::API,这样就不会有 CSRF token 的验证了,至于为什么不需要 CSRF token 请参考#7 楼

fan124 回复

不使用表单的默认动作除了 CSRF 还有其它目的吗?很好奇为什么不用表单的原生行为,烦请赐教🙏

coderliu 回复

原生行为不是异步请求,所以请求完之后会“换”页面,所以就不是 SPA 了吧

fan124 回复

😁 多谢解答

coderliu 回复

因为你说了 SPA 呀。表单提交是表单提交,SPA 是 SPA……

fan124 回复

谢谢解答。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号