Files
MoonTVPlus/src/lib/auth.ts
T
2026-01-28 18:51:17 +08:00

130 lines
3.0 KiB
TypeScript

import { NextRequest } from 'next/server';
export type AuthInfo = {
password?: string;
username?: string;
signature?: string;
timestamp?: number;
role?: 'owner' | 'admin' | 'user';
tokenId?: string;
refreshToken?: string;
refreshExpires?: number;
};
function getAuthTokenFromHeader(value: string): string {
const trimmed = value.trim();
if (!trimmed) {
return '';
}
const bearerMatch = trimmed.match(/^Bearer\s+(.+)$/i);
if (bearerMatch) {
return bearerMatch[1].trim();
}
const tokenMatch = trimmed.match(/^Token\s+(.+)$/i);
if (tokenMatch) {
return tokenMatch[1].trim();
}
return trimmed;
}
export function parseAuthInfo(value?: string | null): AuthInfo | null {
if (!value) {
return null;
}
let decoded = value;
try {
decoded = decodeURIComponent(decoded);
} catch (error) {
decoded = value;
}
if (decoded.includes('%')) {
try {
decoded = decodeURIComponent(decoded);
} catch (error) {
decoded = value;
}
}
try {
return JSON.parse(decoded) as AuthInfo;
} catch (error) {
return null;
}
}
// 从cookie获取认证信息 (服务端使用)
export function getAuthInfoFromCookie(request: NextRequest): AuthInfo | null {
const authHeader = request.headers.get('authorization');
if (authHeader) {
const headerValue = getAuthTokenFromHeader(authHeader);
const headerAuthInfo = parseAuthInfo(headerValue);
if (headerAuthInfo) {
return headerAuthInfo;
}
}
const authCookie = request.cookies.get('auth');
if (!authCookie) {
return null;
}
return parseAuthInfo(authCookie.value);
}
// 从cookie获取认证信息 (客户端使用)
export function getAuthInfoFromBrowserCookie(): AuthInfo | null {
if (typeof window === 'undefined') {
return null;
}
try {
// 解析 document.cookie
const cookies = document.cookie.split(';').reduce((acc, cookie) => {
const trimmed = cookie.trim();
const firstEqualIndex = trimmed.indexOf('=');
if (firstEqualIndex > 0) {
const key = trimmed.substring(0, firstEqualIndex);
const value = trimmed.substring(firstEqualIndex + 1);
if (key && value) {
acc[key] = value;
}
}
return acc;
}, {} as Record<string, string>);
const authCookie = cookies['auth'];
if (!authCookie) {
return null;
}
return parseAuthInfo(authCookie);
} catch (error) {
return null;
}
}
// 清除浏览器中的认证cookie (客户端使用)
export function clearAuthCookie(): void {
if (typeof window === 'undefined') {
return;
}
try {
// 清除 auth cookie,设置过期时间为过去
document.cookie = 'auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
// 如果有其他域名或路径的cookie,也尝试清除
document.cookie = 'auth=; path=/; domain=' + window.location.hostname + '; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
} catch (error) {
console.error('[Auth] Failed to clear cookie:', error);
}
}