mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-14 08:00:45 +08:00
Merge branch 'main' into codex/add-post-module-with-attributes
This commit is contained in:
@@ -8,6 +8,7 @@ OpenIsle 是一个基于 Spring Boot 的社区后端平台示例,提供注册
|
|||||||
- **JWT 认证**:登录成功后返回 JWT,后续请求需在 `Authorization` 头中携带 `Bearer` token。
|
- **JWT 认证**:登录成功后返回 JWT,后续请求需在 `Authorization` 头中携带 `Bearer` token。
|
||||||
- **邮件通知**:示例通过 Resend API 发送欢迎邮件,可根据需要修改。
|
- **邮件通知**:示例通过 Resend API 发送欢迎邮件,可根据需要修改。
|
||||||
- **灵活配置**:数据库地址、账户密码、Resend API Key 等均可通过环境变量或 `application.properties` 配置。
|
- **灵活配置**:数据库地址、账户密码、Resend API Key 等均可通过环境变量或 `application.properties` 配置。
|
||||||
|
- **角色权限**:内置 `ADMIN` 和 `USER` 两种角色,`/api/admin/**` 接口仅管理员可访问。
|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ mvn spring-boot:run
|
|||||||
```
|
```
|
||||||
- `POST /api/auth/login`:登录,返回 `{ "token": "..." }`。
|
- `POST /api/auth/login`:登录,返回 `{ "token": "..." }`。
|
||||||
- 其他受保护接口示例:`GET /api/hello`,需在请求头加入 `Authorization: Bearer <token>`。
|
- 其他受保护接口示例:`GET /api/hello`,需在请求头加入 `Authorization: Bearer <token>`。
|
||||||
|
- 管理员接口示例:`GET /api/admin/hello`,需要具备 `ADMIN` 角色。
|
||||||
|
|
||||||
## 目录结构
|
## 目录结构
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class SecurityConfig {
|
|||||||
.<UserDetails>map(user -> org.springframework.security.core.userdetails.User
|
.<UserDetails>map(user -> org.springframework.security.core.userdetails.User
|
||||||
.withUsername(user.getUsername())
|
.withUsername(user.getUsername())
|
||||||
.password(user.getPassword())
|
.password(user.getPassword())
|
||||||
.authorities("USER")
|
.authorities(user.getRole().name())
|
||||||
.build())
|
.build())
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
|
||||||
}
|
}
|
||||||
@@ -64,6 +64,7 @@ public class SecurityConfig {
|
|||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
|
.requestMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
|
||||||
.requestMatchers(HttpMethod.GET, "/api/posts/**").permitAll()
|
.requestMatchers(HttpMethod.GET, "/api/posts/**").permitAll()
|
||||||
|
.requestMatchers("/api/admin/**").hasAuthority("ADMIN")
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
)
|
)
|
||||||
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||||
|
|||||||
16
src/main/java/com/openisle/controller/AdminController.java
Normal file
16
src/main/java/com/openisle/controller/AdminController.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package com.openisle.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple admin demo endpoint.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class AdminController {
|
||||||
|
@GetMapping("/api/admin/hello")
|
||||||
|
public Map<String, String> adminHello() {
|
||||||
|
return Map.of("message", "Hello, Admin User");
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/java/com/openisle/model/Role.java
Normal file
6
src/main/java/com/openisle/model/Role.java
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package com.openisle.model;
|
||||||
|
|
||||||
|
public enum Role {
|
||||||
|
ADMIN,
|
||||||
|
USER
|
||||||
|
}
|
||||||
@@ -5,6 +5,12 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import com.openisle.model.Role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple user entity with basic fields and a role.
|
||||||
|
*/
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@@ -28,4 +34,8 @@ public class User {
|
|||||||
private boolean verified = false;
|
private boolean verified = false;
|
||||||
|
|
||||||
private String verificationCode;
|
private String verificationCode;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Role role = Role.USER;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.openisle.service;
|
package com.openisle.service;
|
||||||
|
|
||||||
import com.openisle.model.User;
|
import com.openisle.model.User;
|
||||||
|
import com.openisle.model.Role;
|
||||||
import com.openisle.repository.UserRepository;
|
import com.openisle.repository.UserRepository;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
@@ -50,6 +51,7 @@ public class UserService {
|
|||||||
user.setUsername(username);
|
user.setUsername(username);
|
||||||
user.setEmail(email);
|
user.setEmail(email);
|
||||||
user.setPassword(passwordEncoder.encode(password));
|
user.setPassword(passwordEncoder.encode(password));
|
||||||
|
user.setRole(Role.USER);
|
||||||
user.setVerified(false);
|
user.setVerified(false);
|
||||||
user.setVerificationCode(genCode());
|
user.setVerificationCode(genCode());
|
||||||
return userRepository.save(user);
|
return userRepository.save(user);
|
||||||
|
|||||||
Reference in New Issue
Block a user