17
respostas

Token JWT inválido ou expirado!

Mesmo quando eu refaço o login, está retornando Token JWT inválido ou expirado.![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

17 respostas

Oi Gabriel!

Pode ser outro erro que está acontecendo. Coloca um try/catch no controller:

try {
    var authenticationToken = new UsernamePasswordAuthenticationToken(dados.login(), dados.senha());
    var authentication = manager.authenticate(authenticationToken);

    var tokenJWT = tokenService.gerarToken((Usuario) authentication.getPrincipal());

    return ResponseEntity.ok(new DadosTokenJWT(tokenJWT));
} catch(Exception e) {
    e.printStackTrace();
    return ResponseEntity.badRequest().body(e.getMessage());
}

Agora está dando outro erro. Segue prints:

![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

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

Teu método recuperarToken da classe SecurityFilter está incorreto. Altere o if e o return para ficar igual demonstrado na aula

O retorno de Token inválido agora aparece até na parte de login. Eu tento fazer o login, mas aparece Token inválido, só que nem está retornando um token.

Confere se sua classe SecurityFilter está assim:

@Component
public class SecurityFilter extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private UsuarioRepository repository;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        var tokenJWT = recuperarToken(request);

        if (tokenJWT != null) {
            var subject = tokenService.getSubject(tokenJWT);
            var usuario = repository.findByLogin(subject);

            var authentication = new UsernamePasswordAuthenticationToken(usuario, null, usuario.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

        filterChain.doFilter(request, response);
    }

    private String recuperarToken(HttpServletRequest request) {
        var authorizationHeader = request.getHeader("Authorization");
        if (authorizationHeader != null) {
            return authorizationHeader.replace("Bearer ", "");
        }

        return null;
    }

}

E a classe SecurityConfigurations está assim:

@Configuration
@EnableWebSecurity
public class SecurityConfigurations {

    @Autowired
    private SecurityFilter securityFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().authorizeHttpRequests()
                .requestMatchers(HttpMethod.POST, "/login").permitAll()
                .anyRequest().authenticated()
                .and().addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
                .build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

Agora está retornando o seguinte erro:

org.springframework.security.authentication.InternalAuthenticationServiceException: UserDetailsService returned null, which is an interface contract violation

Esse erro somente acontece se não tiver usuário na tabela com o email que você está tentando fazer login.

Boa tarde Prof,

Também estou com o mesmo erro, onde passo o token na minha request, porém sempre caio na Exception "Token JWT Inválido ou Expirado".

Debuggando o código, percebi que ao passar pelo .verify(TokenJWT) do método getSubject(), caio na exceção.

public String getSubject(String tokenJWT) {

        try {
            var algoritmo =  Algorithm.HMAC256(secret);
            return JWT.require(algoritmo)
                    .withIssuer("API Voll.med")
                    .build()
                    .verify(tokenJWT)
                    .getSubject();

        } catch (JWTVerificationException exception) {
            throw new RuntimeException("Token JWT inválido ou expirado!");
        }

Debugging

Pesquisei o que pode ser, mas ainda não cheguei numa solução definitiva.

Oi Juan!

No seu caso é o token que está inválido mesmo. No segundo print aparece a String e ela está muito grande para ser um token :D

Confere isso

Professor estou com o mesmo problema, estou utilizando o token gerado pela própria API.

Coloquem um try/catch no controller para saber qual exception de fato está ocorrendo:

try {
    var authenticationToken = new UsernamePasswordAuthenticationToken(autenticacao.login(), autenticacao.senha());
    var authentication = authenticationManager.authenticate(authenticationToken);
} catch (Exception e) {
    e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.OK).build();

No meu caso o erro era a string no .withIssuer("String") dos métodos gerarToken() e getSubject() que estavam diferentes, por isso estava caindo no exception, depois que deixei elas iguais voltou a funcionar..

Pessoal, bom dia!

A demonstração do Rodrigo é excelente, mas para nos tornamos ótimos desenvolvedores precisamos aprender a debugar, pois é o que faremos no dia a dia.

No meu caso estava apresentando o mesmo erro reportado acima: Token JWT inválido ou expirado

Porem usando debug voce consegue ve a exception que ele lançou:

debug

Mas tenho a exception, mas e agora? Agora é o ponto de se analisar, ele esta reclamando que a assinatura do token é invalida e diferente da usada no HMAC256, então vem o "estalo" de olhar onde gerei o token, porque la foi onde eu passei a criptografia que ele iria usar.

E "voala" kkkk

No meu codigo esta gerando o token com o secret usando uma String e na hora de verificar esta usando o meu secrete que pega do properties.

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

Provavelmente o de voces está desse mesmo jeito, dê uma olhada. Abraço, espero te ajudado.

Boa noite, mesmo fazendo este passo a passo, continua dando erro e tudo está igual.

Se postou se codigo no git envia aqui o link.

No meu caso, era algo bem simples. Estava sem o espaço após o Bearer no método recuperarToken:

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

Corrigida a questão do espaço, foi resolvido o problema:

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

Obrigado Allison, era o meu problema também.