增加自定义X-Emby-Authorization

This commit is contained in:
mtvpls
2026-06-24 11:58:21 +08:00
parent 6362c8f251
commit 5625dd204c
6 changed files with 41 additions and 2 deletions
+26
View File
@@ -5278,6 +5278,7 @@ const EmbyConfigComponent = ({
transcodeMp4: false, transcodeMp4: false,
proxyPlay: false, proxyPlay: false,
customUserAgent: '', customUserAgent: '',
embyAuthorizationHeader: '',
}); });
const [authMode, setAuthMode] = useState<'apikey' | 'password'>('apikey'); const [authMode, setAuthMode] = useState<'apikey' | 'password'>('apikey');
@@ -5297,6 +5298,7 @@ const EmbyConfigComponent = ({
Username: config.EmbyConfig.Username, Username: config.EmbyConfig.Username,
Password: config.EmbyConfig.Password, Password: config.EmbyConfig.Password,
UserId: config.EmbyConfig.UserId, UserId: config.EmbyConfig.UserId,
embyAuthorizationHeader: config.EmbyConfig.embyAuthorizationHeader,
isDefault: true, isDefault: true,
}, },
]); ]);
@@ -5321,6 +5323,7 @@ const EmbyConfigComponent = ({
transcodeMp4: false, transcodeMp4: false,
proxyPlay: false, proxyPlay: false,
customUserAgent: '', customUserAgent: '',
embyAuthorizationHeader: '',
}); });
setAuthMode('apikey'); setAuthMode('apikey');
setEditingSource(null); setEditingSource(null);
@@ -5499,6 +5502,7 @@ const EmbyConfigComponent = ({
ApiKey: source.ApiKey, ApiKey: source.ApiKey,
Username: source.Username, Username: source.Username,
Password: source.Password, Password: source.Password,
embyAuthorizationHeader: source.embyAuthorizationHeader,
}), }),
}); });
@@ -6225,6 +6229,28 @@ const EmbyConfigComponent = ({
User-Agent使UA User-Agent使UA
</p> </p>
</div> </div>
{/* 自定义 X-Emby-Authorization */}
<div className='mb-3'>
<label className='block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2'>
X-Emby-Authorization
</label>
<input
type='text'
value={formData.embyAuthorizationHeader || ''}
onChange={(e) =>
setFormData({
...formData,
embyAuthorizationHeader: e.target.value,
})
}
placeholder='留空使用默认 moontvplus 认证头'
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white text-sm'
/>
<p className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
MediaBrowser Client=&quot;moontvplus&quot;, Device=&quot;Web&quot;, DeviceId=&quot;moontvplus-web&quot;, Version=&quot;1.0.0&quot;
</p>
</div>
</div> </div>
{/* 操作按钮 */} {/* 操作按钮 */}
+2 -1
View File
@@ -27,7 +27,7 @@ export async function POST(request: NextRequest) {
try { try {
const body = await request.json(); const body = await request.json();
const { action, ServerURL, ApiKey, Username, Password } = body; const { action, ServerURL, ApiKey, Username, Password, embyAuthorizationHeader } = body;
const authInfo = getAuthInfoFromCookie(request); const authInfo = getAuthInfoFromCookie(request);
if (!authInfo || !authInfo.username) { if (!authInfo || !authInfo.username) {
@@ -64,6 +64,7 @@ export async function POST(request: NextRequest) {
ApiKey, ApiKey,
Username, Username,
Password, Password,
embyAuthorizationHeader,
}; };
const client = new EmbyClient(testConfig); const client = new EmbyClient(testConfig);
+2
View File
@@ -262,6 +262,7 @@ export interface AdminConfig {
transcodeMp4?: boolean; // 转码mp4 transcodeMp4?: boolean; // 转码mp4
proxyPlay?: boolean; // 视频播放代理开关 proxyPlay?: boolean; // 视频播放代理开关
customUserAgent?: string; // 自定义User-Agent customUserAgent?: string; // 自定义User-Agent
embyAuthorizationHeader?: string; // 自定义 X-Emby-Authorization 请求头
}>; }>;
// 旧格式:单源配置(向后兼容) // 旧格式:单源配置(向后兼容)
Enabled?: boolean; Enabled?: boolean;
@@ -272,6 +273,7 @@ export interface AdminConfig {
UserId?: string; UserId?: string;
AuthToken?: string; AuthToken?: string;
Libraries?: string[]; Libraries?: string[];
embyAuthorizationHeader?: string;
LastSyncTime?: number; LastSyncTime?: number;
ItemCount?: number; ItemCount?: number;
}; };
+1
View File
@@ -707,6 +707,7 @@ export function configSelfCheck(adminConfig: AdminConfig): AdminConfig {
UserId: oldConfig.UserId, UserId: oldConfig.UserId,
AuthToken: oldConfig.AuthToken, AuthToken: oldConfig.AuthToken,
Libraries: oldConfig.Libraries, Libraries: oldConfig.Libraries,
embyAuthorizationHeader: oldConfig.embyAuthorizationHeader,
LastSyncTime: oldConfig.LastSyncTime, LastSyncTime: oldConfig.LastSyncTime,
ItemCount: oldConfig.ItemCount, ItemCount: oldConfig.ItemCount,
isDefault: true, isDefault: true,
+4
View File
@@ -23,6 +23,8 @@ interface EmbySourceConfig {
appendMediaSourceId?: boolean; appendMediaSourceId?: boolean;
transcodeMp4?: boolean; transcodeMp4?: boolean;
proxyPlay?: boolean; // 视频播放代理开关 proxyPlay?: boolean; // 视频播放代理开关
customUserAgent?: string; // 自定义User-Agent
embyAuthorizationHeader?: string; // 自定义 X-Emby-Authorization 请求头
} }
class EmbyManager { class EmbyManager {
@@ -62,6 +64,7 @@ class EmbyManager {
UserId: config.EmbyConfig.UserId, UserId: config.EmbyConfig.UserId,
AuthToken: config.EmbyConfig.AuthToken, AuthToken: config.EmbyConfig.AuthToken,
Libraries: config.EmbyConfig.Libraries, Libraries: config.EmbyConfig.Libraries,
embyAuthorizationHeader: config.EmbyConfig.embyAuthorizationHeader,
LastSyncTime: config.EmbyConfig.LastSyncTime, LastSyncTime: config.EmbyConfig.LastSyncTime,
ItemCount: config.EmbyConfig.ItemCount, ItemCount: config.EmbyConfig.ItemCount,
isDefault: true, isDefault: true,
@@ -176,6 +179,7 @@ export function migrateEmbyConfig(config: AdminConfig): AdminConfig {
UserId: oldConfig.UserId, UserId: oldConfig.UserId,
AuthToken: oldConfig.AuthToken, AuthToken: oldConfig.AuthToken,
Libraries: oldConfig.Libraries, Libraries: oldConfig.Libraries,
embyAuthorizationHeader: oldConfig.embyAuthorizationHeader,
LastSyncTime: oldConfig.LastSyncTime, LastSyncTime: oldConfig.LastSyncTime,
ItemCount: oldConfig.ItemCount, ItemCount: oldConfig.ItemCount,
isDefault: true, isDefault: true,
+6 -1
View File
@@ -13,6 +13,7 @@ interface EmbyConfig {
transcodeMp4?: boolean; transcodeMp4?: boolean;
proxyPlay?: boolean; // 视频播放代理开关 proxyPlay?: boolean; // 视频播放代理开关
customUserAgent?: string; // 自定义User-Agent customUserAgent?: string; // 自定义User-Agent
embyAuthorizationHeader?: string; // 自定义 X-Emby-Authorization 请求头
key?: string; // Emby源的唯一标识 key?: string; // Emby源的唯一标识
} }
@@ -77,6 +78,8 @@ interface EmbyView {
CollectionType?: string; CollectionType?: string;
} }
const DEFAULT_EMBY_AUTHORIZATION_HEADER = 'MediaBrowser Client="moontvplus", Device="Web", DeviceId="moontvplus-web", Version="1.0.0"';
export class EmbyClient { export class EmbyClient {
private serverUrl: string; private serverUrl: string;
private apiKey?: string; private apiKey?: string;
@@ -90,6 +93,7 @@ export class EmbyClient {
private proxyPlay: boolean; private proxyPlay: boolean;
private embyKey?: string; private embyKey?: string;
private customUserAgent: string; private customUserAgent: string;
private embyAuthorizationHeader: string;
constructor(config: EmbyConfig) { constructor(config: EmbyConfig) {
let serverUrl = config.ServerURL.replace(/\/$/, ''); let serverUrl = config.ServerURL.replace(/\/$/, '');
@@ -102,6 +106,7 @@ export class EmbyClient {
this.embyKey = config.key; this.embyKey = config.key;
// 设置自定义UA,如果没有设置则使用默认浏览器UA // 设置自定义UA,如果没有设置则使用默认浏览器UA
this.customUserAgent = config.customUserAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; this.customUserAgent = config.customUserAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
this.embyAuthorizationHeader = config.embyAuthorizationHeader?.trim() || DEFAULT_EMBY_AUTHORIZATION_HEADER;
// 如果 URL 不包含 /emby 路径,自动添加(除非启用了 removeEmbyPrefix // 如果 URL 不包含 /emby 路径,自动添加(除非启用了 removeEmbyPrefix
if (!serverUrl.endsWith('/emby') && !this.removeEmbyPrefix) { if (!serverUrl.endsWith('/emby') && !this.removeEmbyPrefix) {
@@ -167,7 +172,7 @@ export class EmbyClient {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Emby-Authorization': 'MediaBrowser Client="LunaTV", Device="Web", DeviceId="lunatv-web", Version="1.0.0"', 'X-Emby-Authorization': this.embyAuthorizationHeader,
'User-Agent': this.customUserAgent, 'User-Agent': this.customUserAgent,
}, },
body: body, body: body,