Spring Boot Backend Development Course, Implementing Login and Logout with JWT, Adding a Token Provider

1. Introduction

Recently, the importance of backend development has been highlighted due to the advancement of microservices architecture and RESTful APIs. In today’s lecture, we will learn how to implement user authentication using JSON Web Token (JWT) through backend development with Spring Boot. This lecture focuses on adding a JWT-based token provider that includes login and logout features.

2. What is Spring Boot?

Spring Boot is a tool that helps developers create Spring applications quickly and easily based on the Spring framework. It allows for the easy development of demo and real applications without complex XML configurations. Additionally, Spring Boot supports embedded servers, enabling applications to be run locally without deployment to an external server.

3. Understanding JWT

JSON Web Token (JWT) is an open standard for transmitting data, used to securely send information between client and server. JWT is mainly used for authentication and information exchange. A JWT consists of three parts:

  • Header: Defines the type of token and the encryption algorithm.
  • Payload: This part stores user information, such as user ID.
  • Signature: The part that is signed with a secret key by combining the header and payload.

4. Setting up a Spring Boot Project

First, you need to set up a Spring Boot project. Visit the Spring Initializr website to create a new project. You should add the following dependencies:

  • Spring Web
  • Spring Security
  • Spring Data JPA
  • H2 Database (or your desired database)
  • jjwt (library for using JWT)

5. Creating the User Entity Class

Create an entity class to store user information. Here is an example of the User entity class:


@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true)
    private String username;

    private String password;

    // Getter and Setter methods
}

            

6. Writing the JWT Utility Class

Write a utility class to create and validate JWT.


@Component
public class JwtUtil {
    private String secretKey = "mySecretKey"; // Secret key

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

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

    public String extractUsername(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
    }

    private boolean isTokenExpired(String token) {
        return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getExpiration().before(new Date());
    }
}

            

7. Setting Up Spring Security

Set up Spring Security to implement a JWT-based authentication process. First, configure the SecurityFilterChain.


@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private JwtRequestFilter jwtRequestFilter;

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("password")).roles("USER");
    }

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

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

            

8. Writing the JWT Request Filter

Create a JWT Request Filter that filters the JWT from user requests to verify authentication.


@Component
public class JwtRequestFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(jwt);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            // Process authentication for the specified user
        }
        chain.doFilter(request, response);
    }
}

            

9. Writing the Login and Token Generation Controller

Create a controller that handles user login requests and generates JWT.


@RestController
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/authenticate")
    public ResponseEntity authenticate(@RequestBody AuthRequest authRequest) throws Exception {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword()));
        } catch (BadCredentialsException e) {
            throw new Exception("Invalid username or password", e);
        }

        final String jwt = jwtUtil.generateToken(authRequest.getUsername());
        return ResponseEntity.ok(new AuthResponse(jwt));
    }
}

            

10. Managing Logout

Since JWT is managed on the client side, the logout feature can simply be performed by deleting the token on the client. However, it is also possible to implement logout on the server side. For example, maintaining a blacklist to block tokens that have been logged out before expiration can be done.

11. Configuring Middleware

Middleware can be used to add functionality for pre-processing and post-processing requests. For instance, you can check JWT for all requests or restrict access to specific endpoints.

12. Testing and Debugging

Adequate levels of testing should be applied to ensure code quality. Write unit tests for each service, controller, and repository. Spring Boot provides an effective test environment through Junit and Mockito.

13. Conclusion

In this lecture, we took a detailed look at how to implement login and logout using Spring Boot and JWT. JWT is a good method for securely handling communication between client and server, and it can significantly enhance the security of web applications. By understanding this method, you can improve your backend development skills and manage user authentication features more efficiently through such implementations in real projects.

Spring Boot Backend Development Course, Implementing Login and Logout with JWT, What is Token-based Authentication

1. Introduction

In modern web applications, there are various methods to efficiently perform user authentication and authorization management. Among these, JSON Web Token (JWT) is one of the widely used authentication methods. In particular, for backend developers using Spring Boot, JWT can be used to implement login and logout functionalities to create a safer and more efficient user authentication system. This course will explain in detail the concept of JWT, how to implement JWT-based authentication using Spring Boot, and the procedures for login and logout.

2. What is JWT?

JWT stands for JSON Web Token, which is an open standard (RFC 7519) for securely transmitting information between the user and the server. JWT is typically used in the following cases:

  • User authentication
  • Information exchange
  • Authorization

The characteristics of JWT are as follows:

  • It can carry information by itself.
  • It can prevent tampering using a signature.
  • It can be easily used in HTTP transmissions.

JWT consists of three parts: Header, Payload, and Signature. Detailed explanations of each part are as follows.

2.1 Header

The header of a JWT contains two pieces of information: the type of the token and the algorithm used (e.g., HMAC SHA256 or RSA).

{
    "alg": "HS256",
    "typ": "JWT"
}

2.2 Payload

The payload is the second part of the JWT that contains information about the user and claims. Claims can include user information, permissions, and other metadata. For example:

{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
}

In this example, “sub” represents the user’s unique ID, “name” represents the username, and “iat” indicates the time issued.

