7
votes

Pourquoi je ne reçois pas de rafraîchi d'une demande Google Oauth?

Je tente d'intégrer Google Calendar dans ma demande et j'ai des problèmes avec l'autorisation de l'OAuth qui passait une rafraîchissante. Je reçois un accès accesstroken sans problème, mais la propriété Rafraîchissante est NULL. Voir la ligne marquée "Erreur ici:" Pour où je suis le problème

mon contrôleur ASP.NET MVC (nommé oauthcontroller code>) ressemble à ce qui suit: p>

    public ActionResult Index()
    {
        var client = CreateClient();
        client.RequestUserAuthorization(new[] { "https://www.googleapis.com/auth/calendar" }, new Uri("http://localhost/FL.Evaluation.Web/OAuth/CallBack"));

        return View();
    }

    public ActionResult CallBack()
    {

        if (string.IsNullOrEmpty(Request.QueryString["code"])) return null;

        var client = CreateClient();

        // Now getting a 400 Bad Request here
        var state = client.ProcessUserAuthorization();

        // ERROR HERE:  The RefreshToken is NULL
        HttpContext.Session["REFRESH_TOKEN"] = Convert.ToBase64String(Encoding.Unicode.GetBytes(state.RefreshToken));

        return JavaScript("Completed!");
    }

    private static WebServerClient CreateClient()
    {
        return
            new WebServerClient(
                new AuthorizationServerDescription()
                    {
                        TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
                        AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"),
                        ProtocolVersion = ProtocolVersion.V20
                    }
                , _GoogleClientId, _GoogleSecret);
    }


2 commentaires

J'ai glacé mon code vers le bas et je reçois maintenant une erreur de 400 mauvaises requéres lorsque vous essayez d'interroger Google.


J'ai résolu mon problème en codant à la main le HTTPequest à Google. Je vais assainir et poster le code comme une réponse


3 Réponses :


9
votes

Réglage googleAuthentiserver.description Pour avoir une autorisation de terminaison URI qui inclut ? Access_type = hors ligne dans la chaîne de requête.


1 commentaires

Merci pour cet indice très utile autorizationnerverdescription decserver = googleeauthenticasever.description; descserver.authorizePoint = nouveau Uri (descserver.authorizePoint.tostring () + "Access_type = Offline"); l'a utilisé comme ça et a travaillé pour moi



12
votes

Après des heures de fidélisation avec DotNetOpenauth et Google APIS publié pour .net, je n'ai nulle part rapide. J'ai décidé de contourner les bibliothèques et allé directement au API de repos Google avec HTTPRequest et httpresponse objets. Mon code désinfecté pour mon contrôleur MVC suit:

    private static string _GoogleClientId = "CLIENT_ID";
    private static string _GoogleSecret = "SECRET";
    private static string _ReturnUrl = "http://localhost/OAuth/CallBack";

    public ActionResult Index()
    {
        return Redirect(GenerateGoogleOAuthUrl());
    }

    private string GenerateGoogleOAuthUrl()
    {

        //NOTE: Key piece here, from Andrew's reply -> access_type=offline forces a refresh token to be issued
        string Url = "https://accounts.google.com/o/oauth2/auth?scope={0}&redirect_uri={1}&response_type={2}&client_id={3}&state={4}&access_type=offline&approval_prompt=force";
        string scope = UrlEncodeForGoogle("https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.readonly").Replace("%20", "+");
        string redirect_uri_encode = UrlEncodeForGoogle(_ReturnUrl);
        string response_type = "code";
        string state = "";

        return string.Format(Url, scope, redirect_uri_encode, response_type, _GoogleClientId, state);

    }

    private static string UrlEncodeForGoogle(string url)
    {
        string UnReservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
        var result = new StringBuilder();

        foreach (char symbol in url)
        {
            if (UnReservedChars.IndexOf(symbol) != -1)
            {
                result.Append(symbol);
            }
            else
            {
                result.Append('%' + String.Format("{0:X2}", (int)symbol));
            }
        }

        return result.ToString();
    }

    class GoogleTokenData
    {
        public string Access_Token { get; set; }
        public string Refresh_Token { get; set; }
        public string Expires_In { get; set; }
        public string Token_Type { get; set; }
    }

    public ActionResult CallBack(string code, bool? remove)
    {

        if (remove.HasValue && remove.Value)
        {
            Session["GoogleAPIToken"] = null;
            return HttpNotFound();
        }

        if (string.IsNullOrEmpty(code)) return Content("Missing code");

        string Url = "https://accounts.google.com/o/oauth2/token";
        string grant_type = "authorization_code";
        string redirect_uri_encode = UrlEncodeForGoogle(_ReturnUrl);
        string data = "code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type={4}";

        HttpWebRequest request = HttpWebRequest.Create(Url) as HttpWebRequest;
        string result = null;
        request.Method = "POST";
        request.KeepAlive = true;
        request.ContentType = "application/x-www-form-urlencoded";
        string param = string.Format(data, code, _GoogleClientId, _GoogleSecret, redirect_uri_encode, grant_type);
        var bs = Encoding.UTF8.GetBytes(param);
        using (Stream reqStream = request.GetRequestStream())
        {
            reqStream.Write(bs, 0, bs.Length);
        }

        using (WebResponse response = request.GetResponse())
        {
            var sr = new StreamReader(response.GetResponseStream());
            result = sr.ReadToEnd();
            sr.Close();
        }

        var jsonSerializer = new JavaScriptSerializer();
        var tokenData = jsonSerializer.Deserialize<GoogleTokenData>(result);
        Session["GoogleAPIToken"] = tokenData.Access_Token;

        return JavaScript("Refresh Token: " + tokenData.Refresh_Token);

    }


0 commentaires

0
votes

ajoutez simplement

AccessType = "offline",


0 commentaires