feat: Web 管理后台及 e2e 测试适配 API 路径变更

- e2e-tests API 路径统一更新为 /api/admin/ 和 /api/member/ 前缀
- Gateway isPublicPath 更新为 /api/admin/auth/ 和 /api/member/auth/
- Gateway 签名白名单路径更新
- 移除已废弃的 /api/checkIn/ 和 /api/auth/login 公开路径
This commit is contained in:
张翔
2026-06-03 11:51:47 +08:00
parent 981d8ef211
commit 5237dfc1cb
11 changed files with 34 additions and 36 deletions
+7 -7
View File
@@ -5,7 +5,7 @@ test.describe('认证和授权测试', () => {
let userId: number;
test.beforeAll(async ({ request }) => {
const response = await request.post('http://localhost:8080/api/auth/login', {
const response = await request.post('http://localhost:8080/api/admin/auth/login', {
headers: {
'Content-Type': 'application/json'
},
@@ -28,7 +28,7 @@ test.describe('认证和授权测试', () => {
});
await test.step('发送登录请求', async () => {
const response = await page.request.post('http://localhost:8080/api/auth/login', {
const response = await page.request.post('http://localhost:8080/api/admin/auth/login', {
headers: {
'Content-Type': 'application/json'
},
@@ -78,7 +78,7 @@ test.describe('认证和授权测试', () => {
});
await test.step('查询指定用户信息', async () => {
const response = await page.request.get(`http://localhost:8080/api/users/${userId}`, {
const response = await page.request.get(`http://localhost:8080/api/admin/users/${userId}`, {
headers: {
'Authorization': `Bearer ${authToken}`
}
@@ -98,10 +98,10 @@ test.describe('认证和授权测试', () => {
test('权限验证测试', async ({ page }) => {
await test.step('测试访问受保护的API', async () => {
const protectedEndpoints = [
'/api/users',
'/api/roles',
'/api/menus',
'/api/config'
'/api/admin/users',
'/api/admin/roles',
'/api/admin/menus',
'/api/admin/config'
];
for (const endpoint of protectedEndpoints) {
+1 -1
View File
@@ -4,7 +4,7 @@ test.describe('参数配置功能测试', () => {
let authToken: string;
test.beforeAll(async ({ request }) => {
const response = await request.post('http://localhost:8080/api/auth/login', {
const response = await request.post('http://localhost:8080/api/admin/auth/login', {
headers: {
'Content-Type': 'application/json'
},
+1 -1
View File
@@ -4,7 +4,7 @@ test.describe('字典管理功能测试', () => {
let authToken: string;
test.beforeAll(async ({ request }) => {
const response = await request.post('http://localhost:8080/api/auth/login', {
const response = await request.post('http://localhost:8080/api/admin/auth/login', {
headers: {
'Content-Type': 'application/json'
},
+6 -6
View File
@@ -269,7 +269,7 @@ async function verifyAllServices(): Promise<void> {
console.log(' 验证网关到后端的连通性...');
try {
const response = await fetch('http://localhost:8080/api/auth/login', {
const response = await fetch('http://localhost:8080/api/admin/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'Test@123' }),
@@ -316,7 +316,7 @@ async function waitForBackendReady(): Promise<void> {
console.log(`✅ 后端服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);
try {
const loginTest = await fetch('http://localhost:8084/api/auth/login', {
const loginTest = await fetch('http://localhost:8084/api/admin/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'Test@123' }),
@@ -364,7 +364,7 @@ async function waitForGatewayReady(): Promise<void> {
console.log(`✅ 网关服务健康检查通过 (尝试 ${i + 1}/${maxRetries})`);
try {
const loginTest = await fetch('http://localhost:8080/api/auth/login', {
const loginTest = await fetch('http://localhost:8080/api/admin/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'Test@123' }),
@@ -425,7 +425,7 @@ async function waitForFrontendReady(): Promise<void> {
async function cleanupTestData(): Promise<void> {
try {
// 登录获取token(通过网关)
const loginResponse = await fetch('http://localhost:8080/api/auth/login', {
const loginResponse = await fetch('http://localhost:8080/api/admin/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -458,7 +458,7 @@ async function cleanupTestData(): Promise<void> {
for (const user of users) {
if (user.id > 10) {
try {
await fetch(`http://localhost:8080/api/users/${user.id}`, {
await fetch(`http://localhost:8080/api/admin/users/${user.id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
@@ -486,7 +486,7 @@ async function cleanupTestData(): Promise<void> {
for (const role of roles) {
if (role.id > 4) {
try {
await fetch(`http://localhost:8080/api/roles/${role.id}`, {
await fetch(`http://localhost:8080/api/admin/roles/${role.id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
@@ -50,7 +50,7 @@ test.describe('管理员完整工作流', () => {
await test.step('提交表单', async () => {
const [response] = await Promise.all([
page.waitForResponse(resp =>
resp.url().includes('/api/roles') && resp.request().method() === 'POST',
resp.url().includes('/api/admin/roles') && resp.request().method() === 'POST',
{ timeout: 10000 }
).catch(() => null),
page.locator('.el-dialog button:has-text("确定")').click()
@@ -112,7 +112,7 @@ test.describe('用户权限边界验证', () => {
});
await test.step('尝试访问受限API', async () => {
const response = await page.request.get('/api/users?page=0&size=10');
const response = await page.request.get('/api/admin/users?page=0&size=10');
expect([200, 401, 403]).toContain(response.status());
});
});
+1 -1
View File
@@ -4,7 +4,7 @@ test.describe('菜单管理功能测试', () => {
let authToken: string;
test.beforeAll(async ({ request }) => {
const response = await request.post('http://localhost:8080/api/auth/login', {
const response = await request.post('http://localhost:8080/api/admin/auth/login', {
headers: {
'Content-Type': 'application/json'
},
+10 -10
View File
@@ -10,7 +10,7 @@ export class ApiClient {
}
async login(username: string, password: string): Promise<{ token: string; userId: number }> {
const response = await this.request.post(`${this.baseURL}/api/auth/login`, {
const response = await this.request.post(`${this.baseURL}/api/admin/auth/login`, {
data: {
username,
password,
@@ -29,7 +29,7 @@ export class ApiClient {
}
async logout(token: string): Promise<void> {
await this.request.post(`${this.baseURL}/api/auth/logout`, {
await this.request.post(`${this.baseURL}/api/admin/auth/logout`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -37,7 +37,7 @@ export class ApiClient {
}
async getUsers(token: string): Promise<any[]> {
const response = await this.request.get(`${this.baseURL}/api/users`, {
const response = await this.request.get(`${this.baseURL}/api/admin/users`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -51,7 +51,7 @@ export class ApiClient {
}
async createUser(token: string, userData: any): Promise<any> {
const response = await this.request.post(`${this.baseURL}/api/users`, {
const response = await this.request.post(`${this.baseURL}/api/admin/users`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -66,7 +66,7 @@ export class ApiClient {
}
async updateUser(token: string, userId: number, userData: any): Promise<any> {
const response = await this.request.put(`${this.baseURL}/api/users/${userId}`, {
const response = await this.request.put(`${this.baseURL}/api/admin/users/${userId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -81,7 +81,7 @@ export class ApiClient {
}
async deleteUser(token: string, userId: number): Promise<void> {
const response = await this.request.delete(`${this.baseURL}/api/users/${userId}`, {
const response = await this.request.delete(`${this.baseURL}/api/admin/users/${userId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -93,7 +93,7 @@ export class ApiClient {
}
async getRoles(token: string): Promise<any[]> {
const response = await this.request.get(`${this.baseURL}/api/roles`, {
const response = await this.request.get(`${this.baseURL}/api/admin/roles`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -107,7 +107,7 @@ export class ApiClient {
}
async createRole(token: string, roleData: any): Promise<any> {
const response = await this.request.post(`${this.baseURL}/api/roles`, {
const response = await this.request.post(`${this.baseURL}/api/admin/roles`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -122,7 +122,7 @@ export class ApiClient {
}
async deleteRole(token: string, roleId: number): Promise<void> {
const response = await this.request.delete(`${this.baseURL}/api/roles/${roleId}`, {
const response = await this.request.delete(`${this.baseURL}/api/admin/roles/${roleId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
@@ -134,7 +134,7 @@ export class ApiClient {
}
async getMenus(token: string): Promise<any[]> {
const response = await this.request.get(`${this.baseURL}/api/menus`, {
const response = await this.request.get(`${this.baseURL}/api/admin/menus`, {
headers: {
Authorization: `Bearer ${token}`,
},
+4 -4
View File
@@ -55,7 +55,7 @@ export class TestDataManager {
}
static async createTestUser(request: APIRequestContext, userData: TestUser): Promise<any> {
const response = await request.post(`${this.apiBaseUrl}/api/users`, {
const response = await request.post(`${this.apiBaseUrl}/api/admin/users`, {
data: userData,
});
@@ -75,7 +75,7 @@ export class TestDataManager {
}
static async createTestRole(request: APIRequestContext, roleData: TestRole): Promise<any> {
const response = await request.post(`${this.apiBaseUrl}/api/roles`, {
const response = await request.post(`${this.apiBaseUrl}/api/admin/roles`, {
data: roleData,
});
@@ -100,7 +100,7 @@ export class TestDataManager {
return;
}
const response = await request.delete(`${this.apiBaseUrl}/api/users/${userData.id}`);
const response = await request.delete(`${this.apiBaseUrl}/api/admin/users/${userData.id}`);
if (!response.ok()) {
console.warn(`Failed to delete test user ${username}: ${await response.text()}`);
}
@@ -114,7 +114,7 @@ export class TestDataManager {
return;
}
const response = await request.delete(`${this.apiBaseUrl}/api/roles/${roleData.id}`);
const response = await request.delete(`${this.apiBaseUrl}/api/admin/roles/${roleData.id}`);
if (!response.ok()) {
console.warn(`Failed to delete test role ${roleKey}: ${await response.text()}`);
}
@@ -81,11 +81,9 @@ public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory<JwtAut
}
private boolean isPublicPath(String path) {
return path.startsWith("/api/auth/") ||
return path.startsWith("/api/admin/auth/") ||
path.equals("/actuator/health") ||
path.startsWith("/api/member/auth/") ||
path.equals("/api/auth/login") ||
path.startsWith("/api/checkIn/") ||
path.startsWith("/actuator/info");
}
@@ -64,7 +64,7 @@ signature:
max-age-minutes: ${SIGNATURE_MAX_AGE_MINUTES:5}
nonce-cache-size: ${SIGNATURE_NONCE_CACHE_SIZE:10000}
whitelist:
paths: ${SIGNATURE_WHITELIST_PATHS:/actuator/health,/actuator/info,/api/auth/login,/api/auth/register,/api/member/auth/miniapp/login,/api/member/auth/mp/callback}
paths: ${SIGNATURE_WHITELIST_PATHS:/actuator/health,/actuator/info,/api/admin/auth/login,/api/admin/auth/register,/api/member/auth/miniapp/login,/api/member/auth/mp/callback}
resilience:
enabled: ${RESILIENCE_ENABLED:true}