首頁 >Java >java教程 >使用 JWT 令牌和電子郵件重設密碼登入系統

使用 JWT 令牌和電子郵件重設密碼登入系統

Barbara Streisand
Barbara Streisand原創
2024-11-24 22:48:13377瀏覽

Login system with JWT token and email reset password

介紹

Spring 登入應用程式 是一個使用 Spring Boot 建立的安全且強大的使用者管理系統。該專案演示了實現身份驗證、授權和使用者帳戶功能的現代方法。主要功能包括使用者註冊、使用 BCrypt 進行安全密碼處理、基於電子郵件的密碼重設和 JWT(JSON Web 令牌)身份驗證。該應用程式在設計時考慮到了可擴展性和可擴展性,為需要用戶管理和基於角色的存取控制的項目奠定了良好的基礎。

透過利用Spring 強大的工具,例如Spring SecuritySpring Data JPAJavaMailSender,該專案確保了安全性、可維護性和易用性方面的最佳實踐的整合。無論您是建立小型 Web 應用程式還是大型企業系統,該專案都為安全管理使用者帳戶提供了實用且結構良好的起點。


配置

Pom.xml 依賴項

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


碼頭工人

要執行 PostgreSQL 資料庫,請建立一個 docker-compose.yaml 檔案:

services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

運行:

docker compose up -d

應用程式屬性

spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key


環境屬性

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>

如何建立非對稱金鑰?

在這篇文章中查看如何產生非對稱金鑰


專案結構

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file

特徵

  • 透過電子郵件和密碼驗證進行使用者註冊
  • 使用 JWT 驗證登入
  • 透過電子郵件連結傳遞恢復密碼
  • 透過帶有臨時令牌的連結重設密碼
  • 欄位驗證與錯誤處理

程式碼

配置目錄

BCryptPasswordConfig.java