2.3 Signature

Lastly, the signature is created by combining the header and payload and generating a hash using a secret key. This allows the integrity of the data to be verified. For example:

HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)

Through this process, a JWT is generated, and the recipient can verify the validity of the token using the secret key they possess.

3. Spring Boot Setup

To implement a JWT-based user authentication system using Spring Boot, you first need to set up a Spring Boot project. You should create a new project using Spring Initializr and add the necessary dependencies. In this course, we will use Spring Web, Spring Security, and the jjwt library.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'io.jsonwebtoken:jjwt:0.9.1'
}

4. Configuring Spring Security and JWT

You can set up basic authentication and authorization using Spring Security. To do this, you need to write a SecurityConfig class and define security rules for HTTP requests.

@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()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

In the above configuration, the /api/auth/** route is allowed for all requests, while other requests require authentication. The session management is set to STATLESS to utilize token-based authentication using JWT.

5. User Authentication and JWT Issuance

When a user logs in, the server issues a JWT based on the user’s information. You need to write an AuthController class for user authentication and implement a method to handle login requests.

@RestController
@RequestMapping("/api/auth")
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtProvider jwtProvider;

    @PostMapping("/login")
    public ResponseEntity authenticateUser(@RequestBody LoginRequest loginRequest) {
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));

        SecurityContextHolder.getContext().setAuthentication(authentication);

        String jwt = jwtProvider.generateToken(authentication);
        return ResponseEntity.ok(new JwtResponse(jwt));
    }
}

6. Implementing Logout

Since JWT does not store state values on the server, implementing logout works differently than other methods. Generally, logout is handled by deleting or expiring the JWT on the client side. For example, when the client sends a logout request, the JWT token is deleted, and this token is no longer used for subsequent requests.

@PostMapping("/logout")
    public ResponseEntity logoutUser() {
        // Response handling for client token deletion
        return ResponseEntity.ok(new MessageResponse("User logged out successfully!"));
    }

7. JWT Validation

To validate a JWT on the server, the signature of the token is checked, and the expiration is verified. A JwtProvider can be written for this process.

@Component
public class JwtProvider {
    @Value("${jwt.secret}")
    private String jwtSecret;

    public String generateToken(Authentication authentication) {
        return Jwts.builder()
            .setSubject(authentication.getName())
            .setIssuedAt(new Date())
            .setExpiration(new Date((new Date()).getTime() + 86400000)) // 1 day
            .signWith(SignatureAlgorithm.HS512, jwtSecret)
            .compact();
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

8. Conclusion

We have seen how to efficiently implement user authentication in Spring Boot using JWT. This token-based authentication method allows for a more flexible application structure without maintaining the server’s state. Based on the content explained in this course, I encourage you to implement a user authentication system using JWT in your projects.

In the future, we will provide you with useful information and courses on various web development topics. Thank you.

Spring Boot Backend Development Course, Implementing Login and Logout with JWT, Implementing Token API

Implementing Login/Logout with JWT and Token API

Recently, the architecture of web applications has become increasingly complex, and security issues are a significant concern for all developers. In this course, we will take a detailed look at how to implement login and logout features based on JWT (JSON Web Token) and the token API using Spring Boot. This course is targeted at developers with basic Spring Boot development experience and includes an understanding of JWT.

Table of Contents

1. What is JWT?

JWT stands for JSON Web Token, an open standard (RFC 7519) for securely transmitting user authentication information. JWT is one of the most commonly used authentication methods, used to prove that a user is logged in without the need to maintain state between the client and server. JWT consists of three parts:

  • Header: Specifies the type of token and the signing algorithm.
  • Payload: Contains user information and claims.
  • Signature: A signature created based on the header and payload.

One of the main advantages of JWT is that it allows for stateless authentication. This means that the server does not store session information, thereby reducing the server’s burden and making it easier to scale out.

2. Project Setup

Before starting the project, you need to create a Spring Boot project. You can easily set up a project using Spring Initializr. Add the following dependencies:

  • Spring Web
  • Spring Security
  • Spring Data JPA
  • H2 Database (or any database of your choice)
  • jjwt (Java JWT library)

After creating the project, add the necessary libraries to your `pom.xml`:



    
    
        io.jsonwebtoken
        jjwt
        0.9.1
    


3. User Authentication and JWT Issuance

To authenticate users, create a User entity and UserRepository. Then, set up the service layer and implement the logic to generate JWT.


// Example of User Entity
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    private String password;
    
    // getters and setters
}


// Example of UserRepository
public interface UserRepository extends JpaRepository {
    Optional findByUsername(String username);
}

Now, let’s add the functionality to create JWT:


// JwtUtil.java
@Component
public class JwtUtil {
    
    private String secretKey = "secret"; // In production, manage this in environment variables or separate files
    
    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();
    }
}

3.1 Implementing Login API

Now we will implement a Controller to handle login requests:


// AuthController.java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private UserRepository userRepository;
    
    @PostMapping("/login")
    public ResponseEntity login(@RequestBody User user) {
        authenticate(user.getUsername(), user.getPassword());
        String token = jwtUtil.generateToken(user.getUsername());
        return ResponseEntity.ok(token);
    }
    
    private void authenticate(String username, String password) {
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(username, password)
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
}

4. Token Verification and Authorization

To handle authenticated requests using JWT, you need to implement a filter to validate the token in the request header.


// JwtRequestFilter.java
@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtUtil.extractUsername(jwt);
        }

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (jwtUtil.validateToken(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                        new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        chain.doFilter(request, response);
    }
}

5. Implementing Logout Functionality

Since JWT is stateless, implementing logout functionality means that the client simply deletes the token. However, it is also possible to implement logout functionality by managing a blacklist on the server.


// Example of Logout
@PostMapping("/logout")
public ResponseEntity logout(HttpServletRequest request) {
    String token = request.getHeader("Authorization").substring(7);
    // Implement logic to add to blacklist here
    return ResponseEntity.ok("Logout successful");
}

6. API Testing

You can test the API using tools like Postman. After the login request, confirm that you can access protected resources using the JWT issued by the server.

7. Conclusion

In this course, we learned how to implement a JWT-based authentication system using Spring Boot. Depending on the system requirements, JWT can be utilized in various ways, and security should always remain a key consideration. Going forward, consider adding more advanced features to expand the system.

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

1. Introduction

Security is one of the most important factors in modern web applications. User authentication and authorization are key functions in maintaining this security.
In this course, we will take a detailed look at how to implement login and logout features using JWT (JSON Web Token) in backend development with Spring Boot.
This course covers the process of setting up a basic Spring Boot application, implementing a JWT-based authentication system, and adding a controller to complete the RESTful API.

2. What is Spring Boot?

Spring Boot is a tool that makes it easier to use the Java-based framework Spring.
This allows developers to minimize configuration and setup, enabling rapid application development.
Spring Boot can be packaged into a standalone JAR file and can efficiently develop RESTful services.
The main features of Spring Boot are as follows:

  • Auto-configuration: Spring Boot automatically configures the basic settings needed by developers.
  • Starter packages: Developers can use starter packages to quickly add the functionality they need.
  • Embedded server: Spring Boot provides embedded servers such as Tomcat, Jetty, and Undertow, making it easy to run applications.
  • Dependency management: Dependencies can be easily managed within the source code using Maven or Gradle.

3. What is JWT?

JWT (JSON Web Token) is an Internet standard RFC 7519 for secure information transmission. JWT uses a JSON object to encrypt and convey information such as subject (sub), issuer (iss), and expiration time (exp).
JWT is composed of three parts:

  1. Header: Specifies the type of JWT and the signing algorithm used.
  2. Payload: Contains the information to be transmitted and metadata describing that information.
  3. Signature: Secures the header and payload to prevent tampering. It is created using a secret key.

JWT is widely used for API authentication in high-traffic environments. It is efficient as there is no need to store sessions on the server, and it allows the client to hold state information,
reducing the load on the server.

4. Project Setup

4.1. Creating a Spring Boot Project

We use Spring Initializr to create a Spring Boot project.
Enter the necessary configurations as follows:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.6.6 (latest version)
  • Project Metadata:
    • Group: com.example
    • Artifact: jwt-demo
    • Name: jwt-demo
    • Description: JWT Authentication Demo
    • Packaging: Jar
    • Java: 11

Then, add the following dependencies:

  • Spring Web
  • Spring Security
  • Spring Data JPA
  • H2 Database
  • jjwt (Java JWT)

4.2. Project Structure

After creating the project, the basic package structure will be as follows:

    └── src
        └── main
            ├── java
            │   └── com
            │       └── example
            │           └── jwt_demo
            │               ├── JwtDemoApplication.java
            │               ├── controller
            │               ├── model
            │               ├── repository
            │               ├── security
            │               └── service
            └── resources
                ├── application.properties
                └── static
    

5. Database Configuration

We can use the H2 database to store user information.
Configure the application.properties file as follows:

    spring.h2.console.enabled=true
    spring.datasource.url=jdbc:h2:mem:testdb
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    

6. Creating a User Model

We create a User model class to hold user information.

    package com.example.jwt_demo.model;

    import javax.persistence.*;

    @Entity
    @Table(name = "users")
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;

        @Column(nullable = false, unique = true)
        private String username;

        @Column(nullable = false)
        private String password;

        // Getters and Setters...

        public User() {}

        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    }
    

7. Creating a User Repository

We create a JPA repository interface to manage user information in the database.

    package com.example.jwt_demo.repository;

    import com.example.jwt_demo.model.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;

    @Repository
    public interface UserRepository extends JpaRepository {
        User findByUsername(String username);
    }
    

8. Security Configuration

We will implement JWT authentication through Spring Security. To do this, we create a SecurityConfig class that extends WebSecurityConfigurerAdapter.

    package com.example.jwt_demo.security;

    import com.example.jwt_demo.filter.JwtRequestFilter;
    import com.example.jwt_demo.service.UserDetailsServiceImpl;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    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;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private UserDetailsServiceImpl userDetailsService;

        @Autowired
        private JwtRequestFilter jwtRequestFilter;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService);
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/authenticate").permitAll()
                .anyRequest().

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!