Tecnologia do Blogger.
RSS

Re: [androidbrasil-dev] Re: Retrofit2 com autenticação

Tiago, entendi o que quer fazer, mas neste caso é mais simples não deixar o token NÃO expirar, certo?

Tipo, se a aplicação pode revalidar o token quando o token for inválidado. Não tem porque existir o "invalidamento de token com revalidamento de token", sacou?

Mas como somos brasileiros e não desistimos nunca, dá uma olhada no meu CustomCallback.

public class CustomCallback<T> implements Callback<T> {

   
private Context context;

   
public CustomCallback(Context context) {
       
this.context = context;
   
}

   
@Override
    public void onResponse(Call<T> call, Response<T> response) {
       
try {
           
if (!Utils.isNullOrEmpty(response)) {
               
Excecao excecao = (Excecao) response.body();
               
Utils.dispararAlerta(((Activity) context), excecao);
           
}
       
} catch (Exception e) {
            e
.printStackTrace();
       
}
   
}

   
@Override
    public void onFailure(Call<T> call, Throwable t) {
       
if (!Utils.isNullOrEmpty(t) && !Utils.isNullOrEmpty(t.getMessage()) && t.getMessage().contains("Unable to resolve host")) {
           
UtilsAlerta.dispararDialogSimples(context, Application.getContext().getString(R.string.erro), Application.getContext().getString(R.string.sem_conectividade_com_o_servidor));
       
} else {
           
UtilsAlerta.dispararDialogSimples(context, Application.getContext().getString(R.string.erro), t.getMessage());
       
}
   
}
}

Uma forma de fazer isso que você quer (com base na minha sugestão e código), bastaria você tratar a revalidação do token dentro do if "(!Utils.isNullOrEmpty(response))". 
Ótimo, você teria o novo token e provavelmente setaria em uma sigleton que cuida da sua sessão.
Agora precisará pensar em como reenviar este request (com o novo token).

Sugiro olhar no seu "createService", lá dá pra colocar um interceptor que analisa os pacotes que estão sendo trafegados, talvez consiga "repetir" um pacote (alterando o seu token), mas não consigo imaginar em como controlaria isto através de cada consulta (é meio que cada trecho do endpoint vai controlar a parte que lida com a requisição, caminho inverso). Como disse, sugiro dar uma olhada se dá pra bolar alguma coisa - mas não acho um caminho muito agradável.

O segundo caminho que sugiro dar uma olhada, é o design pattern Proxy que trata justamente do encapsulamento (que é o que tá acontecendo lá no seu create service, junto com o interceptor do okhttp e tal).
Ou seja, você criaria um proxy (no sentido de design pattern) que encapsularia a requisição ([...]enquee(newCustomCallback)[...]) e antes de fazer a requisição em si, cria um endpoint pra validar o token e com base nisto você trata se gera ou não um novo token etc.

Finalizando, tem jeito de fazer o que você quer, mas ainda bato o pé que o token não deve ser revalidado caso seja inválido - porque se não perde o sentido de usar o token.

P.S.: De quebra neste código, ainda tem como tratar quando não houver conectividade com o servidor hehehe.

Em terça-feira, 12 de julho de 2016 15:03:05 UTC-3, Tiago J. Grillo escreveu:
Pedro fiz a solução baseado na sua ideia 2 e vi o site também (muito legal)

Veja se consegue me ajudar com mais esta (abro a quem mais puder ajudar..rsrss)

Como eu disse no primeiro post, queria montar uma classe que funcionasse assim por exemplo:

     BlaAPI api = ServiceGenerator.createService(BlaAPI.class, Bla.class);
     api.FazAlgo("321").enqueue(new Callback<Dispositivo>()....);

Esta chama no header esta indo o token, se este estiver válido, coisa linda, 

Mas se ele for inválido o programador no Callback vai ter o erro de autenticação e preciso fazer uma nova chamada para o 

     loginAPI.GerarToken(user).enqueue(new Callback<Token>()...)...

Para pegar um token válido. E ai depois fazer uma nova chamada para o api.FazAlgo...

Eu queria encapsular isso, e o programador só faz a chamada que deseja, e caso o erro seja por conta do token esta classe se encarrega de buscar um novo e concluir a chama original, neste exemplo a api.FazAlgo


Obrigado,
Tiago Grillo

2016-06-02 10:18 GMT-03:00 Tiago Grillo <tijg...@gmail.com>:
Olá,
    
    Pedro gostei do site, quanto a ideia eu acho que entendi, vou fazer uns testes aqui e absorver ela melhor e volto com (mais duvidas) um feedback...

Obrigado

2016-06-02 9:17 GMT-03:00 pedrofsn <pedr...@gmail.com>:
Bom dia,

Estou utilizando o Retrofit2, encontrei um local com os melhores tutoriais pra esta library (https://futurestud.io/blog/retrofit-token-authentication-on-android).
Encontrei duas saídas pra resolver este problema, ainda não acho que são as melhores, mas são funcionais.

  1. Colocar o servidor pra retornar um erro no protocolo e tratar este erro em cada response.
  2. Todos os seus objetos que forem retornados de uma requisição, devem extender um objeto "Erro" em que nele você tenha as propriedades das suas mensagens de erro (ex.: erroInterno, mensagemUsuario, mensagemLog). Nesta classe você pode determinar um atributo que sempre que for um erro vai existir (ex.: erro = true). Então quando retorno.isErro() for true, quer dizer que efetivamente ocorreu um erro e então você tratará. Como utilizo o retrofit 2, criem um CustomCallBack onde tenho o meu tratamento. 
Este segundo caso é uma alternativa ao primeiro por questões de padrões mesmo. Por exemplo, se o seu erro for a validação de cadastro, o server não tem que retornar um erro HTTP, ele vai retornar SUCESSO/200 e o seu JSON de erro (que é algo do SEU sistema e não do protocolo). O primeiro caso é ruim por conta disto, mas se não se importar, é até mais fácil de tratar hehehe.


Att.


Em quarta-feira, 1 de junho de 2016 16:54:50 UTC-3, Tiago J. Grillo escreveu:
Olá,

    Minha app faz chamadas síncronas e assíncronas a um servidor que fornece e pede um token no header. 

    Até ai tudo bem, minha duvida é:

    Qual a melhor maneira de implementar para que caso minha chamada ao servidor seja rejeitada (por que o token mudou ou esta inválido) eu já fazer uma chamada ao serviço que me dá um novo token e chamar novamente a requisição que originou tudo de forma transparente para o usuário (nas síncronas)?

    Faço isto no Interceptor, se é q posso fazer uma nova chamada aqui?
 
    Deixo dar erro e faço o tratamento no onFailure? 

--
You received this message because you are subscribed to the Google Groups "Android Brasil - Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to androidbrasil-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups "Android Brasil - Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to androidbrasil-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

  • Digg
  • Del.icio.us
  • StumbleUpon
  • Reddit
  • RSS

0 comentários:

Postar um comentário