Yahoo OAuth 2.0 invalid_grant при выдаче токена доступа

Я попытался внедрить Yahoo OAuth 2.0 со следующим руководством: https://developer.yahoo.com/oauth2/guide/ Мне удалось авторизоваться, и я получил код авторизации, но на шаге 4 у меня ничего не вышло. Когда мой код пытается обменять код авторизации на токен доступа с помощью /get_token, возникает ошибка 401 Unauthorized Error. { "ошибка": "invalid_grant"}

Согласно https://developer.yahoo.com/oauth2/guide/errors/index.html invalid_grant означает, что был предоставлен недопустимый токен или токен с истекшим сроком действия. Я немного смущен, почему выбрасывается 401.

Кто-нибудь сталкивался с подобной проблемой?

public class YahooOAuthClient : OAuth2Client
{
    private const string AuthorizeUrl = "https://api.login.yahoo.com/oauth2/request_auth";
    private const string TokenEndpoint = "https://api.login.yahoo.com/oauth2/get_token";

    private readonly string clientId;
    private readonly string clientSecret;

    public YahooOAuthClient(string clientId, string clientSecret)
        : base("Yahoo")
    {
        this.clientId = clientId;
        this.clientSecret = clientSecret;
    }

    protected override Uri GetServiceLoginUrl(Uri returnUrl)
    {
        var uriBuilder = new UriBuilder(AuthorizeUrl);
        uriBuilder.AppendQueryArgument("client_id", this.clientId);
        uriBuilder.AppendQueryArgument("redirect_uri", returnUrl.ToString());
        uriBuilder.AppendQueryArgument("response_type", "code");
        uriBuilder.AppendQueryArgument("language", "en-us");

        return uriBuilder.Uri;
    }

    protected override IDictionary<string, string> GetUserData(string accessToken)
    {
        return new Dictionary<string, string>
        {
            {"id", accessToken}
        };
    }

    protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
    {
        var postData = HttpUtility.ParseQueryString(string.Empty);
        postData.Add(new NameValueCollection
            {
                { "grant_type", "authorization_code" },
                { "code", authorizationCode },
                { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) },
            });

        var webRequest = (HttpWebRequest)WebRequest.Create(TokenEndpoint);

        webRequest.Method = "POST";
        webRequest.ContentType = "application/x-www-form-urlencoded";
        String encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(clientId + ":" + clientSecret));
        webRequest.Headers.Add("Authorization", "Basic " + encoded);

        using (var s = webRequest.GetRequestStream())
        using (var sw = new StreamWriter(s))
            sw.Write(postData.ToString());

        using (var webResponse = webRequest.GetResponse())
        {
            var responseStream = webResponse.GetResponseStream();
            if (responseStream == null)
                return null;

            using (var reader = new StreamReader(responseStream))
            {
                var response = reader.ReadToEnd();
                var json = JObject.Parse(response);
                var accessToken = json.Value<string>("access_token");
                return accessToken;
            }
        }
    }
}

person Zbigniew Winiarski    schedule 26.03.2015    source источник
comment
ОП, решил? Я столкнулся с той же проблемой. Если это так и вы помните это, пожалуйста, напишите ответ, это может очень помочь.   -  person MasterMastic    schedule 16.06.2016


Ответы (1)


Этот ответ может быть поздним, но я столкнулся с той же проблемой, что и вы, хотя я реализовал PHP. Я понял, что это моя ошибка:

Изначально мой return_url имеет вид

http://example.com/oauth_handle?route=something/path/like&param1=value&param2=value

Я внедрял oauth для facebook, twitter(blah), google linkedin и yahoo. Google oauth API не понравился route=something/path/like, поэтому я закодировал его в URL-адресе

http://example.com/oauth_handle?route=something%2Fpath%2Flike&param1=value&param2=value

Итак, это return_uri, который был отправлен в конечную точку /request_auth как есть.

Затем для /get_token параметр return_uri снова был закодирован в URL-адресе, что означает, что теперь я выполнял двойное кодирование URL-адреса для части route=something/path/like, что делает return_uri разными в двух запросах.

Исправление этого, выполнив url_encode только один раз, решает мою проблему. Надеюсь это поможет!

person Cyril Tata    schedule 11.04.2015