Spring Boot Backend Development Course, What is NoSQL

In recent years, the paradigm of software development has changed significantly. Especially with the explosive increase in the amount of data, new methods of database management have become necessary. While traditional relational databases are still widely used, NoSQL databases are emerging, creating a new trend. In this article, we will explain in detail what NoSQL is in Spring Boot backend development, when it should be used, and the types and characteristics of NoSQL databases.

Concept of NoSQL

NoSQL stands for “Not Only SQL,” referring to a data storage model developed as an alternative to traditional relational database management systems (RDBMS). NoSQL supports various data models, providing the capability to flexibly store and query large amounts of unstructured or semi-structured data that relational databases find difficult to handle.

The main features of NoSQL are as follows:

  • Schema Flexibility: NoSQL databases do not have a fixed schema, allowing for easy adaptation even if the data structure changes.
  • Horizontal Scalability: As the volume of data increases, servers can be added to the cluster to scale horizontally.
  • High Availability: To maintain high availability even when failures occur, replication and distributed storage capabilities are provided.

The Need for NoSQL

The reasons for the need for NoSQL are primarily as follows.

  • Handling Large Amounts of Data: It is useful when large-scale data collection and storage are needed, such as IoT, social media, and log data.
  • Unstructured Data: While relational databases are optimized for structured data, NoSQL is suitable when it is necessary to store images, videos, and data in various formats.
  • Fast Development: It allows for quick adaptation to dynamic data structures, improving the speed of application development.

Types of NoSQL Databases

NoSQL databases can be classified into various types, each of which is suitable for specific use cases based on its characteristics.

1. Key-Value Store

A key-value store is a structure where data is stored as key-value pairs. It offers a simple structure and fast query speed, making it suitable for session management, caching, and simple data storage. Examples include Redis and DynamoDB.

2. Document Store

A document store saves data in document formats such as JSON, BSON, and XML. The schema for the data is flexible, allowing other structured data to be stored within the same document. MongoDB and CouchDB are representative examples.

3. Column-Family Store

A column-family store is optimized for handling large volumes of data by storing data in column units. By keeping frequently used columns in memory, performance can be improved. Apache Cassandra and HBase are typical examples.

4. Graph Database

A graph database stores data represented as nodes and edges. It is suitable for data models where relationships are significant and is commonly used in social network analysis. Neo4j is well known in this category.

Integration of Spring Boot and NoSQL

Spring Boot supports various Spring Data projects for integration with NoSQL databases. In this section, we will look at a simple integration example with MongoDB using Spring Boot.

1. Adding Dependencies

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    

2. MongoDB Configuration

Add the connection settings for MongoDB in the application.properties file.

        spring.data.mongodb.uri=mongodb://localhost:27017/testdb
    

3. Creating Domain Class

    import org.springframework.data.annotation.Id;
    import org.springframework.data.mongodb.core.mapping.Document;

    @Document(collection = "user")
    public class User {
        @Id
        private String id;
        private String name;
        private String email;

        // getters and setters
    }
    

4. Creating Repository

    import org.springframework.data.mongodb.repository.MongoRepository;

    public interface UserRepository extends MongoRepository<User, String> {
        User findByName(String name);
    }
    

5. Creating Service and Controller

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.List;

    @Service
    public class UserService {
        @Autowired
        private UserRepository userRepository;

        public List<User> getAllUsers() {
            return userRepository.findAll();
        }

        public User getUserByName(String name) {
            return userRepository.findByName(name);
        }
        
        public void createUser(User user) {
            userRepository.save(user);
        }
    }
    

Conclusion

NoSQL databases play an important role in modern web applications, helping developers meet various data processing requirements. By using them with Spring Boot, they offer higher productivity and flexibility, especially demonstrating their value in unstructured data environments. Through this course, I hope to summarize the essence of NoSQL and its practical use cases in Spring Boot.

Spring Boot Backend Development Course, Implementing Login and Logout with OAuth2, Implementing OAuth2 Service

In today’s lecture, we will learn in detail how to implement login and logout functionality based on OAuth2 using Spring Boot. OAuth2 is a representative authentication protocol that enables efficient and secure authentication through integration with external services. Through this article, we will explain step by step how to implement OAuth2 services in Spring Boot with practical examples.

1. What is OAuth2?

OAuth2 is a protocol that allows a third-party application to access the resources of a resource owner. This enables users to access applications without the need to share their passwords. OAuth2 has two main roles:

  • Resource Owner: Typically refers to the user, who grants permission to provide their data to a third-party service.
  • Client: The application that requests the user’s data.

1.1 Key Components of OAuth2

  • Authorization Server: The server that handles user authentication and authorization.
  • Resource Server: The server that provides protected resources (e.g., API).
  • Client Credentials: Information that identifies the application.
  • Access Token: A token representing access rights to the resource server.

2. Setting Up Spring Boot Environment

To set up OAuth2 using Spring Boot, you first need to add the required dependencies. You can use Gradle or Maven. Here, we will explain it based on Maven.

2.1 Adding Maven Dependencies

pom.xml
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
</dependencies>

2.2 Configuring application.properties

Add the basic configuration that the OAuth2 client will use in the application.properties file.

application.properties
spring.security.oauth2.client.registration.google.client-id=YOUR_CLIENT_ID
spring.security.oauth2.client.registration.google.client-secret=YOUR_CLIENT_SECRET
spring.security.oauth2.client.registration.google.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.google.scope=email,profile
spring.security.oauth2.client.provider.google.authorization-uri=https://accounts.google.com/o/oauth2/auth
spring.security.oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token
spring.security.oauth2.client.provider.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
spring.security.oauth2.client.provider.google.user-name-attribute=sub

Note: The YOUR_CLIENT_ID and YOUR_CLIENT_SECRET placeholders must be replaced with the credentials of the OAuth 2.0 client created in the Google Developer Console.

3. Implementing OAuth2 Login/Logout

Now that we have completed the basic setup for applying OAuth2, we will proceed to implement the login and logout functionalities.

3.1 Security Configuration

We configure security settings for the web application using Spring Security. Add the following code to the SecurityConfig.java class:

SecurityConfig.java
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
            .authorizeRequests()
                .antMatchers("/", "/login", "/css/**", "/js/**").permitAll()
                .anyRequest().authenticated()
            .and()
            .logout()
                .logoutSuccessUrl("/")
                .permitAll()
            .and()
            .oauth2Login();
    }
}

3.2 Implementing the Login Page

To create a login page, create a login.html file and add the following content:

login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login Page</h1>
    <a href="/oauth2/authorization/google">Login with Google</a>
</body>
</html>

3.3 Handling User Information

Let’s learn how to handle user information after login. You can retrieve user information by implementing OAuth2UserService.

CustomOAuth2UserService.java
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        // Handling user information
        // For example, saving user information to the database or adding it to the session
    }
}

4. Implementing OAuth2 Logout

The logout functionality can be easily implemented using the built-in Spring Security features. Since we have set the URL to redirect after logout success in the SecurityConfig class, you just need to add a logout button.

4.1 Adding a Logout Button

Add a logout button to the main page so that users can log out. A basic HTML code might look like this:

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home Page</title>
</head>
<body>
    <h1>Welcome!</h1>
    <a href="/logout">Logout</a>
</body>
</html>

5. Conclusion

In today’s lecture, we explored how to implement login and logout functionality through OAuth2 using Spring Boot. OAuth2 is a useful method that leverages external services to facilitate user authentication in a simpler and more secure manner. I hope this lecture helped you understand the process of setting up Spring Boot and OAuth2, and that you learned practical implementation methods.

5.1 Additional Resources

If you want more in-depth content, please refer to the resources below:

Spring Boot Backend Development Course, Configuring the Main Directory

Spring Boot is a Java-based framework that helps developers build applications easily without complex configurations. This course will cover how to structure the main directory of a Spring Boot project. This directory serves as the starting point for a Java application and is where the important business logic is implemented.

Spring Boot Project Structure

A Spring Boot project follows a predefined structure. When you create a Spring Boot project in your IDE, a basic structure like the one below is generated.

src
├── main
│   ├── java
│   │   └── com
│   │       └── example
│   │           └── demo
│   │               ├── DemoApplication.java
│   │               └── controller
│   │               └── service
│   │               └── repository
│   └── resources
│       ├── application.properties
│       └── static
│       └── templates
└── test
    └── java

1. src/main/java Directory

The src/main/java directory is where the actual Java source code is located, and each package and class file is stored here. In Spring Boot, packages are generally structured in the format of com.example.demo.

1.1 Main Application Class

The DemoApplication.java file is the entry point of the Spring Boot application. This class is annotated with @SpringBootApplication, which encompasses the following three functionalities:

  • @Configuration: A Java-based configuration class.
  • @EnableAutoConfiguration: Enables Spring Boot’s auto-configuration feature.
  • @ComponentScan: Automatically scans the specified packages to discover Spring components.

Below is an example of the main application class.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

1.2 Package Structure

When there are many source files, defining an appropriate package structure is important. Typically, packages such as controller, service, and repository are defined.

Controller Package

The controller package contains methods that handle requests and return responses. In a RESTful API, the @RestController annotation is mainly used to set up the REST API server.

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, World!";
    }
}

Service Package

The service package includes classes that handle business logic. The classes here are registered in the Spring context using the @Service annotation.

package com.example.demo.service;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    public String getGreeting() {
        return "Hello from Service!";
    }
}

