3
respostas

Chamar Promisse dentro de outra Promisse

Estou com uma dúvida referente a $resource do AngularJS. Vou tentar explicar o fluxo:

Fiz um mecanismo em meu backEnd de geração de Token e RefreshToken. Sendo que o Token expira a cada 1 hora, porém se o client possuir o refreshToken no momento da requisição que devolve 401 poderá enviar o refrehToken e capturar um novo token para mais uma hora de consumo.

Consegui fazer todos os mecanismos, só não estou conseguindo no momento da requisição em que ela devolve 401 eu chamar meu minha API de Refresh token e novamente chamar a primeira requisição (a mesma que gerou o erro 401). Segue o código:



      factoryResource.GET = function (parametros, callback) {
        var acao = resourceAux.get(parametros);

        return processPromise(acao, callback);
      };



      var processPromise = function (call, callback) {

        var callOriginal = angular.copy(call);

        //SUCESSO GLOBAL DE UMA AÇÃO.
        function SUCESSO(result){

          if (result.hasOwnProperty("messages")) {
            mensagensFactory.generateMessages(result.messages);
          }

          if (!angular.isUndefined(callback) &&
            result.hasOwnProperty("data")
          ) {
            callback(result.data);
          }
        };


        //ERRO SEM REFRESH
        function ERROR(result){

          if(result.status === 401){
               refresh();
               processPromise(callOriginal, callback);
          } else {
            if (result.data) {
              if (result.data.hasOwnProperty("messages")) {
                mensagensFactory.generateMessages(result.data.messages);
              }

              if (result.data.hasOwnProperty("data")) {
                if (callback) {
                  callback(result.data.data);
                }
              }
            }
          }
        };

        //DEFINIÇÃO DE PROMISSE.
        call.$promise
          .then(SUCESSO)
          .catch(ERROR);

        return call.$promise;
      };

      function refresh() {
          // Colocar aqui implementação de refresh Token.
      }

O código está meio bagunçado, por que eu estou testando vários métodos.

Alguém poderia me ajudar?

3 respostas

Bom dia.

Estou com dificuldade de entender, porém essa responsabilidade não deveria ficar em sua API se é que entendi direito.

Em versões nova do Angular há o HttpClient. Ele possui interceptações. Como é algo que ainda não me profundei, não tenho certeza que seja a solução, mas você pode tratar nesse interceptador o 401 e fazer esse processo sem mexer na sua API.

Da uma conferida em https://angular.io/guide/http

O código ficará menos nebuloso.

Sucesso e bom estudo meu aluno.

Olá professor, obrigado pela resposta, O que eu preciso é que minha aplicação, ao fazer uma requisição e a mesma retornar que o token esta expirado, a aplicação sem intermédido do usuário, usando o refreshToken solicitar um novo token e com este token chamar novamente a requisição inicial. Exemplo:

  • Requisição capturar equipamentos; |> Resposta de token expirado.
  • Requisição de RefreshToken |> Resposta com um novo Token e Refresh Token.
  • Nova requisição de capturar equipamento (porém com o novo token).

  • Tem como fazer isso com interceptor?

  • Qual a melhor forma (ou padrão) para eu resolver ? Lembrando que estou utilizando angularJS

Pelo interceptador você não misturará a lógica de refresh do token em sua API. Pelo menos, é assim que eu entendo o seu problema.

Eu não faço refresh automático de token em minhas aplicações, mas fica claro que é uma necessidade sua e você deseja resolver.

Pesquisei por algumas soluções com Angular 2 e encontrei

https://stackoverflow.com/questions/42645350/how-to-refresh-the-access-token-using-custom-http-in-angular-2

Achei uma em angular 1.X que usa o interceptor. Por mais que seja em Angular 1.X pode servir como espelho para uma solução com interceptor em Angular 2.

https://stackoverflow.com/questions/26552892/angularjs-http-interceptor-resend-all-request-after-token-refresh

Dá uma conferida. Eu penso que é melhor ir por esse caminho para que sua API não fique poluída com esse código de infra.