2
respostas

TOKEN JWT INVÁLIDO OU EXPIRADO

Boa tarde!!

Após imprementar o teste de validade do token, o sistema só retorna: "TOKEN JWT INVÁLIDO OU EXPIRADO",

Quando tento gerar novo token ( com a requisição "Efetuar login"), o sistema retorna: "TOKEN JWT NÃO ENVIADO NO CABEÇALHO",

Portanto não consigo resolver o problema do primeiro caso relatado acima,

em anexo seguem um print das classes envolvidas e das telas do Isomnomia;

código SecurityFilter:

@Component  // é algo genérico
public class SecurityFilter extends OncePerRequestFilter {

    //chama a classe tokenService para analizar o token
    @Autowired
    private TokenService tokenService;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //o frontend irá enviar o token pelo cabelho autorization
        // APÓS REALIZAR O FILTER, ELE CHAMA: OU O PROXIMO FILTRO OO A CADEIA DE REQUISIÇÃO
        var tokenJWT = recuperarToken(request);
            var subject = tokenService.getSubject( tokenJWT );
            System.out.println( subject ); //imprime o nome do login
            System.out.println("chamou o fiter");
            System.out.println(tokenJWT); //imprime o token no console

        // vai ser encaminhado para o próximo filter o request e o response
        filterChain.doFilter( request, response );
    }
    private String recuperarToken(HttpServletRequest request) {
        // vai pegar o cabeçalho da requisição (onde virá o token)
        var authorizationHeader = request.getHeader( "Authorization" );
        // se não existir o cabeçalho vai lançar uma exception
        if (authorizationHeader == null){
            throw new RuntimeException("Token JWT não enviado no cabeçalho");
        }
        // para não vir no nome do cabeçalho(Bearer) foi feito um replace vazio
        return authorizationHeader.replace( "Bearer ", " " );
    }
}

código TokenService:

@Service
public class TokenService {


    // aqu ficará a senha para gerar tokens
    @Value( "${api.security.token.secret}" ) // aqui indica para buscar a variável no application.properties
    private String secret;

    public String gerarToken(UsuarioEntidade usuarioEntidade){

        System.out.println(secret);

        try {

            // dentro do parentese vai uma senha para gerar tokens
            var algoritimo = Algorithm.HMAC256( secret);
            return JWT.create()
                    .withIssuer("API VOLL.med")
                    .withSubject( usuarioEntidade.getLogin() )
                    .withExpiresAt( dataExpiracao() )
                    .sign(algoritimo);
        } catch (JWTCreationException exception){
            throw new RuntimeException("erro ao gerar token", exception);
        }

    }

    ////++++++++++++++++++++TESTA SE O TOKEN RECEBIDO (SecurityFilter) ESTÁ VÁLIDO+++++++++++


    // recebe o token vindo da classe SecutityFilter
    public String getSubject(String tokenJWT){
        // vai verificar se o token é valido:

        try {
            var algoritimo = Algorithm.HMAC256( secret);
            return JWT.require(algoritimo)
                    .withIssuer("API VOLL.med")
                    .build()
                    .verify(tokenJWT)//verifica se o token está valido
                    .getSubject(); // pega o nome do login do token

        } catch (JWTVerificationException exception){
            exception.printStackTrace();
            throw new RuntimeException("TOKEN JWT INVÁLIDO OU EXPIRADO");

        }

    }


        // aqui ajusta o tempo de expiração do token ( no caso ficou 2 horas)
    private Instant dataExpiracao() {
        ZoneOffset zoneOffset = ZoneOffset.of("Z"); // Criando um ZoneOffset UTC
        return LocalDateTime.now().plusHours(2).atOffset(zoneOffset).toInstant();
    }

}

telas: Insira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidade

2 respostas

Olá ! O erro "TOKEN JWT INVÁLIDO OU EXPIRADO" ocorre porque o token JWT não está sendo validado com sucesso no método getSubject do seu TokenService. Quando essa validação falha, a exceção JWTVerificationException é lançada, e você está tratando essa exceção da seguinte maneira:

catch (JWTVerificationException exception){
    exception.printStackTrace();
    throw new RuntimeException("TOKEN JWT INVÁLIDO OU EXPIRADO");
}

Isso significa que qualquer problema na validação do token, seja por inválido ou expirado, resultará em uma exceção sendo lançada com a mensagem "TOKEN JWT INVÁLIDO OU EXPIRADO".

A fim de solucionar esse problema e entender melhor qual é a causa raiz, você pode ajustar o código para fornecer mensagens mais informativas e identificar a razão exata da validação do token falhar. Por exemplo:

catch (JWTVerificationException exception){
    exception.printStackTrace();
    throw new RuntimeException("TOKEN JWT INVÁLIDO OU EXPIRADO: " + exception.getMessage());
}

Dessa forma, a mensagem de exceção irá incluir detalhes sobre o motivo da validação ter falhado, que pode ser útil para depurar o problema.

Lembre-se de que as principais razões para o token JWT ser considerado inválido ou expirado incluem:

  1. O token JWT foi manipulado.
  2. O token JWT expirou.
  3. A assinatura do token JWT não corresponde à chave secreta usada para criá-lo.
  4. O token JWT não foi fornecido na solicitação HTTP ou está em um formato inválido.
  5. A chave secreta usada para verificar o token JWT é diferente da usada para criá-lo.

Certifique-se de verificar esses pontos para solucionar o problema.

Boa tarde!

O meu problema é justamente: não consigo gerar um novo token, pois como explicado acima, ao tentar gerar um novo token, o sistema critica: "O TOKEN NÃO FOI ENVIADO NO CABEÇALHO", (na requisição de login), (na verdade, nesta requisição não deveria pedir nehum tipo de token)

Sem resolver este problema, eu não consigo dar andamento nas aulas, conto com o apoio de generosidade de vocês.

Muito obrigado!!