Spring Boot Backend Development Course, Implementing Login and Logout with JWT, Adding Dependencies

Hello! In this blog post, we will take a detailed look at how to implement login and logout functionalities using JSON Web Token (JWT) in the backend development process with Spring Boot. Authentication and authorization are crucial elements in web application development, and JWT helps to manage them effectively. In this tutorial, we will explain the concept of JWT, Spring Boot configuration, how to add dependencies, and more step by step.

1. What is JWT?

JWT stands for JSON Web Token, a standard for securely transmitting user authentication information. JWT consists of three parts:

  • Header: Contains information about the type of token and the hashing algorithm used.
  • Payload: Includes claims such as user information. This claim can contain public information (information needed for API calls).
  • Signature: A signature created using a secret key based on the header and payload information. This ensures the integrity of the data and is used to verify if someone has forged the token.

The greatest advantage of JWT is its stateless property. As there is no need for the server to maintain session state, it provides excellent scalability and performance.

2. Creating a Spring Boot Project

Let’s create a new project using Spring Boot. First, visit Spring Initializr (https://start.spring.io/). Apply the following settings to create the project:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.6.0 (select the latest version)
  • Group: com.example
  • Artifact: jwt-demo
  • Dependencies: Spring Web, Spring Security, Spring Data JPA, H2 Database

After creating the project, open it in your IDE and set up the necessary directory structure.

3. Adding Dependencies

First, add the required dependencies to the pom.xml file:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jwt</artifactId>
    <version>0.9.1</version>
</dependency>

Additionally, Spring Security and Data JPA are already included, so no extra dependencies are needed. The H2 database can be useful for development and testing environments.

4. Configuring Spring Security

We need to configure Spring Security to use JWT. First, create the SecurityConfig class:

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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests().antMatchers("/api/auth/**").permitAll()
            .anyRequest().authenticated();
    }
}

In the above configuration, all users can access the /api/auth/** path. All other requests require authentication.

5. Generating and Validating JWT

Let’s write a class to generate and validate JWT. Define the necessary methods here:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class JwtUtil {

    private String secretKey = "YourSecretKey"; // The secret key should be managed securely and not exposed

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

    public boolean validateToken(String token, String username) {
        final String extractedUsername = extractUsername(token);
        return (extractedUsername.equals(username) && !isExpired(token));
    }

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

    private Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
    }

    private boolean isExpired(String token) {
        return extractAllClaims(token).getExpiration().before(new Date());
    }
}

The above JwtUtil class contains methods for token generation, validation, and username extraction.

6. Implementing Authentication and Logout

Now let’s write a controller to handle authentication and logout. Create the AuthController class:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/login")
    public ResponseEntity login(@RequestBody AuthRequest authRequest) {
        // Add user authentication logic here
        String token = jwtUtil.generateToken(authRequest.getUsername());
        return ResponseEntity.ok(token);
    }

    @PostMapping("/logout")
    public ResponseEntity logout() {
        // Add logic to blacklist JWT, etc.
        return ResponseEntity.ok("Logout successful");
    }
}

In the above code, AuthRequest is a DTO class that contains the username and password, and the user authentication logic should be implemented in detail. Typically, it checks the authentication information in the database.

7. Final Testing

Now that we have completed all the configurations, you can test the API using a tool like Postman:

  • Login: POST /api/auth/login
  • Logout: POST /api/auth/logout

By passing the username and password in the request body of the login API, you will successfully receive a JWT in return. The returned JWT should be included in the Authorization header for subsequent API calls.

8. Conclusion

We explored the implementation of login and logout functionalities based on JWT using Spring Boot. Authentication and authorization are crucial aspects of web application development, and JWT helps manage these conveniently and securely. Additional features to consider include handling JWT blacklist and implementing refresh tokens.

I hope this tutorial has been helpful for your Spring Boot backend development. For more information and resources, you can check the official documentation and community. Thank you!