Como criar login com JWT em Java?

O JWT (JSON Web Token) é usado para autenticação sem estado em aplicações Java, permitindo login seguro e proteção de APIs.

Como criar login com JWT em Java?

A autenticação com JSON Web Token (JWT) é uma forma segura e sem estado de proteger APIs REST. No Spring Boot, é possível gerar e validar JWTs facilmente utilizando bibliotecas como jjwt.

1. Adicionando Dependências

No pom.xml, adicione a biblioteca para manipulação de JWT:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.11.5</version>
</dependency>

2. Criando uma Classe para Gerenciar Tokens JWT

Crie uma classe JwtUtil para gerar e validar tokens:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {
    private static final String SECRET_KEY = "minhaChaveSecreta";

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 hora
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public static String extractUsername(String token) {
        return getClaims(token).getSubject();
    }

    public static boolean isTokenValid(String token) {
        return getClaims(token).getExpiration().after(new Date());
    }

    private static Claims getClaims(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }
}

Explicação:

  • generateToken() cria um token válido por 1 hora.
  • extractUsername() recupera o nome do usuário do token.
  • isTokenValid() verifica se o token é válido.

3. Criando um Endpoint de Login

Crie um Controller para autenticação:

import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/login")
    public Map<String, String> login(@RequestBody LoginRequest request) {
        // Simulação de validação de usuário (substitua por consulta ao banco de dados)
        if ("admin".equals(request.getUsername()) && "123456".equals(request.getPassword())) {
            String token = JwtUtil.generateToken(request.getUsername());
            Map<String, String> response = new HashMap<>();
            response.put("token", token);
            return response;
        }
        throw new RuntimeException("Credenciais inválidas");
    }
}

class LoginRequest {
    private String username;
    private String password;

    public String getUsername() { return username; }
    public String getPassword() { return password; }
}

Explicação:

  • Recebe um username e password.
  • Valida o usuário (de forma simplificada, sem banco de dados).
  • Retorna um token JWT caso a autenticação seja bem-sucedida.

4. Protegendo Endpoints com JWT

Agora, crie um filtro de autenticação para validar o token antes de processar as requisições:

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;

public class JwtFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            if (!JwtUtil.isTokenValid(token)) {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token inválido ou expirado");
                return;
            }
        } else {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token ausente");
            return;
        }
        chain.doFilter(request, response);
    }
}

Explicação:

  • O filtro intercepta todas as requisições.
  • Verifica se há um token JWT no cabeçalho Authorization.
  • Se o token for inválido ou ausente, bloqueia a requisição.

5. Aplicando o Filtro no Spring Security

No SecurityConfig, adicione o filtro JWT:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/auth/login").permitAll()
                .anyRequest().authenticated()
            )
            .addFilterBefore(new JwtFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
}

Explicação:

  • O Spring Security exige autenticação para todos os endpoints, exceto /auth/login.
  • O JwtFilter é adicionado antes da autenticação padrão.

6. Testando a Autenticação com JWT

  1. Gerar o Token:
    • Faça uma requisição POST para http://localhost:8080/auth/login.
    • Envie um JSON com:
{
    "username": "admin",
    "password": "123456"
}
  1. Usar o Token nas Requisições:
    • Copie o token JWT recebido.
    • Faça uma requisição GET para qualquer endpoint protegido.
    • No Postman, adicione um cabeçalho Authorization com Bearer SEU_TOKEN_AQUI.

Se o token for válido, a requisição será processada com sucesso.

Conclusão

O JWT permite que aplicações Java implementem autenticação sem estado, eliminando a necessidade de sessões no servidor. No Spring Boot, a configuração é simplificada com Spring Security, garantindo proteção para APIs REST.

O JWT revolucionou a autenticação de APIs REST. Antes, os sistemas dependiam de sessões no servidor, o que gerava alto consumo de memória. Com o JWT, os clientes armazenam o token e o enviam a cada requisição, tornando a autenticação escalável e eficiente. Essa abordagem é amplamente utilizada em aplicações modernas e microsserviços.

Algumas aplicações:

  • Autenticação segura para APIs REST
  • Login sem necessidade de sessões no servidor
  • Controle de acesso baseado em permissões
  • Integração com Single Sign-On (SSO)

Dicas para quem está começando

  • Use tokens curtos para aumentar a segurança
  • Não armazene tokens no localStorage em aplicações web
  • Proteja a chave secreta do JWT
  • Utilize refresh tokens para manter a sessão ativa

Contribuições de Rodrigo Farias

Compartilhe este tutorial: Como criar login com JWT em Java

Compartilhe este tutorial

Continue aprendendo:

Como autenticar usuários em uma aplicação Java web

Autenticar usuários em uma aplicação Java web pode ser feito com Spring Security, garantindo segurança e controle de acesso.

Tutorial anterior

Como configurar uma conexão com banco de dados no Spring Boot

No Spring Boot, configurar uma conexão com banco de dados é simples com Spring Data JPA e suporte para bancos como MySQL e PostgreSQL.

Próximo tutorial