Files
vf_react/src/services/authService.js
2025-10-15 11:43:04 +08:00

147 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/services/authService.js
/**
* 认证服务层 - 处理所有认证相关的 API 调用
*/
const isProduction = process.env.NODE_ENV === 'production';
const API_BASE_URL = isProduction ? "" : process.env.REACT_APP_API_URL;
/**
* 统一的 API 请求处理
* @param {string} url - 请求路径
* @param {object} options - fetch 选项
* @returns {Promise} - 响应数据
*/
const apiRequest = async (url, options = {}) => {
try {
const response = await fetch(`${API_BASE_URL}${url}`, {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers,
},
credentials: 'include', // 包含 cookies
});
// 检查响应是否为 JSON
const contentType = response.headers.get('content-type');
const isJson = contentType && contentType.includes('application/json');
if (!response.ok) {
let errorMessage = `HTTP error! status: ${response.status}`;
if (isJson) {
try {
const errorData = await response.json();
errorMessage = errorData.error || errorData.message || errorMessage;
} catch (parseError) {
console.warn('Failed to parse error response as JSON');
}
}
throw new Error(errorMessage);
}
// 安全地解析 JSON 响应
if (isJson) {
try {
return await response.json();
} catch (parseError) {
console.error('Failed to parse response as JSON:', parseError);
throw new Error('服务器响应格式错误');
}
} else {
throw new Error('服务器响应不是 JSON 格式');
}
} catch (error) {
console.error(`Auth API request failed for ${url}:`, error);
// 如果是网络错误,提供更友好的提示
if (error.message === 'Failed to fetch' || error.name === 'TypeError') {
throw new Error('网络连接失败,请检查网络设置');
}
throw error;
}
};
export const authService = {
/**
* 获取微信二维码授权链接PC扫码登录
* @returns {Promise<{auth_url: string, session_id: string}>}
*/
getWechatQRCode: async () => {
return await apiRequest('/api/auth/wechat/qrcode');
},
/**
* 获取微信H5授权链接移动端网页授权
* @param {string} redirectUrl - 授权成功后的回调地址
* @returns {Promise<{auth_url: string}>}
*/
getWechatH5AuthUrl: async (redirectUrl) => {
return await apiRequest('/api/auth/wechat/h5-auth', {
method: 'POST',
body: JSON.stringify({ redirect_url: redirectUrl }),
});
},
/**
* 微信H5授权回调处理
* @param {string} code - 微信授权code
* @param {string} state - 状态参数
* @returns {Promise<{success: boolean, user?: object, token?: string}>}
*/
handleWechatH5Callback: async (code, state) => {
return await apiRequest('/api/auth/wechat/h5-callback', {
method: 'POST',
body: JSON.stringify({ code, state }),
});
},
/**
* 检查微信扫码状态
* @param {string} sessionId - 会话ID
* @returns {Promise<{status: string, user_info?: object}>}
*/
checkWechatStatus: async (sessionId) => {
return await apiRequest('/api/auth/wechat/check', {
method: 'POST',
body: JSON.stringify({ session_id: sessionId }),
});
},
/**
* 使用微信 session 登录
* @param {string} sessionId - 会话ID
* @returns {Promise<{success: boolean, user?: object, token?: string}>}
*/
loginWithWechat: async (sessionId) => {
return await apiRequest('/api/auth/login/wechat', {
method: 'POST',
body: JSON.stringify({ session_id: sessionId }),
});
},
};
/**
* 微信状态常量
*/
export const WECHAT_STATUS = {
NONE: 'none',
WAITING: 'waiting',
SCANNED: 'scanned',
AUTHORIZED: 'authorized',
LOGIN_SUCCESS: 'login_success',
REGISTER_SUCCESS: 'register_success',
EXPIRED: 'expired',
};
/**
* 状态提示信息映射
*/
export const STATUS_MESSAGES = {
[WECHAT_STATUS.WAITING]: '请使用微信扫码',
[WECHAT_STATUS.SCANNED]: '扫码成功,请在手机上确认',
[WECHAT_STATUS.AUTHORIZED]: '授权成功,正在登录...',
[WECHAT_STATUS.EXPIRED]: '二维码已过期',
};
export default authService;