2017-03-31 3 views
0

Ich habe ein Problem mit Schienen und Faraday, wenn ich versuche, Zugangstoken zu erhalten, die in einer JSON-Antwort von der externen API enthalten sein sollten.Problem mit JSON-Anfrage - Schienen/Faraday

Was ich tun möchte, ist Benutzerauthentifizierung basierend auf externen API. Ich gehe davon aus, dass der Benutzer bereits gültige Zugangsdaten hat (in diesem Fall E-Mail als Benutzername und Passwort).

Jetzt, wenn er eine Verbindung zu meinem Api herstellt, sende ich eine JSON-Anfrage an den externen Api, um zu überprüfen, ob dieser Benutzer gültig ist und auf Zugriffstoken warte.

Sobald die Zugriffstoken in einer Antwort gesendet wird, ist die Benutzerauthentifizierung erfolgreich und ich habe Zugang zu den anderen Endpunkten

Dies ist mein Controller

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 

Und das ist mein AuthClient Service

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 

Was ich weiß, ist, dass Curl im folgenden Format korrekt ist und ich kann User Access Token, Refresh Token usw.

012 sehen
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" 

Aber wenn ich betreibe meine curl

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

ich sehe, dass meine Anfrage nicht korrekt ist. Aber ich habe keine Ahnung, wo das Problem ist, weil Header und Körper zu JSON formatiert sind (Ich habe puts headers, puts body und puts response eingegeben, um das zu überprüfen).

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' 

Ist meine Anfrage nicht korrekt oder das Problem woanders existiert? Ich bin kein erfahrener Entwickler. Nur versuchen, genug zu lernen, um als Junior RoR zu beginnen. Ich habe versucht, eine Lösung auf Stapel und auf verschiedenen Seiten zu finden, aber ich bin steckengeblieben. Sogar Faraday-Dokumente hilft mir nicht viel

Antwort

0

Ok. Ich habe gerade ein weiteres Problem gefunden, als ich angefangen habe, meinen Beitrag wieder zu lesen.

Mein Controller erkennt kein Pluszeichen im Feld Benutzername und es wird durch Leerzeichen ersetzt. In meinem curl sende ich curl -X POST -d '[email protected]&... Und Controller Ich sehe "username":"test [email protected]"

Aber das ist mein Problem nicht behebt.

0

Wenn URIs maskiert werden, wird + als Ersatz für Leerzeichen verwendet. Wenn Ihr Controller den URI entkoppelt, wird die + in ein Leerzeichen zurückgesetzt. Wenn Sie ein Leerzeichen senden möchten, verwenden Sie stattdessen %2B.

Für Ihr erstes Problem zeigt die Fehlermeldung an, dass db_user Null ist, wenn Sie versuchen, db_user.access_token zu tun. Also, entweder response[:access_token] ist Null, api_user["id"] ist Null, oder User.create gescheitert.

Sie müssen ein Debugging durchführen, um herauszufinden, wo Ihr Problem liegt.

+0

'I, [2017-04-01T00: 50: 34.680829 # 23770] INFO -: Beitrag https: // auth.xxx.com/oauth2/token' ' D, [2017-04-01T00: 50 : 34.681004 # 23770] DEBUG - Anfrage: User-Agent: "Faraday v0.11.0" ' ' D, [2017-04-01T00: 50: 34.681299 # 23770] DEBUG - Anfrage: {"grant_type": "password "," Benutzername ":" test [email protected] "," password ":" Beispielpasswort "," client_id ":" particlicclientid "," client_secret ":" specialclientsecret "}' – Hubert

+0

Hmmm, es sieht so aus, als ob mein Header nicht gerade ist an den Kunden gesendet. – Hubert

0

Ich habe meinen Controller debuggt, und ich sehe, dass, wenn ich Antwort in meiner Konsole

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

puts response 

I {:error=>"autentication error"} erhalten drucken. dann bedeutet es, ich einen Fehler anstelle von Zugriffstoken empfangen, wenn ich Api meine Anfrage an den Kunden schicken

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

Also das einzige, was in diesem Fall falsch sein kann, ist mein Wunsch, die nicht richtig formatiert ist (sollte JSON sein) oder es fehlt etwas in Header oder Body.

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) 

Ist es irgendwie möglich zu überprüfen, was hier gesendet wird? api_response = http_client.post("/oauth2/token", body) Ich habe schon versucht, Puts unterhalb dieses Codes einzufügen und ich sehe nichts in der Konsole.

+0

Beachten Sie, dass alle Körperwerte korrekt sind, damit Grant-Typ, Benutzername, Kennwort, Client-ID und Client-Geheimnis in Ordnung sind. Ist es möglich, dass mein Header oder Body nicht im JSON-Format gesendet wird? Oder d. H. Mein Header wird nicht gesendet, so dass meine Anfrage jedes Mal fehlschlägt. – Hubert