mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-10-23 08:01:23 +08:00
feat: Add xeapi crypto support
This commit is contained in:
+73
-2
@@ -23,6 +23,20 @@ const anonymous_token = fs.readFileSync(
|
||||
path.resolve(tmpPath, './anonymous_token'),
|
||||
'utf-8',
|
||||
)
|
||||
const xeapiPublicKeyPath = path.resolve(tmpPath, './xeapi_public_key')
|
||||
let xeapi_public_key = null
|
||||
const loadXeapiPublicKey = () => {
|
||||
if (!xeapi_public_key && fs.existsSync(xeapiPublicKeyPath)) {
|
||||
try {
|
||||
xeapi_public_key = JSON.parse(
|
||||
fs.readFileSync(xeapiPublicKeyPath, 'utf-8'),
|
||||
)
|
||||
} catch (error) {
|
||||
console.log('[ERR]', error)
|
||||
}
|
||||
}
|
||||
return xeapi_public_key
|
||||
}
|
||||
|
||||
// 预先绑定常用函数和常量
|
||||
const floor = Math.floor
|
||||
@@ -95,9 +109,13 @@ const userAgentMap = {
|
||||
// 预先定义常量
|
||||
const DOMAIN = APP_CONF.domain
|
||||
const API_DOMAIN = APP_CONF.apiDomain
|
||||
const XEAPI_DOMAIN = 'https://interface3.music.163.com'
|
||||
const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
|
||||
const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
|
||||
|
||||
let xeapiSessionId = ''
|
||||
let xeapiSessionKey = ''
|
||||
|
||||
// chooseUserAgent函数
|
||||
const chooseUserAgent = (crypto, uaType = 'pc') => {
|
||||
return (userAgentMap[crypto] && userAgentMap[crypto][uaType]) || ''
|
||||
@@ -216,6 +234,52 @@ const createRequest = (uri, data, options) => {
|
||||
url = (options.domain || DOMAIN) + '/api/linux/forward'
|
||||
break
|
||||
|
||||
case 'xeapi':
|
||||
const xeapiPublicKey = loadXeapiPublicKey()
|
||||
if (!xeapiPublicKey) {
|
||||
throw new Error('xeapi public key is missing')
|
||||
}
|
||||
const xeapiOs = cookie.os === 'android' ? cookie.os : 'android'
|
||||
const xeapiAppver =
|
||||
cookie.os === 'android' && cookie.appver ? cookie.appver : '9.1.65'
|
||||
const xeapiOsver =
|
||||
cookie.os === 'android' && cookie.osver ? cookie.osver : '16'
|
||||
const xeapiBuildver = cookie.buildver || now().toString().substr(0, 10)
|
||||
headers['User-Agent'] = options.ua || chooseUserAgent('api', 'android')
|
||||
headers['X-Client-Enc-State'] = 'ENCRYPTED'
|
||||
headers['x-aeapi'] = true
|
||||
headers['content-type'] =
|
||||
'application/x-www-form-urlencoded;charset=utf-8'
|
||||
headers['x-deviceid'] = cookie.deviceId
|
||||
headers['x-os'] = xeapiOs
|
||||
headers['x-osver'] = xeapiOsver
|
||||
headers['x-appver'] = xeapiAppver
|
||||
headers['x-sdeviceid'] = cookie.sDeviceId || cookie.deviceId
|
||||
headers['x-buildver'] = xeapiBuildver
|
||||
if (cookie.MUSIC_U) headers['x-music-u'] = cookie.MUSIC_U
|
||||
const xeapiCookie = {
|
||||
...cookie,
|
||||
os: xeapiOs,
|
||||
osver: xeapiOsver,
|
||||
appver: xeapiAppver,
|
||||
buildver: xeapiBuildver,
|
||||
deviceId: cookie.deviceId,
|
||||
sDeviceId: cookie.sDeviceId || cookie.deviceId,
|
||||
}
|
||||
headers['Cookie'] = cookieObjToString(xeapiCookie)
|
||||
url = (options.domain || XEAPI_DOMAIN) + '/xeapi/' + uri.substr(5)
|
||||
encryptData = encrypt.xeapi(uri, data, {
|
||||
...options,
|
||||
publicKeyState: xeapiPublicKey,
|
||||
sessionId: xeapiSessionId,
|
||||
sessionKey: xeapiSessionKey,
|
||||
appver: xeapiAppver,
|
||||
deviceId: cookie.deviceId,
|
||||
os: xeapiOs,
|
||||
uid: cookie.uid || cookie.userId || '',
|
||||
})
|
||||
break
|
||||
|
||||
case 'eapi':
|
||||
case 'api':
|
||||
// header创建
|
||||
@@ -272,7 +336,8 @@ const createRequest = (uri, data, options) => {
|
||||
|
||||
// 使用返回值加密
|
||||
const use_e_r = (crypto === 'eapi' || crypto === 'weapi') && data.e_r
|
||||
if (use_e_r) {
|
||||
const use_xeapi = crypto === 'xeapi'
|
||||
if (use_e_r || use_xeapi) {
|
||||
settings.encoding = null
|
||||
settings.responseType = 'arraybuffer'
|
||||
}
|
||||
@@ -320,7 +385,13 @@ const createRequest = (uri, data, options) => {
|
||||
)
|
||||
|
||||
try {
|
||||
if (use_e_r) {
|
||||
if (use_xeapi) {
|
||||
if (res.headers['x-encr-ssid'] && res.headers['x-encr-sskey']) {
|
||||
xeapiSessionId = res.headers['x-encr-ssid']
|
||||
xeapiSessionKey = res.headers['x-encr-sskey']
|
||||
}
|
||||
answer.body = encrypt.xeapiResDecrypt(Buffer.from(body))
|
||||
} else if (use_e_r) {
|
||||
answer.body = encrypt.eapiResDecrypt(
|
||||
body.toString('hex').toUpperCase(),
|
||||
headers['x-aeapi'],
|
||||
|
||||
Reference in New Issue
Block a user