2025-09-26 15:50:37 +08:00
|
|
|
import {Request} from "express";
|
2025-09-11 14:02:25 +08:00
|
|
|
import axios from "axios";
|
2025-09-26 15:50:37 +08:00
|
|
|
import {ApiError, ApiResponse} from "../types/api";
|
|
|
|
|
import type {UserInfo} from "../types/user";
|
|
|
|
|
|
|
|
|
|
export async function expressAuthentication(
|
|
|
|
|
request: Request,
|
|
|
|
|
securityName: string,
|
|
|
|
|
scopes?: string[]
|
|
|
|
|
): Promise<any> {
|
|
|
|
|
if (securityName === "jwt") {
|
|
|
|
|
const authHeader = request.headers.authorization;
|
|
|
|
|
const token = extractTokenFromHeader(authHeader);
|
2025-09-11 14:02:25 +08:00
|
|
|
|
2025-09-26 15:50:37 +08:00
|
|
|
if (!token) {
|
|
|
|
|
throw new ApiError(401, "Unauthorized");
|
2025-09-11 14:02:25 +08:00
|
|
|
}
|
2025-09-26 15:50:37 +08:00
|
|
|
|
|
|
|
|
// 返回的对象会挂到 request.user 上
|
|
|
|
|
return await getUserInfoByToken(token);
|
2025-09-11 14:02:25 +08:00
|
|
|
}
|
2025-09-26 15:50:37 +08:00
|
|
|
throw new ApiError(401, "Unsupported security scheme");
|
2025-09-11 14:02:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extract Bearer token from request header
|
|
|
|
|
*/
|
|
|
|
|
export const extractTokenFromHeader = (authHeader: string | undefined): string | null => {
|
|
|
|
|
if (!authHeader) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const parts = authHeader.split(" ");
|
|
|
|
|
if (parts.length !== 2 || parts[0] !== "Bearer") {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parts[1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get user information by token
|
|
|
|
|
*/
|
2025-09-26 15:50:37 +08:00
|
|
|
export const getUserInfoByToken = async (token: string): Promise<UserInfo> => {
|
2025-09-11 14:02:25 +08:00
|
|
|
try {
|
2025-09-26 15:50:37 +08:00
|
|
|
const response = await axios.post<ApiResponse<Omit<UserInfo, 'token'>>>(
|
2025-09-11 14:02:25 +08:00
|
|
|
"https://egret.byteawake.com/api/user/info",
|
|
|
|
|
{}, // 请求体数据,这里为空对象
|
|
|
|
|
{
|
|
|
|
|
headers: {
|
|
|
|
|
Authorization: `Bearer ${token}`,
|
|
|
|
|
},
|
|
|
|
|
timeout: 10000, // 10 second timeout
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2025-09-26 15:50:37 +08:00
|
|
|
if (response.data.code !== 200 || !response.data.data) {
|
|
|
|
|
throw new Error(`Failed to get user information: ${response.data.message}`);
|
2025-09-11 14:02:25 +08:00
|
|
|
}
|
2025-09-11 16:46:54 +08:00
|
|
|
|
2025-09-26 15:50:37 +08:00
|
|
|
return {...response.data.data, token};
|
2025-09-11 16:46:54 +08:00
|
|
|
} catch (error: any) {
|
|
|
|
|
if (error.response) {
|
|
|
|
|
// API returned error response
|
|
|
|
|
throw new Error(`Failed to get user information: ${error.response.status} ${error.response.statusText}`);
|
|
|
|
|
} else if (error.request) {
|
|
|
|
|
// Request was sent but no response received
|
|
|
|
|
throw new Error("Failed to get user information: timeout or network error");
|
|
|
|
|
} else {
|
|
|
|
|
// Other errors
|
|
|
|
|
throw new Error(`Failed to get user information: ${error.message}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|