2017-03-31 26 views
0

當我試圖接收訪問令牌時應該將其包含在來自外部Api的JSON響應中,我遇到了rails和法拉第的問題。JSON請求問題 - rails /法拉第

我想要做的是基於外部API的用戶認證。 我假設用戶已經有有效的憑據(在這種情況下,電子郵件作爲用戶名和密碼)。

現在,當他連接到我的Api,我發送JSON請求到外部Api以驗證此用戶是否有效並等待訪問令牌。

一旦訪問令牌是在響應中發送,用戶身份驗證是成功的,我有機會到其他端點

這是我的控制器

module Api 
    class AuthenticationController < ApplicationController 
    def create 
     client = XXX::AuthClient.new 

     response = client.authenticate(
     email: params[:email], 
     password: params[:password] 
    ) 

     api_client = XXX::Client.new(response[:access_token]) 

     if response[:access_token] 
     api_user = api_client.get_user() 

     if api_user["id"] 
      db_user = User.create(xxx_id: api_user["id"], xxx_access_token: response[:access_token]) 
     end 
     end 

     render json: { access_token: db_user.access_token } 
    end 
    end 
end 

這是我AuthClient服務

class AuthClient 
    def initialize 
     @http_client = Faraday.new('https://auth.xxx.com/') 
    end 

    def authenticate(email:, password:) 
     headers = { 
     'Content-Type': 'application/json' 
     }.to_json 

     body = { 
     grant_type: "password", 
     username: email, 
     password: password, 
     client_id: "particularclientid", 
     client_secret: "particularclientsecret" 
     }.to_json 

     api_response = http_client.post("/oauth2/token", body) 
     response = JSON.parse(api_response.body) 

     if response["access_token"] 
     { access_token: access_token } 
     else 
     { error: "autentication error" } 
     end 

    end 

    private 

    attr_reader :http_client 
    end 
end 

我所知道的是,以下格式的捲曲是正確的,我可以看到用戶的訪問令牌,刷新令牌等。

curl -X POST -H "Content-Type: application/json" -d '{ 
"grant_type": "password", 
"username": "[email protected]", 
"password": "examplepassword", 
"client_id": "particularclientid", 
"client_secret": "particularclientsecret" 
}' "https://auth.xxx.com/oauth2/token" 

但是當我跑我的捲曲

curl -X POST -d '[email protected]&password=examplepassword' "http://localhost:3000/api/auth" 

我看到,我的要求是不正確的。但我不知道問題在哪裏,因爲標題和正文被格式化爲JSON(我已輸入puts headers,puts bodyputs response來驗證)。

Started POST "/api/auth" for 127.0.0.1 at 2017-03-31 16:42:26 +0200 
Processing by Api::AuthenticationController#create as */* 
    Parameters: {"email"=>"test [email protected]", "password"=>"[FILTERED]"} 
{"Content-Type":"application/json"} 
{"grant_type":"password","username":"test [email protected]","password":"examplepassword","client_id":"particularclientid","client_secret":"particularclientsecret"} 
{"error"=>"invalid_request", "error_description"=>"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."} 
Completed 500 Internal Server Error in 610ms (ActiveRecord: 0.0ms) 


NoMethodError (undefined method `access_token' for nil:NilClass): 

app/controllers/api/authentication_controller.rb:21:in `create' 

是我的要求不正確或問題的其他地方存在? 我沒有經驗的開發人員。只是試圖學習足夠的初級RoR。我試圖找到堆棧和不同網站上的解決方案,但我被困住了。即使法拉第文檔也沒有多大幫助

回答

0

好的。 我剛剛發現一個問題,當我開始閱讀我的文章了。

我的控制器無法識別用戶名字段中的加號,並且它被替換爲空格。 在我捲曲我送curl -X POST -d '[email protected]&... 而在控制器我看到"username":"test [email protected]"

但這並沒有解決我的問題。

0

當URI被轉義時,+被用作空白的替換。因此,當您的控制器不轉義URI時,+會變回空格。如果您想發送空間,請改用%2B

對於您的第一個問題,錯誤消息指示當您嘗試執行db_user.access_token時,db_user爲零。因此,要麼response[:access_token]爲零,api_user["id"]爲零,或者User.create失敗。

您需要進行一些調試以找出問題所在。

+0

'我,[2017-04-01T00:50:34.680829#23770]信息 - :post https:// auth.xxx.com/oauth2/token' 'D,[2017-04-01T00:50 :請求:User-Agent:「Faraday v0.11.0」' 'D,[2017-04-01T00:50:34.681299#23770] DEBUG - request:{「grant_type」:「password 「,」username「:」test [email protected]「,」password「:」examplepassword「,」client_id「:」particularclientid「,」client_secret「:」particularclientsecret「} – Hubert

+0

嗯,它看起來像我的標題不甚至發送給客戶。 – Hubert

0

我已經調試我的控制器和我看到,當我在控制檯

response = client.authenticate(
    email: params[:email], 
    password: params[:password] 
) 

puts response 

打印響應我收到{:error=>"autentication error"}。 那麼就意味着我收到一個錯誤,而不是訪問令牌,當我把我的請求,客戶端的API

if response["access_token"] 
    { access_token: access_token } 
else 
    { error: "autentication error" } 
end 

因此,這可能是錯誤的在這種情況下,唯一的事情是我的請求,這是格式不正確(應爲JSON )或者在標題或正文中缺少某些內容。

def authenticate(email:, password:) 
    headers = { 
    'Content-Type': 'application/json' 
    }.to_json 

    body = { 
    grant_type: GRANT_TYPE, 
    username: email, 
    password: password, 
    client_id: CLIENT_ID, 
    client_secret: CLIENT_SECRET 
    }.to_json 

    api_response = http_client.post("/oauth2/token", body) 
    response = JSON.parse(api_response.body) 

是否可以通過某種方式驗證此處發送的內容? api_response = http_client.post("/oauth2/token", body)我已經嘗試在該代碼下面插入提示,並且在控制檯中看不到任何內容。

+0

請注意,所有正文值都是正確的,所以授予類型,用戶名,密碼,客戶端ID和客戶端密碼都可以。是否有可能我的標題或正文不是以JSON格式發送的?或者,即我的標題未被髮送,因此我的請求每次都會失敗。 – Hubert