mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-06-13 18:55:07 +00:00
feat: 为xeapi重构相关接口以优化密钥获取流程
This commit is contained in:
parent
c92613b19e
commit
50cc26f297
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
## 项目简介
|
## 项目简介
|
||||||
|
|
||||||
网易云音乐第三方 Node.js API, 支持丰富的音乐相关接口,适合自建服务、二次开发和多平台部署(如果原版诈尸, 我会及时同步 or 归档)。
|
网易云音乐第三方 Node.js API, 支持丰富的音乐相关接口,适合自建服务、二次开发和多平台部署
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
>
|
>
|
||||||
@ -215,7 +215,7 @@ pnpm test
|
|||||||
|
|
||||||
原作者 [Binaryify/NeteaseCloudMusicApi](https://github.com/binaryify/NeteaseCloudMusicApi) 项目为本项目基础 (该项目在`npmjs`网站上仍持续维护, 但 github 仓库已不再更新)
|
原作者 [Binaryify/NeteaseCloudMusicApi](https://github.com/binaryify/NeteaseCloudMusicApi) 项目为本项目基础 (该项目在`npmjs`网站上仍持续维护, 但 github 仓库已不再更新)
|
||||||
|
|
||||||
感谢大佬们为逆向eapi, weapi等加密算法所做的贡献
|
感谢大佬们为逆向eapi, weapi, xeapi等加密算法所做的贡献
|
||||||
|
|
||||||
项目参考:
|
项目参考:
|
||||||
|
|
||||||
|
|||||||
74
module/register_xeapikey.js
Normal file
74
module/register_xeapikey.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
const { default: axios } = require('axios')
|
||||||
|
const encrypt = require('../util/crypto')
|
||||||
|
const { APP_CONF } = require('../util/config.json')
|
||||||
|
|
||||||
|
const generateNonce = () => {
|
||||||
|
let nonce = ''
|
||||||
|
for (let i = 0; i < 16; i++) {
|
||||||
|
nonce += Math.floor(Math.random() * 10).toString()
|
||||||
|
}
|
||||||
|
return nonce
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = async (query, request) => {
|
||||||
|
const nonce = generateNonce()
|
||||||
|
const timestamp = String(Date.now())
|
||||||
|
const deviceId = query.deviceId || global.deviceId || ''
|
||||||
|
const currentKeyVersion = query.currentKeyVersion || ''
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
appVersion: '9.1.65',
|
||||||
|
currentKeyVersion,
|
||||||
|
deviceId,
|
||||||
|
nonce,
|
||||||
|
os: 'android',
|
||||||
|
requestType: 'active',
|
||||||
|
signature: encrypt.xeapiSign(timestamp, nonce),
|
||||||
|
t1: '',
|
||||||
|
t2: '',
|
||||||
|
timestamp,
|
||||||
|
uid: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await axios({
|
||||||
|
method: 'POST',
|
||||||
|
url: APP_CONF.apiDomain + '/api/gorilla/anti/crawler/security/key/get',
|
||||||
|
headers: {
|
||||||
|
'User-Agent':
|
||||||
|
'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
|
||||||
|
Cookie: deviceId ? `deviceId=${encodeURIComponent(deviceId)}` : '',
|
||||||
|
},
|
||||||
|
data: new URLSearchParams(data).toString(),
|
||||||
|
proxy: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
!res.data ||
|
||||||
|
res.data.code !== 200 ||
|
||||||
|
!res.data.data ||
|
||||||
|
!res.data.data.encryptedData
|
||||||
|
) {
|
||||||
|
throw new Error('xeapi public key request failed')
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!res.data.data.signature ||
|
||||||
|
encrypt.xeapiSign(res.data.data.timestamp, nonce) !==
|
||||||
|
res.data.data.signature
|
||||||
|
) {
|
||||||
|
throw new Error('xeapi public key response signature mismatch')
|
||||||
|
}
|
||||||
|
|
||||||
|
const publicKey = encrypt.xeapiDecryptPublicKey(res.data.data.encryptedData)
|
||||||
|
if (!publicKey.sk) {
|
||||||
|
throw new Error('xeapi public key response missing sk')
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
...publicKey,
|
||||||
|
deviceId,
|
||||||
|
},
|
||||||
|
cookie: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@
|
|||||||
},
|
},
|
||||||
"APP_CONF": {
|
"APP_CONF": {
|
||||||
"apiDomain": "https://interface.music.163.com",
|
"apiDomain": "https://interface.music.163.com",
|
||||||
|
"xeapiDomain": "https://interface3.music.163.com",
|
||||||
"domain": "https://music.163.com",
|
"domain": "https://music.163.com",
|
||||||
"encrypt": true,
|
"encrypt": true,
|
||||||
"encryptResponse": false,
|
"encryptResponse": false,
|
||||||
|
|||||||
@ -110,7 +110,7 @@ const userAgentMap = {
|
|||||||
// 预先定义常量
|
// 预先定义常量
|
||||||
const DOMAIN = APP_CONF.domain
|
const DOMAIN = APP_CONF.domain
|
||||||
const API_DOMAIN = APP_CONF.apiDomain
|
const API_DOMAIN = APP_CONF.apiDomain
|
||||||
const XEAPI_DOMAIN = 'https://interface3.music.163.com'
|
const XEAPI_DOMAIN = APP_CONF.xeapiDomain
|
||||||
const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
|
const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
|
||||||
const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
|
const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
|
||||||
|
|
||||||
|
|||||||
@ -1,59 +1,15 @@
|
|||||||
const { default: axios } = require('axios')
|
const registerXeapiKey = require('../module/register_xeapikey')
|
||||||
const encrypt = require('./crypto')
|
|
||||||
const { APP_CONF } = require('./config.json')
|
|
||||||
|
|
||||||
const generateNonce = () => {
|
|
||||||
let nonce = ''
|
|
||||||
for (let i = 0; i < 16; i++) {
|
|
||||||
nonce += Math.floor(Math.random() * 10).toString()
|
|
||||||
}
|
|
||||||
return nonce
|
|
||||||
}
|
|
||||||
|
|
||||||
const getXeapiPublicKey = async (currentPublicKey = {}, deviceId = '') => {
|
const getXeapiPublicKey = async (currentPublicKey = {}, deviceId = '') => {
|
||||||
const nonce = generateNonce()
|
const result = await registerXeapiKey(
|
||||||
const timestamp = String(Date.now())
|
{
|
||||||
const data = {
|
deviceId,
|
||||||
appVersion: '9.1.65',
|
currentKeyVersion: currentPublicKey.version || '',
|
||||||
currentKeyVersion: currentPublicKey.version || '',
|
|
||||||
deviceId,
|
|
||||||
nonce,
|
|
||||||
os: 'android',
|
|
||||||
requestType: 'active',
|
|
||||||
signature: encrypt.xeapiSign(timestamp, nonce),
|
|
||||||
t1: '',
|
|
||||||
t2: '',
|
|
||||||
timestamp,
|
|
||||||
uid: '',
|
|
||||||
}
|
|
||||||
const res = await axios({
|
|
||||||
method: 'POST',
|
|
||||||
url: APP_CONF.apiDomain + '/api/gorilla/anti/crawler/security/key/get',
|
|
||||||
headers: {
|
|
||||||
'User-Agent':
|
|
||||||
'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
|
|
||||||
Cookie: deviceId ? `deviceId=${encodeURIComponent(deviceId)}` : '',
|
|
||||||
},
|
},
|
||||||
data: new URLSearchParams(data).toString(),
|
null,
|
||||||
proxy: false,
|
)
|
||||||
})
|
|
||||||
if (
|
|
||||||
!res.data ||
|
|
||||||
res.data.code !== 200 ||
|
|
||||||
!res.data.data ||
|
|
||||||
!res.data.data.encryptedData
|
|
||||||
) {
|
|
||||||
throw new Error('xeapi public key request failed')
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!res.data.data.signature ||
|
|
||||||
encrypt.xeapiSign(res.data.data.timestamp, nonce) !==
|
|
||||||
res.data.data.signature
|
|
||||||
) {
|
|
||||||
throw new Error('xeapi public key response signature mismatch')
|
|
||||||
}
|
|
||||||
|
|
||||||
const publicKey = encrypt.xeapiDecryptPublicKey(res.data.data.encryptedData)
|
const publicKey = result.body
|
||||||
if (!publicKey.sk && currentPublicKey.sk) {
|
if (!publicKey.sk && currentPublicKey.sk) {
|
||||||
publicKey.sk = currentPublicKey.sk
|
publicKey.sk = currentPublicKey.sk
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user