I-a*_*ser 9 ruby ruby-on-rails oauth faraday
目前我正在开发rails 4项目,现在我必须链接/连接另一个应用程序(不是用于访问API的sso),例如example.com.(注意: example.com使用3脚oauth安全架构)
搜索后发现我必须实施omniouth策略.
为此,我已经审阅了这个链接.根据策略 - 贡献指南, 我能够完成设置和请求阶段,您可以在这里找到我的示例代码.
require 'multi_json'
require 'omniauth/strategies/oauth2'
require 'uri'
module OmniAuth
module Strategies
class MyAppStrategy < OmniAuth::Strategies::OAuth2
option :name, 'my_app_strategy'
option :client_options, {
site: site_url,
authorize_url: authorize_url,
request_url: request_url,
token_url: token_url,
token_method: :post,
header: { Accept: accept_header }
}
option :headers, { Accept: accept_header }
option :provider_ignores_state, true
def consumer
binding.pry
::OAuth::Consumer.new(options.client_id, options.client_secret, options.client_options)
end
def request_phase # rubocop:disable MethodLength
binding.pry
request_token = consumer.get_request_token({:oauth_callback => callback_url}, options.request_params)
session["oauth"] ||= {}
session["oauth"][name.to_s] = {"callback_confirmed" => request_token.callback_confirmed?, "request_token" => request_token.token, "request_secret" => request_token.secret}
if request_token.callback_confirmed?
redirect request_token.authorize_url(options[:authorize_params])
else
redirect request_token.authorize_url(options[:authorize_params].merge(:oauth_callback => callback_url))
end
rescue ::Timeout::Error => e
fail!(:timeout, e)
rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
fail!(:service_unavailable, e)
end
def callback_phase # rubocop:disable MethodLength
fail(OmniAuth::NoSessionError, "Session Expired") if session["oauth"].nil?
request_token = ::OAuth::RequestToken.new(consumer, session["oauth"][name.to_s].delete("request_token"), session["oauth"][name.to_s].delete("request_secret"))
opts = {}
if session["oauth"][name.to_s]["callback_confirmed"]
opts[:oauth_verifier] = request["oauth_verifier"]
else
opts[:oauth_callback] = 'http://localhost:3000/auth/callback' #callback_url
end
@access_token = request_token.get_access_token(opts)
super
rescue ::Timeout::Error => e
fail!(:timeout, e)
rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
fail!(:service_unavailable, e)
rescue ::OAuth::Unauthorized => e
fail!(:invalid_credentials, e)
rescue ::OmniAuth::NoSessionError => e
fail!(:session_expired, e)
end
def custom_build_access_token
binding.pry
verifier = request["oauth_verifier"]
client.auth_code.get_token(verifier, get_token_options(callback_url), deep_symbolize(options.auth_token_params))
end
alias_method :build_access_token, :custom_build_access_token
def raw_info
binding.pry
@raw_info ||= access_token.get('users/me').parsed || {}
end
private
def callback_url
options[:redirect_uri] || (full_host + script_name + callback_path)
end
def get_token_options(redirect_uri)
{ :redirect_uri => redirect_uri }.merge(token_params.to_hash(:symbolize_keys => true))
end
end
end
Run Code Online (Sandbox Code Playgroud)
结束
我可以重定向到example.com,也可以在登录后返回我的callback_phase(你会问你怎么知道,所以答案是我binding.pry在callback_phase方法中添加了检查流程).
但在执行策略后,我遇到了错误
错误 - omniauth:(my_app_strategy)身份验证失败!invalid_credentials:OAuth2 ::错误.
调试后发现我收到了这个super调用的错误(来自callback_phase方法).
首先,我可能会有一些凭据问题,但我可以使用以下(在super调用之前执行)获取访问令牌
@access_token = request_token.get_access_token(opts)
Run Code Online (Sandbox Code Playgroud)
另外,对于更多信息,我得到的错误build_access_token是oauth2方法
您可以参考此链接以获取更多信息(只需搜索页面上的build_access_token).
编辑 - 1
调试后发现从请求方法中获取此问题.(在提出法拉第请求时).这是代码片段
response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
yield(req) if block_given?
end
Run Code Online (Sandbox Code Playgroud)
这是我的法拉第请求
#<struct Faraday::Request method=:post, path="example.com/oauth/access_token", params={}, headers={"User-Agent"=>"Faraday v0.9.2", "Content-Type"=>"application/x-www-form-urlencoded"}, body={"grant_type"=>"authorization_code", "code"=>"aPexxxvUg", "client_id"=>"xxxxxur303GXEch7QK9k", "client_secret"=>"xxxxxxcad97b3d252e2bcdd393a", :redirect_uri=>"http://localhost:3000/auth/my_app_strategy/callback"}, options=#<Faraday::RequestOptions (empty)>>
Run Code Online (Sandbox Code Playgroud)
作为响应,我收到以下错误消息
HTTP状态400 - OAuth使用者凭据不足.
那么任何人都可以帮助解决这个问题吗?
是否有任何其他方式来存储访问令牌,以便我可以利用它来进行通信.谢谢
小智 4
首先,我想弄清楚Oauth2是如何工作的:
Oauth2,协议说:
您将用户重定向到提供者登录端点,添加一些必需的参数(Ejm:PROVIDER/public/oauth?redirect_uri=MYWEB/oauthDemo&response_type=code&client_id=ABCDE)。有时还有一个范围/权限/资源参数来指示您的目的。
-> 然后用户登录并使用代码重定向到您的端点 MYWEB/public/oauth
现在,您必须请求访问令牌,向提供者端点执行 POST。例子:
POST PROVIDER?code=d5Q3HC7EGNH36SE3N& client_id=d4HQNPFIXFD255H& client_secret=1a98b7cb92407cbd8961cd8db778de53& redirect_uri= https://example.com/oauthDemo& grant_type=authorization_code
现在您有了 access_token,您可以使用它来获取信息或使用 JWT 对其进行解码。
清楚这一点,并看到您的电话似乎是正确的:
#<struct Faraday::Request method=:post, path="PROVIDER/oauth/access_token", params={}, headers={"User-Agent"=>"Faraday v0.9.2", "Content-Type"=>"application/x-www-form-urlencoded"}, body={"grant_type"=>"authorization_code", "code"=>"aPexxxvUg", "client_id"=>"xxxxxur303GXEch7QK9k", "client_secret"=>"xxxxxxcad97b3d252e2bcdd393a", :redirect_uri=>"MYWEB/auth/my_app_strategy/callback"}, options=#<Faraday::RequestOptions (empty)>>
Run Code Online (Sandbox Code Playgroud)
由于响应是“HTTP 状态 400 - OAuth 消费者凭据不足。”,我想也许您:
A。您的客户端在提供程序上配置不正确。通常,您通常会在提供商网站上进行基本配置,以便他能够识别您。所以可能是配置不好。
b. 第一步(在重定向到提供程序时)缺少或配置了错误的资源/权限/范围参数。所以当你请求令牌时就会出现问题。
| 归档时间: |
|
| 查看次数: |
2188 次 |
| 最近记录: |