【问题标题】:axios/rack-cors/react-rails/heroku: Internal Server Error 500 on sign out, no persistence on refreshaxios/rack-cors/react-rails/heroku:退出时出现内部服务器错误 500,刷新时没有持久性
【发布时间】:2023-10-08 20:13:01
【问题描述】:

错误信息: Error: Request failed with status code 500 Stack trace: [42]/</t.exports@http://crdwk.herokuapp.com/packs/bundle-ecc8ea14dbe153e50352.js:1:89311 [42]/</t.exports@http://crdwk.herokuapp.com/packs/bundle-ecc8ea14dbe153e50352.js:1:251725 [42]/</t.exports/</d[h]@http://crdwk.herokuapp.com/packs/bundle-ecc8ea14dbe153e50352.js:1:88311

Ruby 版本: 2.3

Rails 版本: 5.1

我有一个服务器端渲染的客户端水合 React/Rails 应用程序(使用 gem 'react-rails')。

我在application.rb 中添加了gem 'rack-cors' plus 设置,以便我的请求能够正常工作(我正在使用axios)。但是,signing out(DELETE 请求)失败,并且点击刷新会擦除当前用户。本地/开发中均未出现任何问题。

这是应用程序:http://crdwk.herokuapp.com

还有回购:https://github.com/English3000/crdwk

【问题讨论】:

  • 我更喜欢使用超链接而不是图标来注销。
  • 你真的希望人们通过一堆文件来找出你把相关代码放在哪里吗?您的问题出在控制器或组件中,将代码粘贴到此处,或添加文件的直接链接

标签: ruby-on-rails heroku axios react-rails rack-cors


【解决方案1】:

我查看了我的 Heroku 日志:

Completed 500 Internal Server Error in 8ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `reset_token' for nil:NilClass):
app/controllers/application_controller.rb:29:in `sign_out'
app/controllers/api/sessions_controller.rb:3:in `destroy'

鉴于点击刷新,当前用户不会持续存在,问题是当前用户不知何故没有设置。

但是,这不是开发中的问题。为什么会这样?

查看我的项目,与客户端渲染的项目(我从字面上复制并粘贴该项目的代码)相比,我在后端发现的唯一区别是application_controller.rb 中的这一行:

skip_before_action :verify_authenticity_token

但是,如果我注释掉这一行,当我尝试注册时,我会收到服务器错误

Started POST "/api/users" for 127.0.0.1 at 2018-03-05 12:16:57 -0800
Processing by Api::UsersController#create as JSON
  Parameters: {"user"=>{"email"=>"", "password"=>"[FILTERED]"}}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)

ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:

这是使用gem 'react-rails' 的结果。 (对于我的其他客户端渲染项目,我没有收到此错误。)

没有"authenticity_token" 参数。

我找到了这两个资源:Rails securityLearnetto's how-to

所以我将第二篇文章中的这两行代码添加到我的api.js

const csrfToken = document.querySelector("meta[name=csrf-token]").content;
axios.defaults.headers.common["X-CSRF-Token"] = csrfToken;

现在我的网络应用程序可以使用注释掉的额外 application_controller.rb 行。除了,我不能使用 DOM 来获取我的 React Native 版本的 csrf 令牌,所以我现在在移动设备上遇到了同样的问题......

【讨论】:

  • 根据 React Native Networking:“XMLHttpRequest 的安全模型与 Web 不同,因为在原生应用程序中没有 CORS 的概念。”那么我不需要担心有一个真实性令牌?如果是这样,我仍然需要一种方法让我的 Rails 后端到 skip_before_action :verify_authenticity_token 仅适用于移动设备。