Rodrigo, fiz a mudança, mas não funcionou também, agora aparece a mensagem no Insomnia: "Token JWT inválido ou expirado!".
Esse linha "throw new RuntimeException("Token JWT não enviado no cabeçalho Authorization!");", você implementa na aula "05 Recuperando o token".
Quando fiz esse aula "05 Recuperando o token", o programa funcionou corretamente, o problema começou na aula seguinte, "06 Validando o token recebido", pois só fui estudar ela no dia seguinte, então o token já havia experido.
Porém, quando disparo uma nova solicitação de login no Insomnia, deveria surgir um novo, certo? Mas aparece a mensagem "Token JWT não enviado no cabeçalho Authorization!", e se eu alterar o código com a mudança que você sugeriu, aparece, "Token JWT inválido ou expirado!".
Reassisti as duas aulas hoje e essa parte do código que você sugeriu mudar, continua como está no meu projeto.
A última aula que estudei é a "06 Validando o token recebido", nela você pode conferir esse código ainda implementado.
De qualquer forma, estou enviando o código completo das duas classes para análise. Ok?
package med.voll.api.infra.security;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import med.voll.api.domain.usuario.Usuario;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
@Service
public class TokenService {
@Value("${api.security.token.secret}")
private String secret;
public String gerarToken(Usuario usuario) {
try {
var algoritmo = Algorithm.HMAC256(secret);
return JWT.create()
.withIssuer("API Voll.med")
.withSubject(usuario.getLogin())
.withExpiresAt(dataExpiracao())
.sign(algoritmo);
} catch (JWTCreationException exception){
throw new RuntimeException("erro ao gerrar token jwt", exception);
}
}
//Valida o token
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!");
}
}
private Instant dataExpiracao() {
return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00"));
}
}
package med.voll.api.infra.security;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Component
public class SecurityFilter extends OncePerRequestFilter {
@Autowired
private TokenService tokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//Recupera o token do cabeçalho.
var tokenJWT = recuperarToken(request);
//Valida se o token está correto.
var subject = tokenService.getSubject(tokenJWT);
//Necessário para chamar o próximo filtro na aplicação.
filterChain.doFilter(request, response);
}
private String recuperarToken(HttpServletRequest request) {
var authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader == null) {
throw new RuntimeException("Token JWT não enviado no cabeçalho Authorization!");
}
return authorizationHeader.replace("Bearer ", "");
}
}