Repository Package

The repository package is responsible for interacting with the database. It usually extends JpaRepository to provide CRUD functionality.

package com.example.demo.repository;

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

@Repository
public interface UserRepository extends JpaRepository {
}

2. src/main/resources Directory

The src/main/resources directory is where static files, templates, and configuration files used by the application are located. The main files and directories in this location are as follows.

2.1 application.properties

The configuration file application.properties is responsible for application environment settings. Here, you can set database configurations, port numbers, log levels, etc.

spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=password
server.port=8080
logging.level.org.springframework=DEBUG

2.2 static Directory

The static directory is where static resources like CSS, JavaScript, and image files are stored. Spring Boot automatically serves all files in this directory.

2.3 templates Directory

The templates directory is used to dynamically generate HTML files using a template engine like Thymeleaf. You can create HTML files here and inject dynamic data.





    Welcome


    

Welcome Message

3. src/test/java Directory

The src/test/java directory contains sources related to the application’s tests. Unit tests and integration tests are performed using testing frameworks like JUnit and Mockito.

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class DemoApplicationTests {
    
    @Autowired
    private HelloService helloService;

    @Test
    void contextLoads() {
        assertNotNull(helloService);
    }
}

Conclusion

In this course, we have explored in detail how to structure the main directory of a Spring Boot project. By understanding the project structure and configuring it correctly, developers can write more efficient and maintainable code. This structure will significantly aid in future maintenance and collaboration. Wishing you successful Spring Boot backend development.

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

1. Introduction

Spring Boot is a framework that helps you easily develop Java-based web applications. With the recent surge in demand for web applications, understanding security and authentication has become crucial. In this course, we will learn how to implement login and logout functionality using JSON Web Token (JWT) and how to validate JWT tokens through filters. Throughout this course, you will learn how to harness various features of Spring Boot to build a more secure and efficient backend application.

2. What is JWT?

JSON Web Token (JWT) is a JSON-based object used to securely transmit information between two entities. JWT has established itself as a standard not only for user authentication but also for claim-based information transmission. JWT consists of three components:

  • Header: Defines the type of JWT and the hashing algorithm used.
  • Payload: Contains the claim information that is being transmitted.
  • Signature: Created by combining the header and payload and using a secret key. This allows for the verification of JWT’s integrity.

3. Setting Up a Spring Boot Project

To start a Spring Boot project, you need to begin with basic settings. You can use Spring Initializr for these settings. The choices to be made when creating the project are as follows:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: Stable version (Latest)
  • Dependencies: Spring Web, Spring Security, Spring Data JPA, Spring Boot DevTools, H2 Database

Once the project is created, you can open it in your IDE and add the necessary dependencies.

4. Creating Entity Class and Repository

First, we need to define the User entity. A simple User entity is a class that stores user information. This will allow us to interact with the database.

package com.example.demo.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

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

Repositories are needed to perform CRUD operations between entities and the database.

package com.example.demo.repository;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

5. Creating Service Class

A service class is needed to handle business logic. This class implements functionalities such as user registration and login.

package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    
    public User register(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userRepository.save(user);
    }
    
    public User findUserByUsername(String username) {
        return userRepository.findByUsername(username);
    }
}

6. Security Configuration and JWT Creation

You can enhance the application’s security using Spring Security. To do this, you need to create a SecurityConfig class and add a class to generate JWT tokens.

package com.example.demo.config;

import com.example.demo.security.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.annotation.web.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

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

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

7. Implementing JWT Creation and Verification

Upon logging in, a JWT is generated based on the user’s information and sent to the client. To accomplish this, we create a JWT utility class to handle token generation and verification tasks.

