mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-10-22 23:51:23 +08:00
refactor: 重构获取anonymous token以及xeapikey的获取
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* 凭证刷新层:把“如何获取”与“状态存放”解耦。
|
||||
*
|
||||
* - util/runtimeState.js 负责进程内状态的存取(纯内存、并发去重);
|
||||
* - 本模块负责实际的网络获取,并在成功后写入 runtimeState。
|
||||
*
|
||||
* 两者分离后,runtimeState 可被纯单测覆盖(注入 mock 刷新函数),
|
||||
* 而本模块是唯一允许 util -> module 依赖的地方。
|
||||
*/
|
||||
|
||||
const runtimeState = require('./runtimeState')
|
||||
const registerXeapiKey = require('../module/register_xeapikey')
|
||||
const { cookieToJson } = require('./index')
|
||||
|
||||
// 惰性加载 request,规避 util/request -> credentials -> request 的启动期循环依赖。
|
||||
// runtimeState 与本模块均不在 require 阶段触发网络或文件 I/O。
|
||||
let requestModule = null
|
||||
const loadRequest = () => {
|
||||
if (!requestModule) {
|
||||
requestModule = require('./request')
|
||||
}
|
||||
return requestModule
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过网络注册匿名账号,获取并写入 anonymous_token。
|
||||
* @returns {Promise<string>} 最新 token
|
||||
*/
|
||||
const refreshAnonymousToken = async () => {
|
||||
const { register_anonimous } = require('../module/register_anonimous')
|
||||
const res = await register_anonimous({}, loadRequest())
|
||||
const cookie = res && res.body ? res.body.cookie : ''
|
||||
if (!cookie) {
|
||||
throw new Error('anonymous token response missing cookie')
|
||||
}
|
||||
const cookieObj = cookieToJson(cookie)
|
||||
const token = cookieObj.MUSIC_A
|
||||
if (!token) {
|
||||
throw new Error('anonymous token response missing MUSIC_A')
|
||||
}
|
||||
runtimeState.setAnonymousToken(token)
|
||||
return token
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 xeapi public key(纯获取,不写状态——由 runtimeState 统一合并/写入)。
|
||||
*
|
||||
* 兼容 serverless:内存缺失时由调用方触发;若服务端未下发 version,
|
||||
* 沿用旧状态里的 version,避免无谓的重取判定。
|
||||
*
|
||||
* @returns {Promise<Record<string, any>>}
|
||||
*/
|
||||
const fetchXeapiPublicKey = async () => {
|
||||
const current = runtimeState.getXeapiPublicKey() || {}
|
||||
const result = await registerXeapiKey(
|
||||
{
|
||||
deviceId: global.deviceId,
|
||||
currentKeyVersion: current.version || '',
|
||||
},
|
||||
null,
|
||||
)
|
||||
const publicKey = result && result.body ? result.body : {}
|
||||
if (!publicKey.sk && !current.sk) {
|
||||
throw new Error('xeapi public key response missing sk')
|
||||
}
|
||||
if (!publicKey.version && current.version) {
|
||||
publicKey.version = current.version
|
||||
}
|
||||
return publicKey
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保 anonymous_token 可用(缺失时刷新)。
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
const ensureAnonymousToken = () =>
|
||||
runtimeState.ensureAnonymousToken(refreshAnonymousToken)
|
||||
|
||||
/**
|
||||
* 确保 xeapi public key 可用。
|
||||
*
|
||||
* @param {{ force?: boolean }} [options]
|
||||
* @returns {Promise<Record<string, any> | null>}
|
||||
*/
|
||||
const ensureXeapiPublicKey = (options = {}) =>
|
||||
runtimeState.ensureXeapiPublicKey(fetchXeapiPublicKey, options)
|
||||
|
||||
module.exports = {
|
||||
refreshAnonymousToken,
|
||||
fetchXeapiPublicKey,
|
||||
ensureAnonymousToken,
|
||||
ensureXeapiPublicKey,
|
||||
}
|
||||
Reference in New Issue
Block a user