• 0
Sign in to follow this  
AGL

Erro na Autorização com C#

Question

Olá, estou utilizando os exemplos do endereço https://github.com/mercadolibre/net-sdk porem estou tendo erro (veja imagem em anexo) na autenticação abaixo:

  static void Main()
        {
            Meli m = new Meli(clientId, "clientSecret"); //coloquei clientId e clientSecret para omitir os códigos, mas, na minha aplicação eles foram incluídos.
            string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://www.google.com");
            m.Authorize("", "https://www.google.com");
        }

erro_mlN7DCYHPXZ5.png

Estou lendo principalmente essa parte https://developers.mercadolibre.com/pt_br/server-side mas ainda não consegui entender como fazer para aparecer a autenticação, ou seja aparecer a tela onde o usuário informa o e-mail e senha do ML para autorizar minha aplicação.

Se informo a URL https://auth.mercadolivre.com.br/authorization?response_type=code&client_id=34029XXXXXXX8860 (substitui parte do código por X) direto no navegador ele mostra a tela do ML para o usuário efetuar a permissão. Mas, não sei como isso isso e pegar o retorno via código C#.

O problema pelo que vejo esta nessa linha m.Authorize("", "https://www.google.com"); (coloquei o endereço do Google mas utilizo outro endereço ja cadastrado no gerenciador de aplicação do ML) que chama a função abaixo:

public void Authorize (string code, string redirectUri)
        {
            var request = new RestRequest ("/oauth/token?grant_type=authorization_code&client_id={client_id}&client_secret={client_secret}&code={code}&redirect_uri={redirect_uri}", Method.POST);

            request.AddParameter ("client_id", this.ClientId, ParameterType.UrlSegment);
            request.AddParameter ("client_secret", this.ClientSecret, ParameterType.UrlSegment);
            request.AddParameter ("code", code, ParameterType.UrlSegment);
            request.AddParameter ("redirect_uri", redirectUri, ParameterType.UrlSegment);

            request.AddHeader ("Accept", "application/json");

            var response = ExecuteRequest (request);

            if (response.StatusCode.Equals (HttpStatusCode.OK)) {
                var token = JsonConvert.DeserializeAnonymousType (response.Content, new {refresh_token="", access_token = "", expires_in = 0,
                user_id = "", scope = "", token_type = ""});
                this.AccessToken = token.access_token;
                this.RefreshToken = token.refresh_token;
                this.ExperiIn = Convert.ToInt64(token.expires_in);
                this.Scope = token.scope;
                this.UserId = token.user_id;
                this.TokenType = token.token_type;
            } else {
                throw new AuthorizationException ();
            }
        }
 

Edited by AGL

Share this post


Link to post
Share on other sites

14 answers to this question

Recommended Posts

  • 1
2 hours ago, AGL said:

Nathalie, mas como? Para mim não retorna nada. O que to fazendo de errado?

 

erro_ml.png

Tente substituir a linha

request.AddParameter("undefined", "client_id=<CLIENTID>&client_secret=<SECRET>&grant_type=client_credentials", ParameterType.RequestBody);

pelas linhas

request.AddParameter("client_id", <CLIENTID>);
request.AddParameter("client_secret", <SECRET>);
request.AddParameter("grant_type", "client_credentials");

 

Retorna um Json, lá tem o Access Token. Não precisa fazer autenticação via browser

Share this post


Link to post
Share on other sites
  • 0

Correto, estou utilizando outro endereço, que possui certificado HTTPS e esta configurada (informada) no gerenciador de aplicativos do Mercado Livre.

Quando executo o código abaixo esta dando esse erro da imagem anexa:

static void Main()
        {
            Meli m = new Meli(clientId, "clientSecret"); //coloquei clientId e clientSecret para omitir os códigos, mas, na minha aplicação eles foram incluídos.
            string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://www.google.com");
            m.Authorize("", "https://www.google.com");
        }

erro_ml.png

Edited by AGL

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, AGL said:

Correto, estou utilizando outro endereço, que possui certificado HTTPS e esta configurada (informada) no gerenciador de aplicativos do Mercado Livre.

Quando executo o código abaixo esta dando esse erro da imagem anexa:

static void Main()
        {
            Meli m = new Meli(clientId, "clientSecret"); //coloquei clientId e clientSecret para omitir os códigos, mas, na minha aplicação eles foram incluídos.
            string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://www.google.com");
            m.Authorize("", "https://www.google.com");
        }

