Etsy oauth аутентификация C# RestSharp

Я пытаюсь сделать образец Авторизованного запроса (или что-нибудь с API Etsy, который требует аутентификации), приведенный в их документации. Я получаю ответ "oauth_problem=token_rejected".

Я использовал этот SO-ответ вместе с базой OAuth, с benSharper связывался benSharper.

Я смотрел на это и это, и другие. Один из них использовал https://sandbox.https://openapi.etsy.com/v2 и когда я попробовал это, исключение было "Основное соединение было закрыто: не удалось установить доверительные отношения для безопасного канала SSL/TLS". Я развернул на своем сервере (который является https) и все тот же ответ.

Просто не могу заставить его работать. Что мне не хватает?

Вот мой код:

public class AuthorizedRequestHelper
    {
        string baseUrl = "https://openapi.etsy.com/v2";
        string relativePath = "/oauth/scopes";
        string oauth_consumer_key = "xxx";
        string consumerSecret = "xxx";
        string oauth_token = "xxx";
        string oauth_token_secret = "xxx";

        public void test()
        {
            var restClient = new RestClient(baseUrl);
            OAuthBase oAuth = new OAuthBase();

            string nonce = oAuth.GenerateNonce();
            string timeStamp = oAuth.GenerateTimeStamp();
            string normalizedUrl;
            string normalizedRequestParameters;

            string sig = oAuth.GenerateSignature(new Uri(baseUrl + relativePath), oauth_consumer_key, consumerSecret, oauth_token, oauth_token_secret, "GET", timeStamp, nonce, out normalizedUrl, out normalizedRequestParameters);


            var request = new RestRequest(relativePath);
            request.Resource = string.Format(relativePath);
            request.Method = Method.GET;

            request.AddParameter("oauth_consumer_key", oauth_consumer_key);
            request.AddParameter("oauth_token", oauth_token);
            request.AddParameter("oauth_nonce", nonce);
            request.AddParameter("oauth_timestamp", timeStamp);
            request.AddParameter("oauth_signature_method", "HMAC-SHA1");
            request.AddParameter("oauth_version", "1.0");
            request.AddParameter("oauth_signature", sig);

            IRestResponse irestResponse = restClient.Execute(request);
            var content = irestResponse.Content;
            // content = oauth_problem=token_rejected
        }
    }  

Любая помощь будет принята с благодарностью.

1 ответ

Решение

Разобрался, чего мне не хватало. Мне не хватало получения токенов, которые являются постоянными токенами, необходимыми для доступа к защищенным ресурсам.

У меня были проблемы с тем, чтобы обернуться вокруг реализации OAuth, RestSharp и Etsy одновременно. Не нужен OAuthBase, об этом позаботится RestSharp.

Обратите внимание, что appKey а также sharedSecret становиться consumerKey а также consumerSecret при совершении вызовов OAuth с помощью RestSharp.

Вот рабочий код:

    /// <summary>
    /// RestSharp documentation: https://github.com/restsharp/RestSharp/wiki
    /// </summary>
    public class Etsy_portal
    {
        Uri BASE_URL = new Uri("https://openapi.etsy.com/v2/");

        string appKey;
        string sharedSecret;
        RestClient restClient;

        private string[] _permissions_array;
        public string Permissions
        {
            get { return string.Join(" ", _permissions_array); }
        }

        public Etsy_portal(string appKey_, string sharedSecret_)
        {
            appKey = appKey_;
            sharedSecret = sharedSecret_;

            restClient = new RestClient(BASE_URL);

            //todo move permissions to Web.config
            _permissions_array = new string[] { "listings_r", "listings_w", "listings_d", "shops_rw" };
        }

        public string GetConfirmUrl(out string oauth_token, out string oauth_token_secret, string callbackUrl_ = null)
        {
            restClient.Authenticator = OAuth1Authenticator.ForRequestToken(appKey, sharedSecret, callbackUrl_ ?? "oob");

            RestRequest restRequest = new RestRequest("oauth/request_token", Method.POST);

            restRequest.AddParameter("scope", Permissions);

            IRestResponse response = restClient.Execute(restRequest);

            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                oauth_token = null;
                oauth_token_secret = null;
                return null;
            }

            NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(response.Content);

            oauth_token = queryString["oauth_token"];
            oauth_token_secret = queryString["oauth_token_secret"];

            return queryString["login_url"];
        }

        public void ObtainTokenCredentials(string oauth_token_temp_, string oauth_token_secret_temp_, string oauth_verifier_, out string permanent_oauth_token_, out string permanent_oauth_token_secret_)
        {
            //consumerKey is the appKey you got when you registered your app, same for sharedSecret
            restClient.Authenticator = OAuth1Authenticator.ForAccessToken(appKey, sharedSecret, oauth_token_temp_, oauth_token_secret_temp_, oauth_verifier_);

            RestRequest restRequest = new RestRequest("oauth/access_token", Method.GET);
            IRestResponse irestResponse = restClient.Execute(restRequest);

            NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(irestResponse.Content);

            permanent_oauth_token_ = queryString["oauth_token"];
            permanent_oauth_token_secret_ = queryString["oauth_token_secret"];
        }

        public string GetScopes(string accessToken_, string accessTokenSecret_)
        {
            restClient.Authenticator = OAuth1Authenticator.ForProtectedResource(appKey, sharedSecret, accessToken_, accessTokenSecret_);

            RestRequest restRequest = new RestRequest("oauth/scopes", Method.GET);

            IRestResponse irestResponse = restClient.Execute(restRequest);

            return irestResponse.Content;
        }
    }

Псевдокод (с обратным вызовом):

  1. Построить Etsy_portal объект
  2. Вызов GetConfirmUrl, предоставьте URL обратного вызова. Обратный вызов будет иметь два параметра запроса oauth_token а также oauth_verifier, Вот пример подписи функции обратного вызова:

    [HttpGet] public ActionResult EtsyCallback (строка oauth_token, строка oauth_verifier)

  3. Сохраните возвращенный токен и секрет в структуре карты для последующего поиска.

  4. Посетите ссылку для подтверждения, возвращенную после звонка GetConfirmUrl,
  5. В функции обратного вызова используйте предоставленный токен (первый аргумент в приведенном выше примере), чтобы найти секрет, сохраненный на шаге 3.
  6. Используя верификатор (второй аргумент функции обратного вызова в приведенном выше примере), токен и секрет, вызов ObtainTokenCredentials получить постоянный токен и секрет.
  7. Сохраните постоянный токен и секрет, вы можете отказаться от верификатора, временного токена и временного секрета, полученных на шагах 1-4.
Другие вопросы по тегам