ホームページ Java &#&チュートリアル JWT トークンと電子メール リセット パスワードを使用したログイン システム

JWT トークンと電子メール リセット パスワードを使用したログイン システム

Nov 24, 2024 pm 10:48 PM

Login system with JWT token and email reset password

導入

Spring ログイン アプリケーション は、Spring Boot を使用して構築された安全で堅牢なユーザー管理システムです。このプロジェクトでは、認証、認可、およびユーザー アカウント機能を実装するための最新のアプローチを示します。主な機能には、ユーザー登録、BCrypt による安全なパスワード処理、電子メールベースのパスワード リセット、JWT (JSON Web Token) 認証などがあります。拡張性とスケーラビリティを念頭に置いて設計されたこのアプリケーションは、ユーザー管理とロールベースのアクセス制御を必要とするプロジェクトの優れた基盤として機能します。

Spring SecuritySpring Data JPAJavaMailSender などの Spring の強力なツールを活用することで、このプロジェクトはセキュリティ、保守性、容易さのベスト プラクティスを保証します。統合の。小規模な 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. @構成

    • このアノテーションは、クラスに Bean 定義が含まれていることを Spring に伝えます。
    • @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:

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • これは、Bean (Spring 管理コンポーネント) が定義されている 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 Key) 表現を作成します。
    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 (クロスサイト リクエスト フォージェリ) 保護が無効になっています。
    • トークン (JWT など) はすでに不正なリクエストを防ぐ方法を提供しているため、CSRF 保護はステートレス API には不要であることがよくあります。
    • これを無効にすると、この 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
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • JWT トークンを使用してリクエストを検証する OAuth 2.0 リソース サーバー としてアプリケーションを構成します。
  • JWT デコーダー:
    • JwtDecoder Bean (JwtConfig によって提供される) は、セキュリティで保護されたエンドポイントへのリクエストの受信 JWT トークンを検証するために使用されます。

仕組み

  1. CSRF の無効化: これはステートレス JWT 認証に依存する API であるため、CSRF を無効にするのが一般的です。
  2. 認可ルール:
    • 認証されていないユーザーは、明示的に許可されたエンドポイント (/user/register または /user/login など) にのみアクセスできます。
    • その他のリクエストには有効な JWT トークンが必要です。
  3. JWT 検証:
    • Spring Security は、受信リクエストから Authorization ヘッダーを自動的に抽出します。
    • ヘッダーに有効な 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
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

列挙型ディレクトリ

Role.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 Email を安全で効率的な電子メール テスト サービスである Mailtrap と統合しました。これにより、アプリケーションは、電子メールが安全に送信され、制御された環境でテストされることを保証しながら、一時トークンを含むパスワード リセット リンクを送信できるようになります。この設定では、開発やテスト中に実際のユーザーを潜在的な問題にさらすことなく、パスワード回復などの機密性の高いワークフローを処理する方法を示します。

安全な認証方法、堅牢なパスワード管理、シームレスな電子メール統合の組み合わせにより、このアプリケーションは最新の Web システムにとって信頼できる基盤となります。開発者は、これらのプラクティスを特定の要件に合わせて調整し、スケーラビリティとユーザーの信頼の両方を確保できます。 Spring Security や Mailtrap などのベスト プラクティスとツールを活用することで、安全でユーザー重視のアプリケーションを簡単に構築する方法を実証しました。


?参照

  • スプリングセキュリティ
  • メールトラップ
  • 春のメール

?プロジェクトリポジトリ

  • Github 上のプロジェクト リポジトリ

?私に話して

  • リンクトイン
  • Github
  • ポートフォリオ

以上がJWT トークンと電子メール リセット パスワードを使用したログイン システムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? 会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? Apr 19, 2025 pm 04:51 PM

一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? 名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? Apr 19, 2025 pm 11:30 PM

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? Apr 19, 2025 pm 06:21 PM

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? Apr 19, 2025 pm 11:42 PM

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Apr 19, 2025 pm 11:45 PM

intellijideaultimatiateバージョンを使用してスプリングを開始します...

Javaオブジェクトを配列に安全に変換する方法は? Javaオブジェクトを配列に安全に変換する方法は? Apr 19, 2025 pm 11:33 PM

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? Apr 19, 2025 pm 11:27 PM

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Apr 19, 2025 pm 11:36 PM

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

See all articles