erro_ml.png

Você precisa entender o fluxo de autorização e depurar melhor sua aplicação para localizar o problema e verificar se é um problema de configuração ou outro problema.

O login e a autorização quem controla é o ML.

Se o usuário já estiver logado não vai pedir para logar de novo. Para saber se já está logado, acesse a página da sua conta no ML e veja se pede login ou não. Se não pede e você quer partir daí, faça logoff no ML e depois tente acessar pela sua aplicação para ver se pede o login.

Se o usuário já tiver feito a autorização também não vai pedir para autorizar de novo. Verifique na tela de autorizações se consta a sua aplicação.

No fluxo, após login e autorização, você recebe um code e vai trocar ele pelo token. No seu erro, note que não tem o code e tanto o erro quanto a mensagem exibida são por causa disso. Note na mensagem onde informa: Empty parameter code

A questão é: porque você não tem o code? Não tem porque tá fazendo o fluxo errado. Você não deve chamar o Authorize no início. Você recupera a redirectUrl e deve redirecionar seu usuário para ela. Aí o ML controla o fluxo de login e autorização e ao final vai encaminhar seu usuário para sua URL configurada passando o code. Na sua URL configurada você faz o tratamento para recuperar o code e aí sim chamar o Authorize passando este code para continuar seu fluxo e trocar o code pelo token.

Se não confirmar que já recebeu o code não adianta tentar fazer o próximo passo que é trocar o code pelo token, que é o que seu código está tentando fazer.

Edited by Diogenes Lima

Share this post


Link to post
Share on other sites
  • 0

A minha conta de cliente (vendedor no ML) que estou utilizando para teste não esta logada.

Veja o codigo de chamada:

static void Main()
        {
            Meli m = new Meli(clientId, "clientSecret"); //coloquei clientId e clientSecret para omitir os códigos, mas, na minha aplicação eles foram incluídos.
            string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://www.google.com");

pelo que reparei, o problema esta entre essas duas linhas (acima e abaixo), o que falta é o código que pega o retorno da autorização do usuario no ML e retorne aquele codigo TG-5bXXXe2ee4b0b1178dfefe31-XXXXXXXXX como pego este codigo e coloco no m.Authorize("TG-5bXXXe2ee4b0b1178dfefe31-XXXXXXXXX ", "https://www.google.com");


            m.Authorize("", "https://www.google.com");
        }

E abaixo o MELI.CS o que estou fazendo de errado?

using System;
using System.Web;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Specialized;
using RestSharp;
using System.Collections.Generic;

namespace MercadoLibre.SDK
{
    public class Meli
    {

        private RestClient client = new RestClient (ApiUrl);
        static private string apiUrl = "https://api.mercadolibre.com";
        static private string sdkVersion = "MELI-NET-SDK-1.0.2";
        static public string ApiUrl {
            get {
                return apiUrl;
            }
            set {
                apiUrl = value;
            }
        }

        public static class AuthUrls
        {
            public static string MLA { get { return "https://auth.mercadolibre.com.ar"; } } //Argentina
            public static string MLB { get { return "https://auth.mercadolivre.com.br"; } } // Brasil
            public static string MCO { get { return "https://auth.mercadolibre.com.co"; } } // Colombia
            public static string MCR { get { return "https://auth.mercadolibre.com.cr"; } } // Costa Rica
            public static string MEC { get { return "https://auth.mercadolibre.com.ec"; } } // Ecuador
            public static string MLC { get { return "https://auth.mercadolibre.cl"; } } // Chile
            public static string MLM { get { return "https://auth.mercadolibre.com.mx"; } } // Mexico
            public static string MLU { get { return "https://auth.mercadolibre.com.uy"; } } // Uruguay
            public static string MLV { get { return "https://auth.mercadolibre.com.ve"; } } // Venezuela
            public static string MPA { get { return "https://auth.mercadolibre.com.pa"; } } // Panama
            public static string MPE { get { return "https://auth.mercadolibre.com.pe"; } } // Peru
            public static string MPT { get { return "https://auth.mercadolibre.com.pt"; } } // Portugal
            public static string MRD { get { return "https://auth.mercadolibre.com.do"; } } // Dominicana


        }

        public string ClientSecret { get; private set; }

        public long ClientId { get; private set; }

        public string AccessToken { get; private set; }

        public string RefreshToken { get; private set; }

        /** News **/

        public long ExperiIn { get; private set; }

        public string Scope { get; private set; }

        public string UserId { get; private set; }

        public string TokenType { get; private set; }


        public Meli (long clientId, string clientSecret)
        {
            this.ClientId = clientId;
            this.ClientSecret = clientSecret;
        }

        public Meli (long clientId, string clientSecret, string accessToken)
        {
            this.ClientId = clientId;
            this.ClientSecret = clientSecret;
            this.AccessToken = accessToken;
        }

      
        public Meli (long clientId, string clientSecret, string accessToken, string refreshToken)
        {
            this.ClientId = clientId;
            this.ClientSecret = clientSecret;
            this.AccessToken = accessToken;
            this.RefreshToken = refreshToken;
        }

        public string GetAuthUrl (string authUrl , string redirectUri)
        {
            return authUrl+"/authorization?response_type=code&client_id=" + ClientId + "&redirect_uri=" + HttpUtility.UrlEncode (redirectUri);
        }

        public void Authorize (string code, string redirectUri)
        {
            var request = new RestRequest ("/oauth/token?grant_type=authorization_code&client_id={client_id}&client_secret={client_secret}&code={code}&redirect_uri={redirect_uri}", Method.POST);

            request.AddParameter ("client_id", this.ClientId, ParameterType.UrlSegment);
            request.AddParameter ("client_secret", this.ClientSecret, ParameterType.UrlSegment);
            request.AddParameter ("code", code, ParameterType.UrlSegment);
            request.AddParameter ("redirect_uri", redirectUri, ParameterType.UrlSegment);

            request.AddHeader ("Accept", "application/json");

            var response = ExecuteRequest (request);

            if (response.StatusCode.Equals (HttpStatusCode.OK)) {
                var token = JsonConvert.DeserializeAnonymousType (response.Content, new {refresh_token="", access_token = "", expires_in = 0,
                user_id = "", scope = "", token_type = ""});
                this.AccessToken = token.access_token;
                this.RefreshToken = token.refresh_token;
                this.ExperiIn = Convert.ToInt64(token.expires_in);
                this.Scope = token.scope;
                this.UserId = token.user_id;
                this.TokenType = token.token_type;
            } else {
                throw new AuthorizationException ();
            }
        }

        public IRestResponse Get (string resource)
        {
            return Get (resource, new List<Parameter> ());
        }

        public void refreshToken ()
        {
            var request = new RestRequest ("/oauth/token?grant_type=refresh_token&client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}", Method.POST);
            request.AddParameter ("client_id", this.ClientId, ParameterType.UrlSegment);
            request.AddParameter ("client_secret", this.ClientSecret, ParameterType.UrlSegment);
            request.AddParameter ("refresh_token", this.RefreshToken, ParameterType.UrlSegment);

            request.AddHeader ("Accept", "application/json");

            var response = ExecuteRequest (request);

            if (response.StatusCode.Equals (HttpStatusCode.OK)) {
                var token = JsonConvert.DeserializeAnonymousType (response.Content, new {refresh_token="", access_token = "", expires_in = 0,
                user_id = "", scope = "", token_type = ""});
                this.AccessToken = token.access_token;
                this.RefreshToken = token.refresh_token;
                this.ExperiIn = Convert.ToInt64(token.expires_in);
                this.Scope = token.scope;
                this.UserId = token.user_id;
                this.TokenType = token.token_type;
            } else {
                throw new AuthorizationException ();
            }
        }

        public void refreshToken(string refresh_token )
        {
            var request = new RestRequest("/oauth/token?grant_type=refresh_token&client_id={client_id}&client_secret={client_secret}&refresh_token={refresh_token}", Method.POST);
            request.AddParameter("client_id", this.ClientId, ParameterType.UrlSegment);
            request.AddParameter("client_secret", this.ClientSecret, ParameterType.UrlSegment);
            request.AddParameter("refresh_token", refresh_token, ParameterType.UrlSegment);

            request.AddHeader("Accept", "application/json");

            var response = ExecuteRequest(request);

            if (response.StatusCode.Equals(HttpStatusCode.OK))
            {
                var token = JsonConvert.DeserializeAnonymousType(response.Content, new
                {
                    refresh_token = "",
                    access_token = "",
                    expires_in = 0,
                    user_id = "",
                    scope = "",
                    token_type = ""
                });
                this.AccessToken = token.access_token;
                this.RefreshToken = token.refresh_token;
                this.ExperiIn = Convert.ToInt64(token.expires_in);
                this.Scope = token.scope;
                this.UserId = token.user_id;
                this.TokenType = token.token_type;
            }
            else
            {
                throw new AuthorizationException();
            }
        }

        public IRestResponse Get (string resource, List<Parameter> param)
        {
            bool containsAT = false;

            var request = new RestRequest (resource, Method.GET);
            List<string> names = new List<string> ();
            foreach (Parameter p in param) {
                names.Add (p.Name + "={" + p.Name + "}");
                if (p.Name.Equals ("access_token")) {
                    containsAT = true;
                }
                p.Type = ParameterType.UrlSegment;
                request.AddParameter (p);
            }

            request.Resource = resource + "?" + String.Join ("&", names.ToArray ());

            request.AddHeader ("Accept", "application/json");

            var response = ExecuteRequest (request);

            
            return response;
        }

        public IRestResponse Post (string resource, List<Parameter> param, object body)
        {
            bool containsAT = false;

            var request = new RestRequest (resource, Method.POST);
            List<string> names = new List<string> ();
            foreach (Parameter p in param) {
                names.Add (p.Name + "={" + p.Name + "}");
                if (p.Name.Equals ("access_token")) {
                    containsAT = true;
                }
                p.Type = ParameterType.UrlSegment;
                request.AddParameter (p);
            }

            request.Resource = resource + "?" + String.Join ("&", names.ToArray ());

            request.AddHeader ("Accept", "application/json");
            request.AddHeader ("Content-Type", "application/json");
            request.RequestFormat = DataFormat.Json;

            request.AddBody (body);

            var response = ExecuteRequest (request);

           

            return response;
        }

        public IRestResponse Put (string resource, List<Parameter> param, object body)
        {
            bool containsAT = false;

            var request = new RestRequest (resource, Method.PUT);
            List<string> names = new List<string> ();
            foreach (Parameter p in param) {
                names.Add (p.Name + "={" + p.Name + "}");
                if (p.Name.Equals ("access_token")) {
                    containsAT = true;
                }
                p.Type = ParameterType.UrlSegment;
                request.AddParameter (p);
            }

            request.Resource = resource + "?" + String.Join ("&", names.ToArray ());

            request.AddHeader ("Accept", "application/json");
            request.AddHeader ("Content-Type", "application/json");
            request.RequestFormat = DataFormat.Json;

            request.AddBody (body);

            var response = ExecuteRequest (request);

           

            return response;
        }

        public IRestResponse Delete (string resource, List<Parameter> param)
        {
            bool containsAT = false;

            var request = new RestRequest (resource, Method.DELETE);
            List<string> names = new List<string> ();
            foreach (Parameter p in param) {
                names.Add (p.Name + "={" + p.Name + "}");
                if (p.Name.Equals ("access_token")) {
                    containsAT = true;
                }
                p.Type = ParameterType.UrlSegment;
                request.AddParameter (p);
            }

            request.Resource = resource + "?" + String.Join ("&", names.ToArray ());

            request.AddHeader ("Accept", "application/json");

            var response = ExecuteRequest (request);


            return response;
        }

        public IRestResponse ExecuteRequest(RestRequest request) {
            client.UserAgent = sdkVersion;
            return client.Execute(request);
        }
    }
}

Edited by AGL

Share this post


Link to post
Share on other sites
  • 0

Veja que a autenticacao do Mercado Livre é do tipo Oath2 então o fluxo nao necessarimente precisa de uma URL de retorno . Eu testei agora aqui e esse fluxo funcionou

 

