搜索
首页Javajava教程使用 JWT 令牌和电子邮件重置密码登录系统

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>
</get></get>

如何创建非对称密钥?

在这篇文章中查看如何生成非对称密钥


项目结构

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>
</get></get>
  • 用途:创建一个用于编码(生成)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>
</get></get>
  • 配置哪些端点需要身份验证:
    • 允许全部:
    • 对 /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>
</get></get>

实体目录

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>
</your-private-key></your-public-key>

结论

在这个项目中,我们使用 Spring Boot 成功实现了一个安全且功能丰富的用户身份验证系统。除了用户注册、登录和基于 JWT 的身份验证等核心功能之外,该应用程序还包含密码恢复系统。用户可以通过电子邮件链接重置密码,确保恢复过程顺利、安全。

为了促进基于电子邮件的密码恢复,我们将 Spring EmailMailtrap 集成,这是一种安全高效的电子邮件测试服务。这允许应用程序发送带有临时令牌的密码重置链接,同时确保电子邮件安全发送并在受控环境中进行测试。此设置演示了如何处理密码恢复等敏感工作流程,而不会让真实用户在开发和测试期间面临潜在问题。

安全身份验证实践、强大的密码管理和无缝电子邮件集成的结合使该应用程序成为任何现代 Web 系统的可靠基础。开发人员可以调整这些实践以满足他们的特定要求,确保可扩展性和用户信任。通过利用 Spring Security 和 Mailtrap 等最佳实践和工具,我们演示了如何轻松构建安全、以用户为中心的应用程序。


?参考

  • 春季安全
  • 邮件陷阱
  • 春季电子邮件

?项目库

  • Github 上的项目存储库

?跟我说话

  • 领英
  • Github
  • 投资组合

以上是使用 JWT 令牌和电子邮件重置密码登录系统的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JVM如何促进Java的'写作一次,在任何地方运行”(WORA)功能?JVM如何促进Java的'写作一次,在任何地方运行”(WORA)功能?May 02, 2025 am 12:25 AM

JVM通过字节码解释、平台无关的API和动态类加载实现Java的WORA特性:1.字节码被解释为机器码,确保跨平台运行;2.标准API抽象操作系统差异;3.类在运行时动态加载,保证一致性。

Java的较新版本如何解决平台特定问题?Java的较新版本如何解决平台特定问题?May 02, 2025 am 12:18 AM

Java的最新版本通过JVM优化、标准库改进和第三方库支持有效解决平台特定问题。1)JVM优化,如Java11的ZGC提升了垃圾回收性能。2)标准库改进,如Java9的模块系统减少平台相关问题。3)第三方库提供平台优化版本,如OpenCV。

说明JVM执行的字节码验证的过程。说明JVM执行的字节码验证的过程。May 02, 2025 am 12:18 AM

JVM的字节码验证过程包括四个关键步骤:1)检查类文件格式是否符合规范,2)验证字节码指令的有效性和正确性,3)进行数据流分析确保类型安全,4)平衡验证的彻底性与性能。通过这些步骤,JVM确保只有安全、正确的字节码被执行,从而保护程序的完整性和安全性。

平台独立性如何简化Java应用程序的部署?平台独立性如何简化Java应用程序的部署?May 02, 2025 am 12:15 AM

Java'splatFormIndepentEncealLowsApplicationStorunonAnyOperatingsystemwithajvm.1)singleCodeBase:writeandeandcompileonceforallplatforms.2)easileupdates:updatebybytecodeforsimultaneDeployment.3)testOnOneOnePlatForforuluniverSalpeforuluniverSaliver.4444.4444

Java的平台独立性如何随着时间的流逝而发展?Java的平台独立性如何随着时间的流逝而发展?May 02, 2025 am 12:12 AM

Java的平台独立性通过JVM、JIT编译、标准化、泛型、lambda表达式和ProjectPanama等技术不断增强。自1990年代以来,Java从基本的JVM演进到高性能的现代JVM,确保了代码在不同平台的一致性和高效性。

在Java应用程序中缓解平台特定问题的策略是什么?在Java应用程序中缓解平台特定问题的策略是什么?May 01, 2025 am 12:20 AM

Java如何缓解平台特定的问题?Java通过JVM和标准库来实现平台无关性。1)使用字节码和JVM抽象操作系统差异;2)标准库提供跨平台API,如Paths类处理文件路径,Charset类处理字符编码;3)实际项目中使用配置文件和多平台测试来优化和调试。

Java的平台独立性与微服务体系结构之间有什么关系?Java的平台独立性与微服务体系结构之间有什么关系?May 01, 2025 am 12:16 AM

java'splatformentenceenhancesenhancesmicroservicesharchitecture byferingDeploymentFlexible,一致性,可伸缩性和便携性。1)DeploymentFlexibilityAllowsibilityAllowsOllowsOllowSorlowsOllowsOllowsOllowSeStorunonAnyPlatformwithajvM.2)penterencyCrossServAccAcrossServAcrossServiCessImplifififiesDeevelopmentandeDe

GRAALVM与Java的平台独立目标有何关系?GRAALVM与Java的平台独立目标有何关系?May 01, 2025 am 12:14 AM

GraalVM通过三种方式增强了Java的平台独立性:1.跨语言互操作,允许Java与其他语言无缝互操作;2.独立的运行时环境,通过GraalVMNativeImage将Java程序编译成本地可执行文件;3.性能优化,Graal编译器生成高效的机器码,提升Java程序的性能和一致性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器