diff --git a/src/app/character-center/CharacterCenterClient.tsx b/src/app/character-center/CharacterCenterClient.tsx
index 786b795..077b45a 100644
--- a/src/app/character-center/CharacterCenterClient.tsx
+++ b/src/app/character-center/CharacterCenterClient.tsx
@@ -325,7 +325,7 @@ MOCK-RSA-KEY-FOR-DEMO-PURPOSES-ONLY
- ;
diff --git a/src/app/user-home/page.tsx b/src/app/user-home/page.tsx
index f4b2ea8..24ca9da 100644
--- a/src/app/user-home/page.tsx
+++ b/src/app/user-home/page.tsx
@@ -6,9 +6,10 @@ import Link from 'next/link';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { getSession } from 'next-auth/react';
+import { Session } from 'next-auth';
export default function UserHome() {
- const [session, setSession] = useState(null);
+ const [session, setSession] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
diff --git a/src/lib/api/actions.ts b/src/lib/api/actions.ts
index 29704e8..cbe8940 100644
--- a/src/lib/api/actions.ts
+++ b/src/lib/api/actions.ts
@@ -2,7 +2,62 @@
'use server';
import axios from 'axios';
-const API_URL = process.env.NEXT_PUBLIC_API_URL || '/api';
+// 配置axios实例,统一处理API请求
+const apiClient = axios.create({
+ baseURL: process.env.NEXT_PUBLIC_API_URL || '/api',
+ timeout: 10000, // 设置10秒超时
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+});
+
+// 添加请求拦截器处理认证
+apiClient.interceptors.request.use(
+ (config) => {
+ // 可以在这里添加认证token
+ return config;
+ },
+ (error) => {
+ return Promise.reject(error);
+ }
+);
+
+// 添加响应拦截器统一处理错误
+apiClient.interceptors.response.use(
+ (response) => response,
+ (error) => {
+ // 处理常见错误状态码
+ if (error.response) {
+ switch (error.response.status) {
+ case 401:
+ // 未授权,可能需要重新登录
+ console.error('认证失败,需要重新登录');
+ break;
+ case 403:
+ // 禁止访问
+ console.error('权限不足');
+ break;
+ case 404:
+ // 资源不存在
+ console.error('请求的资源不存在');
+ break;
+ case 500:
+ // 服务器错误
+ console.error('服务器内部错误');
+ break;
+ default:
+ console.error(`API请求错误: ${error.response.status}`);
+ }
+ } else if (error.request) {
+ // 没有收到响应
+ console.error('网络错误,无法连接到服务器');
+ } else {
+ // 请求配置错误
+ console.error('请求配置错误:', error.message);
+ }
+ return Promise.reject(error);
+ }
+);
// 导出退出登录函数 - 供服务器端使用
export const serverSignOut = async () => {
@@ -44,11 +99,24 @@ export const login = async (credentials: {
}) => {
try {
// 对于测试环境,可以直接验证测试账号
- const TEST_USERNAME = 'test';
- const TEST_PASSWORD = 'test';
- // 对于测试环境,可以直接验证测试账号 - 支持通过username或email字段登录
+ const TEST_USERNAME = process.env.TEST_USERNAME || 'test';
+ const TEST_PASSWORD = process.env.TEST_PASSWORD || 'test';
+
+ // 验证是否为空
+ if (!credentials.password) {
+ return { success: false, error: '请输入密码' };
+ }
+
+ // 获取用户名或邮箱字段
const usernameField = credentials.username || credentials.email;
- if (usernameField === TEST_USERNAME && credentials.password === TEST_PASSWORD) {
+ if (!usernameField) {
+ return { success: false, error: '请输入用户名或邮箱' };
+ }
+
+ // 支持通过username或email字段登录测试账号
+ if (process.env.NODE_ENV !== 'production' &&
+ usernameField === TEST_USERNAME &&
+ credentials.password === TEST_PASSWORD) {
return {
success: true,
user: {
@@ -61,11 +129,20 @@ export const login = async (credentials: {
}
// 实际环境中调用API
- const response = await axios.post(`${API_URL}/auth/login`, credentials);
+ const response = await apiClient.post('/auth/login', credentials);
return { success: true, ...response.data };
} catch (error) {
console.error('登录失败:', error);
- return { success: false, error: '登录失败,请检查用户名和密码' };
+ // 根据错误类型提供更具体的错误信息
+ if (error instanceof axios.AxiosError) {
+ if (error.response?.status === 401) {
+ return { success: false, error: '用户名或密码错误,请重试' };
+ }
+ if (error.request) {
+ return { success: false, error: '网络连接失败,请检查您的网络设置' };
+ }
+ }
+ return { success: false, error: '登录失败,请稍后再试' };
}
};
@@ -77,11 +154,56 @@ export const register = async (userData: {
minecraftUsername: string;
}) => {
try {
+ // 基本验证
+ if (!userData.username?.trim()) {
+ return { success: false, error: '用户名不能为空' };
+ }
+ if (!userData.password?.trim()) {
+ return { success: false, error: '密码不能为空' };
+ }
+ if (!userData.email?.trim()) {
+ return { success: false, error: '邮箱不能为空' };
+ }
+ if (!userData.minecraftUsername?.trim()) {
+ return { success: false, error: 'Minecraft用户名不能为空' };
+ }
+
+ // 密码强度检查(简单示例)
+ if (userData.password.length < 6) {
+ return { success: false, error: '密码长度至少为6位' };
+ }
+
+ // 邮箱格式检查
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+ if (!emailRegex.test(userData.email)) {
+ return { success: false, error: '请输入有效的邮箱地址' };
+ }
+
// 实际环境中调用API
- const response = await axios.post(`${API_URL}/auth/register`, userData);
+ const response = await apiClient.post('/auth/register', userData);
return { success: true, ...response.data };
} catch (error) {
console.error('注册失败:', error);
+ // 根据错误类型提供更具体的错误信息
+ if (error instanceof axios.AxiosError) {
+ if (error.response?.status === 400) {
+ // 从服务器获取具体错误信息
+ return {
+ success: false,
+ error: error.response.data?.error || '注册信息有误,请检查后重试'
+ };
+ }
+ if (error.response?.status === 409) {
+ // 冲突,可能是用户名或邮箱已存在
+ return {
+ success: false,
+ error: '用户名或邮箱已被注册'
+ };
+ }
+ if (error.request) {
+ return { success: false, error: '网络连接失败,请检查您的网络设置' };
+ }
+ }
return { success: false, error: '注册失败,请稍后再试' };
}
};
\ No newline at end of file
diff --git a/src/lib/api/auth.ts b/src/lib/api/auth.ts
index f012f4c..18a1a29 100644
--- a/src/lib/api/auth.ts
+++ b/src/lib/api/auth.ts
@@ -3,7 +3,44 @@ import NextAuth, { AuthOptions } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import axios from 'axios';
-const API_URL = process.env.NEXT_PUBLIC_API_URL || '/api';
+// 配置axios实例,与actions.ts保持一致
+const apiClient = axios.create({
+ baseURL: process.env.NEXT_PUBLIC_API_URL || '/api',
+ timeout: 10000,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+});
+
+// 添加响应拦截器,与actions.ts保持一致
+apiClient.interceptors.response.use(
+ (response) => response,
+ (error) => {
+ if (error.response) {
+ switch (error.response.status) {
+ case 401:
+ console.error('认证失败,需要重新登录');
+ break;
+ case 403:
+ console.error('权限不足');
+ break;
+ case 404:
+ console.error('请求的资源不存在');
+ break;
+ case 500:
+ console.error('服务器内部错误');
+ break;
+ default:
+ console.error(`API请求错误: ${error.response.status}`);
+ }
+ } else if (error.request) {
+ console.error('网络错误,无法连接到服务器');
+ } else {
+ console.error('请求配置错误:', error.message);
+ }
+ return Promise.reject(error);
+ }
+);
declare module "next-auth" {
interface Session {
@@ -26,14 +63,16 @@ export const authOptions: AuthOptions = {
password: { label: "密码", type: "password" }
},
async authorize(credentials) {
- // 默认测试账号 - 用于开发和测试环境
- const TEST_USERNAME = 'test';
- const TEST_PASSWORD = 'test';
+ // 测试账号配置 - 从环境变量获取
+ const TEST_USERNAME = process.env.TEST_USERNAME || 'test';
+ const TEST_PASSWORD = process.env.TEST_PASSWORD || 'test';
try {
// 检查是否是测试账号 - 支持通过username或email字段登录
const usernameField = credentials?.username || credentials?.email;
- if (usernameField === TEST_USERNAME && credentials?.password === TEST_PASSWORD) {
+ if (process.env.NODE_ENV !== 'production' &&
+ usernameField === TEST_USERNAME &&
+ credentials?.password === TEST_PASSWORD) {
// 返回模拟的测试用户数据
return {
id: 'test_user_1',
@@ -41,27 +80,42 @@ export const authOptions: AuthOptions = {
email: 'test@test.com',
minecraftUsername: 'SteveTest'
};
-
-
-
}
- // 正常的API登录流程
- const response = await axios.post(`${API_URL}/auth/login`, {
+ // 验证输入
+ if (!usernameField || !credentials?.password) {
+ console.error('用户名/邮箱和密码不能为空');
+ return null;
+ }
+
+ // 正常的API登录流程 - 使用apiClient
+ const response = await apiClient.post('/auth/login', {
username: credentials?.username,
+ email: credentials?.email,
password: credentials?.password
});
if (response.data && response.data.user) {
return {
id: response.data.user.id,
- name: response.data.user.username,
- email: response.data.user.email
+ name: response.data.user.name || response.data.user.username,
+ email: response.data.user.email,
+ minecraftUsername: response.data.user.minecraftUsername
};
}
return null;
} catch (error) {
console.error('认证失败:', error);
+ // 区分不同类型的错误,提供更好的错误反馈
+ if (error instanceof axios.AxiosError) {
+ if (error.response?.status === 401) {
+ console.error('用户名或密码错误');
+ } else if (error.response?.status === 400) {
+ console.error('登录信息不完整或格式错误');
+ } else if (!error.response) {
+ console.error('无法连接到认证服务器');
+ }
+ }
return null;
}
}