[英]Rails Devise-omniauth route points to passthru instead of twitter
I am trying to implement omniauth-twitter
with Devise in Ruby-on-Rails with no success.我正在尝试在 Ruby-on-Rails 中使用 Devise 实施
omniauth-twitter
但没有成功。 According to the definitive article of Devise , the link根据Devise 的权威文章,链接
<%= link_to "Sign up with twitter", user_twitter_omniauth_authorize_path,
method: :post %>
should take the visitor to Twitter (Note I have disabled turbo
site-wide with Turbo.session.drive = false
and so turbo
is irrelevant).应将访问者带到 Twitter(请注意,我已使用
Turbo.session.drive = false
在整个站点范围内禁用了turbo
,因此与turbo
无关)。
However, it just displays但是,它只是显示
Not found.
未找到。 Authentication passthru.
身份验证直通。
I notice the route looks wrong in the first place:我注意到路线首先看起来是错误的:
% bin/rails routes -g omni
Prefix Verb URI Pattern Controller#Action
user_twitter_omniauth_authorize GET|POST /users/auth/twitter(.:format) users/omniauth_callbacks#passthru
user_twitter_omniauth_callback GET|POST /users/auth/twitter/callback(.:format) users/omniauth_callbacks#twitter
It apparently points to Users::OmniauthCallbacksController#passthru
, which is a non-existent method, hence the error?它显然指向
Users::OmniauthCallbacksController#passthru
,这是一个不存在的方法,因此错误?
This problem has been reported multiple times in Stackoverflow and Github (eg, Github , SO1 , SO2 ).这个问题已经在 Stackoverflow 和 Github(例如Github 、 SO1 、 SO2 )中多次报告。 A general advice seems to be using POST as opposed to GET.
一般建议似乎是使用 POST 而不是 GET。 However, besides it is definitely POST in my case (as confirmed with a log file), I doubt if it is relevant to the routes!
但是,除了在我的情况下它肯定是 POST(通过日志文件确认)之外,我怀疑它是否与路由相关!
What is the probable cause of this probblem and how can I solve it?这个问题的可能原因是什么,我该如何解决?
I confirm I am using OA1 API keys as opposed to Twitter OA2 (the latter is not supported by Omniauth, yet).. Also, as the doc of omniauth-twitter suggests, I confirm that "User authentication set up" is active in the Twitter Dev center to allow users to log in.我确认我使用的是 OA1 API 密钥而不是 Twitter OA2(Omniauth 尚不支持后者)。此外,正如omniauth-twitter 的文档所建议的,我确认“用户身份验证设置”在Twitter 开发中心允许用户登录。
My relevant files are as follows:我的相关文件如下:
# Gemfile
gem 'devise'
gem 'devise-i18n'
gem 'omniauth', '~> 2.1' #, '1.9.1'
gem 'omniauth-twitter'
gem 'omniauth-rails_csrf_protection'
# /config/initializers/devise.rb
Devise.setup do |config|
config.omniauth :twitter, 'MY_APP', 'MY_SECRET'
OmniAuth.config.logger = Rails.logger if Rails.env.development? # for debug
end
Note there are no Omniauth or Twitter-related configs in config/initializers/
.请注意,在
config/initializers/
中没有 Omniauth 或 Twitter 相关的配置。 Just devise.rb
.只是
devise.rb
。
# /models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable, #...snipped...
:omniauthable, omniauth_providers: %i(twitter)
def self.from_omniauth(auth)
find_or_create_by(provider: auth.provider, uid: auth.uid) do |user|
user.display_name = auth.info.nickname.strip
user.skip_confirmation!
end
end
end
# /app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
skip_before_action :verify_authenticity_token, only: [:twitter]
def twitter
callback_from __method__
end
def callback_from(provider)
# See User model
@user = User.from_omniauth(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: provider.to_s.capitalize) if is_navigational_format?
else
session["devise.#{provider.to_s}_data"] = request.env['omniauth.auth'].except(:extra)
redirect_to new_user_registration_url(from_omniauth_callback: true)
end
end
def failure
redirect_to root_path
end
end
# /config/routes.rb
Rails.application.routes.draw do
devise_for :users, except: [:destroy],
controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
end
View (the turbo-part is meaningless, for it is globally turned off).查看(turbo-part 没有意义,因为它是全局关闭的)。
<%# /app/views/devise/registrations/new.html.erb >
<%= link_to t(".sign_up_with_twitter"), user_twitter_omniauth_authorize_path,
method: :post, data: { turbo: false } %>
The standard output of the server ( bin/dev
in Rail 7):服务器的标准 output(Rail 7 中的
bin/dev
):
00:... | I, [2022-...6 #793] INFO -- : Started POST "/en/users/auth/twitter" for 127.0.0.1 at 2022-11-27 00:33:14 +0000
00:... | I, [2022-...4 #793] INFO -- : Processing by Users::OmniauthCallbacksController#passthru as HTML
00:... | I, [2022-...0 #793] INFO -- : Parameters: {"authenticity_token"=>"[FILTERED]", "locale"=>"en"}
00:... | D, [2022-...0 #793] DEBUG -- : Rendering text template
00:... | I, [2022-...7 #793] INFO -- : Rendered text template (Duration: 0.0ms | Allocations: 10)
00:... | I, [2022-...9 #793] INFO -- : Completed 404 Not Found in 4ms (Views: 2.5ms | ActiveRecord: 0.0ms | Allocations: 1170)
omniauth-rails_csrf_protection
(0.1.2) → (1.0.1) omniauth-rails_csrf_protection
(0.1.2) → (1.0.1)
Gemfile
did not specify the version and yet a lower-version was installed. Gemfile
没有指定版本,但安装了较低版本。 I now bundle install
with '~> 1.0'
.'~> 1.0'
bundle install
在一起。 The same error still remains (after server-restart).omniauth
(2.1.0) omniauth
(2.1.0)omniauth-oauth
(1.2.0) omniauth-oauth
(1.2.0)omniauth-twitter
(1.4.0) omniauth-twitter
(1.4.0)devise
(4.8.1) devise
(4.8.1)rails
(7.0.4) rails
(7.0.4)ruby
(3.1.2) ruby
(3.1.2) That's it.而已。 Thank you.
谢谢你。
This isn't a full answer, but more of a suggestion of where to keep looking.这不是一个完整的答案,而是更多关于在哪里继续寻找的建议。
You are supposed to see (twitter) Request phase initiated.
您应该会看到
(twitter) Request phase initiated.
in the logs immediately following Started POST "/users/auth/twitter"
(from here ).在
Started POST "/users/auth/twitter"
(来自此处)之后的日志中。
But, the Omniauth controller is instead looking for an HTML template to render (and failing to find one).但是,Omniauth controller 正在寻找一个 HTML 模板来渲染(但没有找到)。
INFO -- : Started POST "/en/users/auth/twitter" for 127.0.0.1 at 2022-11-27 00:33:14 +0000
INFO -- : Processing by Users::OmniauthCallbacksController#passthru as HTML
INFO -- : Parameters: {"authenticity_token"=>"[FILTERED]", "locale"=>"en"}
DEBUG -- : Rendering text template #<--- HERE!!!!
INFO -- : Rendered text template (Duration: 0.0ms | Allocations: 10)
INFO -- : Completed 404 Not Found in 4ms (Views: 2.5ms | ActiveRecord: 0.0ms | Allocations: 1170)
This does make sense;这确实有道理; because
Users::OmniauthCallbacksController#passthru
is getting the POST request as HTML, it's looking for an HTML template to render (and failing to find one).因为
Users::OmniauthCallbacksController#passthru
正在获取 HTML 的 POST 请求,它正在寻找 HTML 模板来呈现(但找不到)。
It seems like Omniauth expects an AJAX request as JSON, not an HTML request.似乎 Omniauth 期望 AJAX 请求为 JSON,而不是 HTML 请求。
A few thoughts:一些想法:
Turn Turbo back on and see what the content-type
of the request is when Turbo gets to decide重新打开 Turbo 并在 Turbo 决定时查看请求的
content-type
Ditch the user_twitter_omniauth_authorize_path
in favor of intercepting the link click and forming an AJAX POST request using Stimulus (Rails 7) or Javascript directly to the path /users/auth/twitter
. user_twitter_omniauth_authorize_path
以拦截链接点击并使用 Stimulus (Rails 7) 或 Javascript 直接向路径/users/auth/twitter
形成 AJAX POST 请求。
The language "en" in the URL of the POST is probably coming from some other gem ( devise-i18n
?) That could be interfering with the POST request somehow and turning the content-type to HTML instead of JSON. POST 的 URL 中的语言“en”可能来自其他一些 gem(devise
devise-i18n
?)这可能会以某种方式干扰 POST 请求并将内容类型转换为 HTML 而不是 JSON。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.