Skip to main content

Step 5

Step 5 — Auth with JWT

4 views

Table of contents

REST is stateless — no server-side sessions. Each request must carry a credential. That credential is JWT.

A JWT in one line

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0In0.signature

Three parts split by .:

  1. Header — algorithm (HS256, RS256…)
  2. Payload — userId, expiry — signed, tamper-evident
  3. Signature — hash made with the server's secret key

The server issues a token; the client sends it on every request as Authorization: Bearer <token>.

Issue flow

1. POST /api/auth/login (email, password)
2. Service verifies password (BCrypt)
3. Issues JWT (sub=userId, exp=now+1h)
4. Returns { accessToken: "eyJ..." }

Spring Security in one config

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
            )
            .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}

STATELESS + a JWT filter is the heart.

The verification filter

@Component
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
    private final JwtService jwtService;

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws ServletException, IOException {
        String header = req.getHeader("Authorization");
        if (header != null && header.startsWith("Bearer ")) {
            String token = header.substring(7);
            Long userId = jwtService.parseUserId(token);
            // populate SecurityContext …
        }
        chain.doFilter(req, res);
    }
}

Try it

Build POST /api/auth/login, then curl -X POST http://localhost:8080/api/auth/login -d '{"email":"...","password":"..."}' to get a token. Call protected APIs with -H "Authorization: Bearer <token>".

Next

Step 6 adds tests so changes don't silently break.

Terms in this content