Spring 登入應用程式 是一個使用 Spring Boot 建立的安全且強大的使用者管理系統。該專案演示了實現身份驗證、授權和使用者帳戶功能的現代方法。主要功能包括使用者註冊、使用 BCrypt 進行安全密碼處理、基於電子郵件的密碼重設和 JWT(JSON Web 令牌)身份驗證。該應用程式在設計時考慮到了可擴展性和可擴展性,為需要用戶管理和基於角色的存取控制的項目奠定了良好的基礎。
透過利用Spring 強大的工具,例如Spring Security、Spring Data JPA 和JavaMailSender,該專案確保了安全性、可維護性和易用性方面的最佳實踐的整合。無論您是建立小型 Web 應用程式還是大型企業系統,該專案都為安全管理使用者帳戶提供了實用且結構良好的起點。
<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
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(); } }
@配置
@Bean
BCryptPasswordEncoder
方法 bPasswordEncoder()
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>
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 編碼(令牌產生):
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(); } }
JWT 解碼(令牌驗證):
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>
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
<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:
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 Email 與 Mailtrap 集成,這是一種安全高效的電子郵件測試服務。這允許應用程式發送帶有臨時令牌的密碼重置鏈接,同時確保電子郵件安全地發送並在受控環境中進行測試。此設定示範如何處理密碼復原等敏感工作流程,而不會讓真實使用者在開發和測試期間面臨潛在問題。
安全身份驗證實踐、強大的密碼管理和無縫電子郵件整合的結合使該應用程式成為任何現代 Web 系統的可靠基礎。開發人員可以調整這些實踐以滿足他們的特定要求,確保可擴展性和使用者信任。透過利用 Spring Security 和 Mailtrap 等最佳實踐和工具,我們示範如何輕鬆建立安全性、以使用者為中心的應用程式。
以上是使用 JWT 令牌和電子郵件重設密碼登入系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!