2016-05-20 19 views
9

Hiện tại tôi đang làm việc trên dự án đường ray 4 và bây giờ tôi phải liên kết/kết nối ứng dụng khác (không phải sso nhưng để truy cập API) nói ví dụ .com. (Lưu ý:example.com sử dụng kiến ​​trúc an ninh oauth 3 chân)Bắt lỗi "Xác thực thất bại! Invalid_credentials: OAuth2 :: Lỗi" cho chiến lược omniauth tùy chỉnh

Sau khi tìm kiếm thấy rằng tôi phải thực hiện omniouth chiến lược.

Đối với điều này, tôi đã xác nhận liên kết this. Theo Strategy-Contribution-Guide Tôi có thể hoàn tất thiết lập và yêu cầu Giai đoạn, Bạn có thể tìm thấy mã mẫu của tôi tại đây.

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 

cuối

Tôi chuyển hướng có thể example.com, cũng sau khi đăng nhập tôi có thể quay trở lại callback_phase tôi (bạn sẽ hỏi làm thế nào bạn biết, vì vậy câu trả lời là tôi có đã thêm binding.pry vào phương thức callback_phase để kiểm tra luồng).

Nhưng sau khi thực hiện chiến lược Tôi nhận được lỗi sau

LỖI - omniauth: (my_app_strategy) Xác thực thất bại! invalid_credentials: OAuth2 :: Lỗi.

Sau khi gỡ lỗi thấy rằng tôi nhận được lỗi này cho cuộc gọi super (từ phương thức callback_phase).

Trước tiên tôi mặc dù có thể có một số vấn đề thông tin nhưng tôi có thể lấy access token sử dụng sau đây (được thực hiện trước khi super cuộc gọi)

@access_token = request_token.get_access_token(opts) 

Ngoài ra để biết thêm thông tin tôi nhận được lỗi cho build_access_token mà là phương pháp OAuth2

Bạn có thể tham khảo this liên kết để biết thêm (chỉ cần tìm kiếm trên build_access_token trên trang).

EDIT - 1

Sau khi gỡ lỗi phát hiện ra rằng nhận được vấn đề này từ request method. (Trong khi thực hiện yêu cầu faraday). Dưới đây là đoạn mã

response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req| 
    yield(req) if block_given? 
    end 

Đây là yêu cầu faraday tôi

#<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)>> 

Để đối phó Tôi nhận được thông báo lỗi sau đây

HTTP Status 400 - Thiếu thông tin người dùng OAuth.

Vì vậy, bất kỳ ai có thể giúp khắc phục vấn đề này?

Có cách nào khác để lưu trữ mã thông báo truy cập để tôi có thể sử dụng mã này cho mục đích giao tiếp hay không. Cảm ơn

+2

Bạn đã tiết lộ khóa người tiêu dùng và bí mật của người tiêu dùng tại đây. Tôi đã cố gắng chỉnh sửa chúng, tuy nhiên, nó sẽ cần được xác nhận bởi những người khác trước khi bản chỉnh sửa hiển thị trực tiếp. Vui lòng đảm bảo rằng các thông tin đăng nhập này đã bị hủy ngay lập tức và nhận thông tin đăng nhập mới mà bạn giữ bí mật. –

+0

@ScottS. Cảm ơn bạn đã trả lời, tôi sẽ chăm sóc nó. BTW đó là những con số ngẫu nhiên. –

+0

Có lý do nào khiến bạn không sử dụng https://github.com/intridea/omniauth-oauth2/blob/master/lib/omniauth/strategies/oauth2.rb để thiết lập oauth của mình không? –

Trả lời

2

Trước hết, tôi wan để làm rõ thế nào OAuth2 hoạt động:

OAuth2, giao thức nói:

  1. Bạn chuyển hướng người dùng đến dấu hiệu nhà cung cấp trong endpoint thêm một số thông số cần thiết (Ejm: PROVIDER/công khai/oauth? Redirect_uri = MYWEB/oauthDemo & response_type = mã & client_id = ABCDE). Đôi khi cũng có tham số phạm vi/quyền/tài nguyên cho biết mục đích của bạn là gì.

    -> Sau đó những dấu hiệu người dùng trong và được chuyển hướng đến MyWeb endpoint của bạn/công cộng/oauth với một mã

  2. Bây giờ bạn phải yêu cầu access token làm một POST để các thiết bị đầu cuối nhà cung cấp. Ví dụ:

    POST CUNG CẤP code = d5Q3HC7EGNH36SE3N & client_id = d4HQNPFIXFD255H & client_secret = 1a98b7cb92407cbd8961cd8db778de53 & redirect_uri = https://example.com/oauthDemo& grant_type = authorization_code

  3. Bây giờ bạn có access_token và bạn có thể sử dụng nó để thu thập thông tin hoặc giải mã nó bằng JWT.


Có rõ ràng này, và thấy rằng cuộc gọi của bạn dường như corect:

#<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)>> 

Như câu trả lời là "HTTP Status 400 - thông tin của người dùng OAuth Thiếu", tôi nghĩ có lẽ bạn:

a. Khách hàng của bạn không được định cấu hình tốt trên Nhà cung cấp. Thông thường bạn sử dụng để có một cấu hình cơ bản trên trang web của nhà cung cấp để có thể nhận ra bạn. Vì vậy, có lẽ không được cấu hình tốt.

b. Có một tham số tài nguyên/quyền/phạm vi bị thiếu hoặc sai cấu hình trên bước đầu tiên (trong chuyển hướng đến nhà cung cấp). Vì vậy, khi bạn yêu cầu mã thông báo có vấn đề.

+1

Đã thảo luận với nhóm nhà cung cấp, họ cho biết họ đang hỗ trợ 'OAuth1' không phải là' OAuth2' để thực hiện các thay đổi trong tệp chiến lược. Và nó hoạt động tìm thấy có thể lấy các chi tiết (access_token). Cảm ơn vi đa trả lơi. –

Các vấn đề liên quan