首页 > Java > java教程 > 使用 JWT 令牌和电子邮件重置密码登录系统

使用 JWT 令牌和电子邮件重置密码登录系统

Barbara Streisand
发布: 2024-11-24 22:48:13
原创
378 人浏览过

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中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板