• 0
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
  • 0
On 7/27/2018 at 1:18 PM, AGL said:

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

AGL vc conseguiu resolver esse problema? Como faço para conseguir essas informações?

 

 

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