Omniauth2 设计 Coinbase 策略
Omniauth2 Devise Coinbase strategy
我正在使用 Devise 使用 Google 和 CoinBase oauth2 策略构建一个应用程序。我几乎完全遵循了 Devise oauth 说明,但我仍然无法使用 CoinBase 进行身份验证。我在登录时遇到的错误是 Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
。通过 Google 的身份验证在开发和生产模式下均能完美运行。以下是每个适用的文件:
config/initializers/devise.rb
config.omniauth :google_oauth2, ENV['google_id'], ENV['google_secret']
config.omniauth :coinbase, ENV['coinbase_id'], ENV['coinbase-secret']
OmniAuth.config.logger = Rails.logger if Rails.env.development?
controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def coinbase
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, :kind => "Coinbase") if is_navigational_format?
else
session["devise.coinbase_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def google_oauth2
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format?
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :async,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, omniauth_providers: [:google_oauth2, :coinbase]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
def self.new_with_session(params, session)
super.tap do |user|
if (data = session["devise.google_data"] && session["devise.google_data"]["extra"]["raw_info"]) || (data = session["devise.coinbase_data"] && session["devise.coinbase_data"]["extra"]["raw_info"])
user.email = data["email"] if user.email.blank?
end
end
end
我一直在试图找出可能触发失败的原因,我所想到的只是 omniauth-coinbase gem 可能不再受支持。还有其他人 运行 在 CoinBase 上使用 oauth2 遇到困难吗?
编辑:oauth 请求的日志
Started GET "/users/auth/coinbase" for 127.0.0.1 at 2017-11-06 19:29:57 -0600
(coinbase) Request phase initiated.
Started GET "/users/auth/coinbase" for 127.0.0.1 at 2017-11-06 19:29:57 -0600
(coinbase) Request phase initiated.
Started GET "/users/auth/coinbase/callback?code=#{redacted_coinbase_client_id}&state={redacted_coinbase_secret}" for 127.0.0.1 at 2017-11-06 19:30:06 -0600
(coinbase) Callback phase initiated.
(coinbase) Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
{"error":"invalid_client","error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."}
Processing by Users::OmniauthCallbacksController#failure as HTML
Parameters: {"code"=>redacted_coinbase_client_id, "state"=>redacted_coinbase_secret}
Redirected to http://portalbase.dev/
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
我在这个项目上遇到了死胡同,但我确实找出了问题的根源。 Coinbase 只允许你重定向到 https 域,如果你使用本地主机,这是一个问题。
解决方案是为本地域设置 SSL 证书(我不具备这方面的专业知识)或使用 ngrok 之类的服务。
我正在使用 Devise 使用 Google 和 CoinBase oauth2 策略构建一个应用程序。我几乎完全遵循了 Devise oauth 说明,但我仍然无法使用 CoinBase 进行身份验证。我在登录时遇到的错误是 Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
。通过 Google 的身份验证在开发和生产模式下均能完美运行。以下是每个适用的文件:
config/initializers/devise.rb
config.omniauth :google_oauth2, ENV['google_id'], ENV['google_secret']
config.omniauth :coinbase, ENV['coinbase_id'], ENV['coinbase-secret']
OmniAuth.config.logger = Rails.logger if Rails.env.development?
controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def coinbase
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, :kind => "Coinbase") if is_navigational_format?
else
session["devise.coinbase_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def google_oauth2
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format?
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
def failure
redirect_to root_path
end
end
models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :async,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, omniauth_providers: [:google_oauth2, :coinbase]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
end
end
def self.new_with_session(params, session)
super.tap do |user|
if (data = session["devise.google_data"] && session["devise.google_data"]["extra"]["raw_info"]) || (data = session["devise.coinbase_data"] && session["devise.coinbase_data"]["extra"]["raw_info"])
user.email = data["email"] if user.email.blank?
end
end
end
我一直在试图找出可能触发失败的原因,我所想到的只是 omniauth-coinbase gem 可能不再受支持。还有其他人 运行 在 CoinBase 上使用 oauth2 遇到困难吗?
编辑:oauth 请求的日志
Started GET "/users/auth/coinbase" for 127.0.0.1 at 2017-11-06 19:29:57 -0600
(coinbase) Request phase initiated.
Started GET "/users/auth/coinbase" for 127.0.0.1 at 2017-11-06 19:29:57 -0600
(coinbase) Request phase initiated.
Started GET "/users/auth/coinbase/callback?code=#{redacted_coinbase_client_id}&state={redacted_coinbase_secret}" for 127.0.0.1 at 2017-11-06 19:30:06 -0600
(coinbase) Callback phase initiated.
(coinbase) Authentication failure! invalid_credentials: OAuth2::Error, invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.
{"error":"invalid_client","error_description":"Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."}
Processing by Users::OmniauthCallbacksController#failure as HTML
Parameters: {"code"=>redacted_coinbase_client_id, "state"=>redacted_coinbase_secret}
Redirected to http://portalbase.dev/
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)
我在这个项目上遇到了死胡同,但我确实找出了问题的根源。 Coinbase 只允许你重定向到 https 域,如果你使用本地主机,这是一个问题。
解决方案是为本地域设置 SSL 证书(我不具备这方面的专业知识)或使用 ngrok 之类的服务。