RubyonRails在表单提交时:“您想要的更改被拒绝”

shstlldc  于 2021-09-29  发布在  Java
关注(0)|答案(2)|浏览(365)

ruby 3.0.1 rails 6.1.2 'devise', '~> 4.7', '>= 4.7.3' 我的处境很不寻常。我正在将rails安装从一台服务器迁移到另一台服务器。我相信我已经完成了95%的工作,刚刚恢复了生产数据库。
但是,任何涉及表单提交的内容,包括用户注册和登录,都会显示错误页面:

The change you wanted was rejected.

Maybe you tried to change something you didn't have access to.

服务器日志提供了更有用的信息:

Completed 422 Unprocessable Entity in 2ms (Allocations: 433)
FATAL -- ActionController::InvalidAuthenticityToken

这使我困惑。因为我确实重新生成了master.key和credentials.yml.enc,并通过 RAILS_MASTER_KEY 环境变量。这意味着表单具有适当的 <input type="hidden" name="authenticity_token" value="<removed for stack_overflow>"> 包括以防止跨站点脚本攻击。
我认为这与会话无关,因为即使是用户注册也会受到影响。我正在使用Desive进行身份验证。
但是现在我碰上了一堵砖墙。从此无路可走。有人知道怎么了吗?
更新1
添加 skip_before_action :verify_authenticity_token 允许我跳过这个问题。作为一种解决办法,我对此感到不舒服。
更新2
我有这些元标签。

<%= csrf_meta_tags %>
<%= csp_meta_tag %>
aemubtdh

aemubtdh1#

您的表单没有发送 X-CSRF-TOKEN 标题以及他们的请求。此标题是一种安全功能,您关闭它时感到不舒服是对的。这是阻止某人上台的部分原因 evil.com 将表格发送到 yourwebsite.co .
开箱即用导轨 <%= forms_* %> 为你做这件事,你可能会有一些习惯。
如果您是从javascript发送这些请求。我会这样做:

let token = document.querySelector("meta[name='csrf-token']").content
fetch(url, {
    method,
    headers: {
        'X-CSRF-Token': auth_token, // <---- this
        'X-Requested-With': 'XMLHttpRequest',
        ...
    },
...

也有可能您没有将其包含在您的应用程序中 application.html.erb 因此表单无法找到它。

<!DOCTYPE html>
<html>
<head>
  <%= csrf_meta_tags %> <!-- you need this! -->
...
rsl1atfo

rsl1atfo2#

我不好意思承认这一点。但nginx配置不正确。当我到达rails的临界点时,我终于开始问这是怎么发生的。
事情是这样的。在内部,rails使用http访问各种端点。我有一个nginx重定向块,如下所示:

server {
  listen 80 default_server;

  server_name _;

  return 301 https://$host$request_uri;
}

这意味着,每次在http上点击内部端点时,它都会转换为带有301。。。这一直是一个问题。我曾经 config.force_ssl = true 在里面 production.rb ,我只需要重做我的ngix配置来支持它。
这是工作配置。

location / {
  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto https;
  proxy_redirect off;
  proxy_pass http://app:3000;
}

它看起来像是身份验证令牌问题的原因是,一旦请求作为get发送,它就是一个不可处理的实体。虽然我可以在浏览器中看到它,但当它到达那里时,它很可能是零或其他东西。只是动词错了。

相关问题