var client = new RestClient("https://api.mercadolibre.com/oauth/token");
var request = new RestRequest(Method.POST);
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("undefined", "client_id=<CLIENTID>&client_secret=<SECRET>&grant_type=client_credentials", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

Share this post


Link to post
Share on other sites
  • 0

Seu erro está na chamada do Authorize. Você não deve chamar o Authorize ali. No seu código deixe esta parte:

Meli m = new Meli(clientId, "clientSecret");
string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://seusite/meli/login");

Logo depois de pegar a redirectUrl você redireciona seu usuário para a url que está em redirectUrl.

Aí por exemplo se a sua URL de retorno é https://seusite/meli/login dentro da chamada dele você recupera o code da querystring e coloca:
 

Meli m = new Meli(clientId, "clientSecret");
m.Authorize(code, "https://seusite/meli/login");

Veja a descrição do processo lá no site da documentação no GitHub (é só jogar no tradutor do google, caso não entenda inglês):
 

Quote

 

Este é um processo de 2 etapas.

Primeiro, pegue o link para redirecionar o usuário. Isso é muito fácil! Somente:

Isso lhe dará a URL para redirecionar o usuário. Você precisa especificar um URL de retorno de chamada que será aquele que o usuário será redirecionado após um processo de autorização bem-sucedido.

Depois que o usuário for redirecionado para seu URL de retorno de chamada, você receberá na string de consulta um parâmetro chamado code. Você precisará disso para a segunda parte do processo.

 

 

Share this post


Link to post
Share on other sites
  • 0

Minha aplicação não é WEB ela é Desktop (Windows Forms) em C#.
Portanto como fazer para usuário efetuar a autorização do meu aplicativo (redirecionar o usuário e pegar o retorno)?

Como executar a URl obtida na string redirectUrl (string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://www.meusite.com.br");) abrir a pagina do Mercado Livre para o usuário informar o E-MAIL e SENHA de acesso, clicar sobre o botão PERMITIR dentro da tela do ML e depois pegar o código  TG-5bXXXe2ee4b0b1178dfefe31-XXXXXXXXX de retorno para ai sim partir para a função Authorize e obter o AccessToken, RefreshToken e ExperiIn?

Edited by AGL

Share this post


Link to post
Share on other sites
  • 0
On 7/25/2018 at 1:33 PM, Diogenes Lima said:

Seu erro está na chamada do Authorize. Você não deve chamar o Authorize ali. No seu código deixe esta parte:


Meli m = new Meli(clientId, "clientSecret");
string redirectUrl = m.GetAuthUrl(Meli.AuthUrls.MLB, "https://seusite/meli/login");

Logo depois de pegar a redirectUrl você redireciona seu usuário para a url que está em redirectUrl.

Aí por exemplo se a sua URL de retorno é https://seusite/meli/login dentro da chamada dele você recupera o code da querystring e coloca:
 


Meli m = new Meli(clientId, "clientSecret");
m.Authorize(code, "https://seusite/meli/login");

Veja a descrição do processo lá no site da documentação no GitHub (é só jogar no tradutor do google, caso não entenda inglês):
 

 

Olá, boa tarde

Também estou com dificuldade para pegar o CODE.

Após instanciar a classe Meli e criar a string redirectUrl (via GetAuthUrl) , eu  instancio um RestClient e executo o POST da redirectUrl. Já testei manualmente via browser a URL criada via GetAuthUrl e ela redireciona certinho e me mostra  o CODE no navegador.

Quando vou fazer o processo via Restsharp, na hora de pegar a resposta, o conteúdo de retorno não tem o CODE

            var client = new RestClient();
            var request = new RestRequest(redirectUrl, Method.POST);
            IRestResponse response = client.Execute(request);

            var qs = HttpUtility.ParseQueryString(response.Content);
            var code = qs["code"];

 

Será que poderiam me ajudar?

Edited by Nathalie

Share this post


Link to post
Share on other sites
  • 0

Nathalie, é o mesmo problema que estou enfrentando.
Manualmente também consegui fazer da mesma forma, o problema é via código C#.

Edited by AGL

Share this post


Link to post
Share on other sites
  • 0
On 7/25/2018 at 1:10 PM, gbandoni said:

Veja que a autenticacao do Mercado Livre é do tipo Oath2 então o fluxo nao necessarimente precisa de uma URL de retorno . Eu testei agora aqui e esse fluxo funcionou

 

var client = new RestClient("https://api.mercadolibre.com/oauth/token");
var request = new RestRequest(Method.POST);
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("undefined", "client_id=<CLIENTID>&client_secret=<SECRET>&grant_type=client_credentials", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);

AGL, esquece o CODE

O exemplo que o GBANDONI enviou já retorna direto o ACCESS TOKEN

 

Share this post


Link to post
Share on other sites
  • 0

Nathalie, mas como? Para mim não retorna nada. O que to fazendo de errado?

 

erro_ml.png

Edited by AGL

Share this post


Link to post
Share on other sites
  • 0

Habilitei sim! A grande duvida é:

1) Como redireciono meu cliente para a URL da string redirectUrl para o mesmo informar seu  E-MAIL e SENHA do Mercado Livre para autorizar meu aplicativo?!
2) Após o cliente autorizar, como pego o código (CODE) de retorno TG-5b58c3a1e4b0fc...... para prosseguir com a autorização?!

ger_apli_ml.png

Edited by AGL

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this