package com.example.demo.security;

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

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtUtil {
    
    private final String SECRET_KEY = "secret_key";
    private final long EXPIRATION_TIME = 86400000; // 1 day

    public String generateToken(String username) {
        Map<String, Object> claims = new HashMap<>();
        return createToken(claims, username);
    }

    private String createToken(Map<String, Object> claims, String subject) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

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

    private boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    private Date extractExpiration(String token) {
        return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();
    }

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

8. Implementing Login and Logout Functionality

Now, when a user logs in, they receive a JWT, and during logout, the client deletes the token. Below is an example of the login API.

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.security.JwtUtil;
import com.example.demo.service.UserService;
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 UserService userService;

    @Autowired
    private JwtUtil jwtUtil;

    @PostMapping("/login")
    public ResponseEntity<String> login(@RequestBody User user) {
        User foundUser = userService.findUserByUsername(user.getUsername());
        if (foundUser != null && passwordEncoder.matches(user.getPassword(), foundUser.getPassword())) {
            return ResponseEntity.ok(jwtUtil.generateToken(foundUser.getUsername()));
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
    }

    @PostMapping("/logout")
    public ResponseEntity<String> logout() {
        // The logout functionality is to be implemented on the client-side.
        return ResponseEntity.ok("Successfully logged out.");
    }
}

9. Implementing JWT Filter

It is necessary to implement a JWT filter to validate JWT on all requests and handle authentication. To do this, we create the JwtAuthenticationFilter class.

package com.example.demo.security;

import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        String authorizationHeader = request.getHeader("Authorization");

        String username = null;
        String jwt = null;

        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            try {
                username = jwtUtil.extractUsername(jwt);
            } catch (ExpiredJwtException e) {
                System.out.println("JWT is expired");
            }

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

10. Conclusion

In this lecture, we learned how to implement login and logout functionality using JWT with Spring Boot. We also explored how to generate and verify JWT tokens and how to enhance application security using Spring Security. Through this course, you will have a foundation for handling authentication and authorization in backend applications more securely. Additionally, you will be able to leverage various features of Spring Boot to develop efficient and secure web applications.

11. References

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

Spring Boot is a powerful framework for modern web application development. In this course, we will explain step by step how to implement user authentication using JWT (Json Web Token) and how to achieve login and logout functionality. This process will also cover how to add token services to enhance security and user management features.

1. What is JWT?

JWT is an open standard based on JSON that provides a way to securely transmit information. A JWT consists of three parts: Header, Payload, Signature.

1.1 Header

The Header specifies the type of the JWT and the hashing algorithm. For example:

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

1.2 Payload

The Payload contains the user’s information, user ID, expiration time, etc. This part is structured in an easily readable JSON format.

1.3 Signature

The Signature is the value signed with a secret key by combining the encoded Header and Payload. This value guarantees the integrity of the token and is used by the server to validate the token.

2. Project Setup

In this tutorial, we will create a project using Spring Boot and Maven. You can set up the project using IDEs such as IntelliJ IDEA or Eclipse.

2.1 Creating a Maven Project

After creating a Maven project in Eclipse or IntelliJ IDEA, add the following dependencies to the pom.xml file.

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjsonwebtoken</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

2.2 Spring Security Configuration

Set up basic security configurations using Spring Security. Create a SecurityConfig class and add user authentication and authorization settings.

    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();
        }
    }
    

3. JWT Creation and Validation

Now we will look at how to create and validate JWTs. Create a JWTUtil class and implement the necessary methods.

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

    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;

    @Component
    public class JWTUtil {
        private String secretKey = "secret";

        public String generateToken(String username) {
            Map<String, Object> claims = new HashMap<>();
            return createToken(claims, username);
        }

        private String createToken(Map<String, Object> claims, String subject) {
            return Jwts.builder()
                    .setClaims(claims)
                    .setSubject(subject)
                    .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) && !isTokenExpired(token));
        }

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

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

        private Boolean isTokenExpired(String token) {
            return extractAllClaims(token).getExpiration().before(new Date());
        }
    }
    

4. Implementing User Authentication and Login API

Now it’s time to implement the user authentication and login API. Create an AuthController class and add the necessary methods.

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.web.bind.annotation.*;

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

        @Autowired
        private AuthenticationManager authenticationManager;

        @Autowired
        private JWTUtil jwtUtil;

        @PostMapping("/login")
        public ResponseEntity<String> login(@RequestBody AuthRequest authRequest) {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
            );
            final String token = jwtUtil.generateToken(authRequest.getUsername());
            return ResponseEntity.ok(token);
        }
    }

    class AuthRequest {
        private String username;
        private String password;

        // getters and setters
    }
    

5. Implementing Logout API

The logout API is implemented by deleting the JWT token on the client side. A separate logout API is not required, but an example can be added for this part.

6. Adding Token Service

By adding a token service, manage user information and implement functionality to manage user sessions as needed. Create a TokenService class to implement this functionality.

    import org.springframework.stereotype.Service;

    @Service
    public class TokenService {

        @Autowired
        private JWTUtil jwtUtil;

        public String refreshToken(String token) {
            if (jwtUtil.isTokenExpired(token)) {
                String username = jwtUtil.extractUsername(token);
                return jwtUtil.generateToken(username);
            }
            return token;
        }
    }
    

7. Other Considerations and Conclusion

In this course, we explored how to implement login and logout functionality using JWT and add a token service for user authentication. In real applications, additional security measures such as enhancing JWT validation, user permission management, and token storage implementation are required.

8. Conclusion

Implementing a JWT-based authentication system using Spring Boot has become an essential element in enhancing the security of modern web applications. Through this course, you should understand the basic concepts of JWT and the fundamentals of implementing an authentication system using it. Furthermore, try to gain experience in implementing and optimizing various features required for actual projects.

I hope this course helps you with your Spring Boot backend development!

© 2023 Your Blog Name. All rights reserved.