Files
egret-app-template/packages/server/src/middleware/auth.ts

78 lines
2.1 KiB
TypeScript
Raw Normal View History

import {Request} from "express";
import axios from "axios";
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);
if (!token) {
throw new ApiError(401, "Unauthorized");
}
// 返回的对象会挂到 request.user 上
return await getUserInfoByToken(token);
}
throw new ApiError(401, "Unsupported security scheme");
}
/**
* 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
*/
export const getUserInfoByToken = async (token: string): Promise<UserInfo> => {
try {
const response = await axios.post<ApiResponse<Omit<UserInfo, 'token'>>>(
"https://egret.byteawake.com/api/user/info",
{}, // 请求体数据,这里为空对象
{
headers: {
Authorization: `Bearer ${token}`,
},
timeout: 10000, // 10 second timeout
}
);
if (response.data.code !== 200 || !response.data.data) {
2025-09-26 17:25:43 +08:00
throw new Error(response.data.message);
}
return {...response.data.data, token};
} catch (error: any) {
if (error.response) {
// API returned error response
2025-09-26 17:25:43 +08:00
throw new ApiError(401, `Failed to get user information: ${error.response.status} ${error.response.statusText}`);
} else if (error.request) {
// Request was sent but no response received
2025-09-26 17:25:43 +08:00
throw new ApiError(401, "Failed to get user information: timeout or network error");
} else {
// Other errors
2025-09-26 17:25:43 +08:00
throw new ApiError(401, `Failed to get user information: ${error.message}`);
}
}
};