2017-12-06 3 views
0

Ich implementiere Google-Anmeldung im Back-End gemäß this tutorial.Autorisierungscodeaustausch funktioniert nicht mit Google OAuth2

Ich habe einen JS-Client:

<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script> 

function start() { 
    gapi.load('auth2', function() { 
     auth2 = gapi.auth2.init({ 
      client_id: 'MY_CLIENT_ID', 
      scope: 'profile email https://www.googleapis.com/auth/plus.me', 
     }); 
    }); 
} 

<button id="signinButton">Login Google</button> 
<script> 
    $('#signinButton').click(function() { 
     auth2.grantOfflineAccess().then(signInCallback); 
    }); 
</script> 

Und ich in signInCallback Funktion bin das Senden authResult['code'] an den Server.

Auf dem Server muss ich id_token und access_token von serverAuthCode generieren. Mein Backend ist in ASP.NET CORE geschrieben.

Das Tutorial enthält Backend-Implementierungsbeispiele für Java und Python. Auf dem Server mache ich folgendes:

var data = new FormUrlEncodedContent(new[] 
{ 
    new KeyValuePair<string, string>("code", serverAuthCode), 
    new KeyValuePair<string, string>("client_id", "MY_CLIENT_ID"), 
    new KeyValuePair<string, string>("client_secret", "MY_CLIENT_SECRET"), 
    new KeyValuePair<string, string>("grant_type", "authorization_code"), 
    new KeyValuePair<string, string>("redirect_uri", "MY_REDIRECT_URI_DEFINED_IN_GOOGLE_CONSOLE") 
}); 
var tokenResponse = await _httpClient.PostAsync("https://www.googleapis.com/oauth2/v4/token", data); 

Und ich bin immer bekommen schlechte Anfrage mit einer der Fehler (zufällig):

  • redirect_uri_mismatch

  • invalid_grant

Mache ich etwas falsch mit der Anfrage?

+0

Sind Sie auf den gleichen URL umleiten? Siehe [redirect_uri] (https://developers.google.com/identity/sign-in/web/reference) unter "gapi.auth2.ClientConfig" – john

+0

Ich kann nicht sagen, dass ich viel über diesen Bereich weiß, aber vielleicht möchten Sie Sehen Sie sich den Code in https://github.com/google/google-api-dotnet-client/tree/master/Src/Support/Google.Apis.Auth.Mvc/OAuth2/Mvc an - das ist nicht für ASP.NET Core, sollte aber zeigen, was Sie tun müssen. –

Antwort

0

Ihr Code sieht genau wie die Methode aus, die ich erfolgreich mit einem anderen OAuth2 /OIDC-Anbieter verwendet. Die einzige Ausnahme ist ein Accept Header, also können Sie dies zu Ihrem Code hinzufügen (nicht sicher, ob es Ihr zufälliges Verhalten beheben wird, aber es könnte einen Versuch wert sein).

_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

Der Vollständigkeit halber ist dies die Methode, die ich bin mit:

public async Task<TokenResponse> ExchangeCodeForTokens(Uri tokenEndpoint, string code, Uri redirectUri, string clientId, string clientSecret) 
{ 
    var content = new FormUrlEncodedContent(new Dictionary<string, string> 
    { 
     {"grant_type", "authorization_code"}, 
     {"code", code}, 
     {"redirect_uri", redirectUri.ToString()}, 
     {"client_id", clientId}, 
     {"client_secret", clientSecret} 
    }); 

    using (var client = _httpClientFactory()) 
    { 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     var response = await client.PostAsync(tokenEndpoint, content); 
     var responseContent = await response.Content.ReadAsStringAsync(); 

     if (!response.IsSuccessStatusCode) 
      throw new OpenIdConnectException($"Request to token endpoint {tokenEndpoint} not successful: {responseContent}"); 

     var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(responseContent); 
     if (tokenResponse == null) 
      throw new OpenIdConnectException($"Request to token endpoint {tokenEndpoint} did not return a valid response: {responseContent}"); 

     return tokenResponse; 
    } 
} 

Wo TokenResponse ist:

public class TokenResponse 
{ 
    [JsonProperty("access_token")] 
    public string AccessToken { get; set; } 

    [JsonProperty("expires_in")] 
    public int ExpiresInSeconds { get; set; } 

    [JsonProperty("refresh_token")] 
    public string RefreshToken { get; set; } 

    [JsonProperty("id_token")] 
    public string IdToken { get; set; } 

    [JsonProperty("token_type")] 
    public string TokenType { get; set; } 

    [JsonIgnore] 
    public TimeSpan ExpiresIn => TimeSpan.FromSeconds(ExpiresInSeconds); 
} 
Verwandte Themen