package dev.mspilari.login_app.configs;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class BCryptPasswordConfig {

    @Bean
    public BCryptPasswordEncoder bPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

程式碼分解

  1. @配置

    • 這個註解告訴 Spring 該類別包含 bean 定義。
    • 使用 @Configuration 註解的類別會在應用程式啟動期間進行處理,任何使用 @Bean 註解的方法都會將其傳回值作為託管 bean 新增至 Spring 應用程式上下文中。
  2. @Bean

    • bPasswordEncoder() 方法上的 @Bean 註解指示該方法傳回一個應在 Spring 應用程式上下文中註冊為 bean 的物件。
    • 這允許將 BCryptPasswordEncoder 物件注入到應用程式中需要的任何地方。
  3. BCryptPasswordEncoder

    • 這是 Spring Security 提供的用於編碼密碼的實用程式類別。
    • 它使用BCrypt 雜湊演算法,該演算法被認為是一種強大且安全的雜湊密碼方法。該演算法在雜湊之前會自動為密碼添加“鹽”,使其能夠抵抗字典攻擊和彩虹表攻擊。
  4. 方法 bPasswordEncoder()

    • 當 Spring 框架呼叫此方法時,它會建立 BCryptPasswordEncoder 的新實例並使其在應用程式上下文中可用。
    • 應用程式中的其他類別可以自動組裝此 Bean 以編碼或匹配密碼。

JwtConfig.java

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

程式碼分解

1.類別級註解

services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

  • 表示這是一個 Spring 配置類,其中定義了 beans(Spring 管理的元件)。
  • 這裡定義的bean將在Spring應用程式上下文中用於依賴注入。

2.從設定注入 RSA 金鑰

docker compose up -d
  • @Value 用於從應用程式的屬性檔案(例如 application.yml 或 application.properties)注入公鑰私鑰
  • 這些鍵預計在屬性中如下:
spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key


3. JWT 編碼器 Bean

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>
  • 用途:建立一個用於編碼(產生)JWT 令牌的 bean。
  • 步驟
    1. 建構 RSA 金鑰
      • RSAKey.Builder 建立公用/私人 RSA 金鑰對的 JWK(JSON Web 金鑰)表示形式。
    2. 建立 JWK 集
      • ImmutableJWKSet 將鍵儲存在集合中。 Nimbus JOSE 函式庫使用此集合來簽署令牌。
    3. NimbusJwtEncoder
      • 此編碼器使用 ImmutableJWKSet 使用私鑰對令牌進行編碼和簽署。

4. JWT 解碼器 Bean

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file
  • 用途:建立用於解碼和驗證 JWT 令牌的 bean。
  • 步驟
    1. 公鑰驗證
      • NimbusJwtDecoder.withPublicKey() 配置 RSA 公鑰。它驗證令牌的簽名。
    2. 建構解碼器
      • build() 方法建立解碼器實例。

JWT 編碼和解碼的工作原理

  1. JWT 編碼(令牌產生):

    • JwtEncoder bean 用來建立簽署的 JWT 令牌。該令牌通常包含使用者資訊(例如使用者名稱、角色等)作為聲明,並使用 RSA 私鑰進行簽署。
    • 範例:
    package dev.mspilari.login_app.configs;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    @Configuration
    public class BCryptPasswordConfig {
    
        @Bean
        public BCryptPasswordEncoder bPasswordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
    
  2. JWT 解碼(令牌驗證):

    • JwtDecoder bean 用於使用 RSA 公鑰解碼和驗證令牌。這確保了令牌:
      • 由伺服器簽發(簽章驗證)。
      • 未被竄改。
    • 範例:
    package dev.mspilari.login_app.configs;
    
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.oauth2.jwt.JwtDecoder;
    import org.springframework.security.oauth2.jwt.JwtEncoder;
    import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
    import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
    
    import com.nimbusds.jose.jwk.JWKSet;
    import com.nimbusds.jose.jwk.RSAKey;
    import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
    
    @Configuration
    public class JwtConfig {
        @Value("${jwt.public.key}")
        private RSAPublicKey publicKey;
    
        @Value("${jwt.private.key}")
        private RSAPrivateKey privateKey;
    
        @Bean
        public JwtEncoder jwtEncoder() {
            var jwk = new RSAKey.Builder(this.publicKey).privateKey(this.privateKey).build();
    
            var jwks = new ImmutableJWKSet<>(new JWKSet(jwk));
    
            return new NimbusJwtEncoder(jwks);
        }
    
        @Bean
        public JwtDecoder jwtDecoder() {
            return NimbusJwtDecoder.withPublicKey(this.publicKey).build();
        }
    }
    

SecurityConfig.java

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

1.類別級註解

services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

  • @Configuration:將此類標記為定義 bean 的 Spring 配置。
  • @EnableWebSecurity:啟用 Spring Security 的 Web 安全功能。
  • @EnableMethodSecurity:啟動方法級安全註釋,例如@PreAuthorize或@Secured。這使您可以根據角色、權限或條件控制對應用程式中特定方法的存取。

2. SecurityFilterChain Bean

docker compose up -d
  • 定義應用程式的安全過濾器鏈。過濾器鍊是套用於傳入 HTTP 請求的一系列安全過濾器。

3. CSRF 保護

spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key

  • CSRF(跨站請求偽造) 保護已停用。
    • CSRF 保護對於無狀態 API 通常是不必要的,因為令牌(如 JWT)已經提供了一種防止未經授權的請求的方法。
    • 停用它可以簡化此基於 JWT 的 API 的安全配置。

4.授權規則

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>
  • 配置哪些端點需要驗證:
    • 允許全部:
    • 對 /user/register、/user/login、/user/redeem-password 和 /user/reset-password 等端點的 POST 請求向所有人開放(無需身份驗證)。
    • 這些端點可能用於使用者註冊、登入和密碼恢復/重置,通常無需登入即可存取。
    • 驗證其他請求:
    • 所有其他端點(anyRequest)都需要驗證。

5. JWT 驗證

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file
  • 將應用程式設定為 OAuth 2.0 資源伺服器,使用 JWT 令牌驗證請求。
  • JWT 解碼器
    • JwtDecoder bean(由 JwtConfig 提供)用於驗證傳入的 JWT 令牌以請求安全端點。

這是如何運作的

  1. CSRF 已停用:由於這是一個依賴無狀態 JWT 驗證的 API,因此停用 CSRF 是常見做法。
  2. 授權規則
    • 未經身份驗證的使用者只能存取明確允許的端點(例如 /user/register 或 /user/login)。
    • 任何其他請求都需要有效的 JWT 令牌。
  3. JWT 驗證
    • Spring Security 會自動從傳入請求中擷取授權標頭。
    • 如果標頭包含有效的 JWT 令牌,則請求將通過身份驗證,並建立使用者上下文。
    • 如果令牌無效或遺失,請求將被拒絕。

網域目錄

電子郵件目錄

服務目錄
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


使用者目錄

控制器目錄
services:
  postgres:
    image: postgres:latest
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_DB=database
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:


DTO目錄

UserDto.java

docker compose up -d

UserRedeemPasswordDto.java

spring.application.name=login_app

spring.datasource.url=jdbc:postgresql://localhost:5432/database
spring.datasource.username=admin
spring.datasource.password=admin

spring.mail.host=sandbox.smtp.mailtrap.io
spring.mail.port=2525


spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.default-encoding=UTF-8


spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.config.import=classpath:env.properties

jwt.public.key=classpath:public.key
jwt.private.key=classpath:private.key


UserResetPasswordDto.java

spring.mail.username=<Get in your mailtrap account>
spring.mail.password=<Get in your mailtrap account>

實體目錄

UserEntity.java

login_app/
├── .mvn/                       # Maven folder (Maven configurations)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── dev/
│   │   │       └── mspilari/
│   │   │           └── login_app/
│   │   │               ├── configs/           # Security, authentication, and other configurations
│   │   │               ├── domains/           # Main application domains
│   │   │               │   ├── email/         # Email-related logic
│   │   │               │   └── user/          # User-related logic
│   │   │               ├── exceptions/        # Custom exceptions and error handling
│   │   │               └── utils/             # Utilities and helpers
│   │   └── resources/                         # Resources (e.g., configuration files)
│   └── test/                                  # Application tests
├── target/                                    # Build folder generated by Maven
├── .gitattributes                             # Git attributes configuration
├── .gitignore                                 # Git ignore file
├── docker-compose.yaml                        # Docker Compose configuration
├── HELP.md                                    # Project help documentation
├── mvnw                                       # Maven Wrapper script for Linux
├── mvnw.cmd                                   # Maven Wrapper script for Windows
└── pom.xml                                    # Maven configuration file

列舉目錄

角色.java

package dev.mspilari.login_app.configs;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class BCryptPasswordConfig {

    @Bean
    public BCryptPasswordEncoder bPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}


儲存庫目錄

UserRepository.java

package dev.mspilari.login_app.configs;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;

@Configuration
public class JwtConfig {
    @Value("${jwt.public.key}")
    private RSAPublicKey publicKey;

    @Value("${jwt.private.key}")
    private RSAPrivateKey privateKey;

    @Bean
    public JwtEncoder jwtEncoder() {
        var jwk = new RSAKey.Builder(this.publicKey).privateKey(this.privateKey).build();

        var jwks = new ImmutableJWKSet<>(new JWKSet(jwk));

        return new NimbusJwtEncoder(jwks);
    }

    @Bean
    public JwtDecoder jwtDecoder() {
        return NimbusJwtDecoder.withPublicKey(this.publicKey).build();
    }
}

服務目錄

UserService.java

@Configuration

例外目錄

GlobalException.java

@Value("${jwt.public.key}")
private RSAPublicKey publicKey;

@Value("${jwt.private.key}")
private RSAPrivateKey privateKey;

實用工具目錄

JwtActions.java

  jwt.public.key=<your-public-key>
  jwt.private.key=<your-private-key>

結論

在這個專案中,我們使用 Spring Boot 成功實現了一個安全且功能豐富的使用者驗證系統。除了用戶註冊、登入和基於 JWT 的身份驗證等核心功能之外,該應用程式還包含密碼恢復系統。使用者可以透過電子郵件連結重設密碼,確保恢復過程順利且安全。

為了促進基於電子郵件的密碼恢復,我們將 Spring EmailMailtrap 集成,這是一種安全高效的電子郵件測試服務。這允許應用程式發送帶有臨時令牌的密碼重置鏈接,同時確保電子郵件安全地發送並在受控環境中進行測試。此設定示範如何處理密碼復原等敏感工作流程,而不會讓真實使用者在開發和測試期間面臨潛在問題。

安全身份驗證實踐、強大的密碼管理和無縫電子郵件整合的結合使該應用程式成為任何現代 Web 系統的可靠基礎。開發人員可以調整這些實踐以滿足他們的特定要求,確保可擴展性和使用者信任。透過利用 Spring Security 和 Mailtrap 等最佳實踐和工具,我們示範如何輕鬆建立安全性、以使用者為中心的應用程式。


?參考

  • 春季安全
  • 郵件陷阱
  • 春季電子郵件

?專案庫

  • Github 上的專案儲存庫

?跟我說話

  • 領英
  • Github
  • 投資組合

以上是使用 JWT 令牌和電子郵件重設密碼登入系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn