【问题标题】:Rails Devise Error "No route matches [GET] "/users/sign_out""Rails 设计错误“没有路线匹配 [GET]“/users/sign_out””
【发布时间】:2014-01-29 04:21:05
【问题描述】:

我只有在手动将 URL 输入浏览器时才会收到此错误。如果我点击我网站上的“退出”链接,它会很好地注销用户。这是我的“退出”链接:

<%= link_to "Sign out", destroy_user_session_path, method: :delete %>

效果很好。如果用户在地址栏中输入地址,我如何才能使退出功能正常工作?我知道这与 GET 和 DELETE 请求有关。它使用带有链接的 DELETE 请求,但在手动输入 URL 时使用 GET 请求。我该如何解决这个问题?

【问题讨论】:

  • 在 RESTful 架构中,DELETE 请求意味着我们实际上是在请求从服务器上删除一些资源。在从应用程序中注销时,我们实际上是在请求从服务器销毁/删除会话。因此,遵循 RESTful 架构,我们不能让用户通过输入 URL 来退出。这是一种不好的做法。
  • 那么大多数使用设计防止用户输入 url 并显示错误页面的 Rails 应用程序是做什么的?
  • 我们不需要定义任何东西。如果方法与路由不匹配,rails 本身将进入 404 状态。

标签: ruby-on-rails devise


【解决方案1】:

添加;

devise_scope :user do get '/users/sign_out' => 'devise/sessions#destroy' end

到路线解决了我的问题。

【讨论】:

    【解决方案2】:

    基本上, 当您尝试手动输入 url 或尝试使用新选项卡单击链接“退出”时,会有 HTTP GET 请求,您将获得 No route matches [GET] "/users/sign_out",它不存在,因为您只有通过 DELETE 请求 @ 987654326@ 在您的 routes.rb 上,对于解决方案,您可以将其添加到 config/initializer/devise.rb

    # The default HTTP method used to sign out a resource. Default is :delete.
    config.sign_out_via = Rails.env.test? ? :get : :delete
    

    并在您的routes.rb 上将DELETE 更改为MATCH 请求

    例如:match 'users/sign_out' =&gt; "devise/sessions#destroy"

    供参考:Devise for user management and authentication.

    说实话,不建议更改默认的“删除”HTTP 方法。供用户测试(例如使用黄瓜) Cucumber Testing for “Sign Out”

    Jose Valim 解释了原因:“GET 请求不应该改变 服务器。当登出是 GET 请求时,可以使用 CSRF 进行签名 你会自动退出,预加载链接的东西最终会 也会误将您注销。”

    @manoj mona 说'我们不能让用户通过输入 URL 来退出。这是一种不好的做法'

    所以,如果用户通过输入 URL 来退出。

    1. 你可以定义它,如果得到请求它会重定向或呈现通知(如stackoverflow登出)

    2. 或者不要使用link_to标签退出,使用input标签和表单(如facebook退出),所以用户不能输入URL见this answer

    【讨论】:

    • 那么每个使用 devise 的人都必须这样做才能使其正常工作吗?似乎这个问题不应该作为默认存在
    • 那么,您想设计更改默认的 HTTP 方法吗?这不是问题,而是您的if users sign out typing in the URL 中的问题。阻止用户输入网址的方法太多,请参阅此网站、facebook 网站、twitter 网站等。我已经更新了我的答案。
    【解决方案3】:

    修改devise.rb

    config.sign_out_via = :get
    

    并更改链接

    <%= link_to "log out", destroy_user_session_path, method: :get %>
    

    【讨论】:

    • 我不想那样做。我知道这是一个解决方案,但这不是最佳实践。我想继续使用 DELETE
    【解决方案4】:

    将此添加到application.js

    //= require jquery_ujs 
    

    【讨论】:

    • 这解决了我在开发中的问题。
    【解决方案5】:

    我不知道是什么原因(我是 ruby​​ on rails 的新手),但是一旦您将此行添加到您的应用程序布局中,您的问题就会得到解决,

    <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
    

    并保持注销链接如下

    <%= link_to "Sign Out", destroy_user_session_path, :method => :delete %>
    

    【讨论】:

    • 这帮助我修复了它。就我而言,我有&lt;%= javascript_include_tag "default", "data-turbolinks-track" =&gt; true %&gt;,但是当我将其更改为&lt;%= javascript_include_tag "application", "data-turbolinks-track" =&gt; true %&gt; 时,它起作用了。虽然我的退出链接语法略有不同,但如果上述解决方案仍然不起作用,请尝试将 :method =&gt; :delete 更改为 method: :delete
    • @mikeym method: :delete:method =&gt; :delete 的简写
    【解决方案6】:

    试试这个

    在路线中

    devise_scope :user do
      get '/users/sign_out' => 'sessions#destroy'
    end
    

    【讨论】:

    • 我已经尝试过了,但它不起作用。我从 rails 收到相同的错误消息
    【解决方案7】:
    devise_scope :user do
      match '/users/sign_out' => 'sessions#destroy', via: [:get, :delete]
    end
    

    【讨论】:

      【解决方案8】:

      我将 ActiveAdmin::Devise.config 添加到我的 routes.rb 中。所以整行是,

      devise_for :users, ActiveAdmin::Devise.config
      

      它实际上在 gem's generator 中,所以我相信它应该在那里,但我注意到它没有被添加到我的某些安装中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-15
        • 1970-01-01
        • 2017-08-03
        • 2015-12-09
        • 2011-09-27
        • 2012-01-30
        相关资源
        最近更新 更多