Rob*_*neo 5 rack http-authentication oauth-2.0 omniauth ruby-on-rails-3
我正在使用Spree构建一个ecomm服务,该服务使用了Devise,其中包含来自用户的所有数据,但是我们仅通过API将其用作服务,因此我们有一个应用程序(rails 3.1),客户端/消费者,使用OmniAuth的用户有一个自定义策略,该策略通过Oauth2将请求重定向到提供程序,显示符号为page,然后让请求通过authorize方法,然后整个oauth2流程将正常工作,直到回调,然后用户登录到我们的消费者。
在这部分之前,一切正常,这是我的策略类:
module OmniAuth
module Strategies
class MyStrategy < OAuth2
def initialize(app, api_key = nil, secret_key = nil, options = {}, &block)
client_options = {
:site => CUSTOM_PROVIDER_URL,
:authorize_url => "#{CUSTOM_PROVIDER_URL}/auth/my_provider/authorize",
:token_url => "#{CUSTOM_PROVIDER_URL}/auth/my_provider/access_token"
}
super(app, :onyx_oauth, api_key, secret_key, client_options, &block)
end
protected
def user_data
response = @access_token.get("/auth/my_provider/user.json");
if response.status.to_i == 200
@data ||= MultiJson.decode(response.body);
else
raise 'Service error'
end
end
def request_phase
options[:scope] ||= "read"
super
end
def user_hash
user_data
end
def auth_hash
OmniAuth::Utils.deep_merge(super, {
'uid' => user_data["uid"],
'user_info' => user_data['user_info'],
'extra' => user_data['extra']
})
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
我想要做的是在客户端应用程序中具有登录表单,然后使用我的自定义策略,将这些凭据(电子邮件/密码)发送给提供程序(我正在考虑通过HTTP_AUTHORIZATION标头),以记录用户进入提供者,跳过提供者中的登录表单,因此在devise对用户进行身份验证之后,它会通过authorize方法,并使整个Oauth2过程继续进行。
我一直在尝试几种方法,包括在策略中定义方法call(env)并在调用super之前使用“ email:password”之类的凭据设置env ['HTTP_AUTHORIZATION']。我还在选项哈希中的request_phase方法中包括了“ HTTP_AUTHORIZATION”键,即使在:headers键中也是如此。我最后的尝试是将其包含在该类的客户端对象(OAuth2 :: Client实例)内的Faraday连接对象的标头哈希中。
在调试了几乎整个过程并尝试将其包含在所有地方之后,我的提供程序一直没有在标头中获取该特定密钥,甚至在Devise测试每种策略时都调试了该提供程序……但毕竟不走运。
如果有人会告诉我我做错了什么,或者如果我尝试完成的事情无法用我做的方式完成,或者有更简单的方法来完成,我将非常感谢。
在此先感谢您的冗长的帖子/问题,并再次感谢您的宝贵时间!
我想这可能就是您正在寻找的:
摘自https://github.com/jackdempsey/omniauth-reddit
module OmniAuth
module Strategies
class Reddit < OmniAuth::Strategies::OAuth2
#class NoAuthorizationCodeError < StandardError; end
option :name, "reddit"
option :authorize_options, [:scope, :duration]
option :client_options, {
site: 'https://oauth.reddit.com',
token_url: 'https://ssl.reddit.com/api/v1/access_token'
}
uid { raw_info['id'] }
info do
{
name: raw_info['name']
}
end
extra do
{'raw_info' => raw_info}
end
def raw_info
@raw_info ||= access_token.get('/api/v1/me').parsed || {}
end
def build_access_token
options.token_params.merge!(:headers => {'Authorization' => basic_auth_header })
super
end
def basic_auth_header
"Basic " + Base64.strict_encode64("#{options[:client_id]}:#{options[:client_secret]}")
end
MOBILE_USER_AGENTS = 'webos|ipod|iphone|mobile'
def request_phase
options[:client_options].authorize_url = mobile_request? ? 'https://ssl.reddit.com/api/v1/authorize.compact' : 'https://ssl.reddit.com/api/v1/authorize'
super
end
def mobile_request?
ua = Rack::Request.new(@env).user_agent.to_s
ua.downcase =~ Regexp.new(MOBILE_USER_AGENTS)
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1494 次 |
| 最近记录: |