Merge branch 'main' into 'main'

feat: 模拟pc客户端的ua和cookie字段

See merge request Binaryify/neteasecloudmusicapi!26
This commit is contained in:
binaryify 2024-10-06 08:32:25 +00:00
commit b25732e820
7 changed files with 67 additions and 60 deletions

View File

@ -5,6 +5,6 @@ module.exports = (query, request) => {
{ {
id: query.id, id: query.id,
}, },
createOption(query, 'weapi'), createOption(query),
) )
} }

View File

@ -11,10 +11,7 @@ module.exports = async (query, request) => {
password: query.md5_password || CryptoJS.MD5(query.password).toString(), password: query.md5_password || CryptoJS.MD5(query.password).toString(),
rememberLogin: 'true', rememberLogin: 'true',
} }
let result = await request(`/api/w/login`, data, { let result = await request(`/api/w/login`, data, createOption(query))
...createOption(query),
uaType: 'pc',
})
if (result.body.code === 502) { if (result.body.code === 502) {
return { return {
status: 200, status: 200,

View File

@ -15,10 +15,11 @@ module.exports = async (query, request) => {
: query.md5_password || CryptoJS.MD5(query.password).toString(), : query.md5_password || CryptoJS.MD5(query.password).toString(),
rememberLogin: 'true', rememberLogin: 'true',
} }
let result = await request(`/api/w/login/cellphone`, data, { let result = await request(
...createOption(query), `/api/w/login/cellphone`,
uaType: 'pc', data,
}) createOption(query),
)
if (result.body.code === 200) { if (result.body.code === 200) {
result = { result = {

View File

@ -5,10 +5,7 @@ module.exports = async (query, request) => {
let result = await request( let result = await request(
`/api/login/token/refresh`, `/api/login/token/refresh`,
{}, {},
{ createOption(query),
...createOption(query, 'eapi'),
uaType: 'pc',
},
) )
if (result.body.code === 200) { if (result.body.code === 200) {
result = { result = {

View File

@ -2,12 +2,5 @@
const createOption = require('../util/option.js') const createOption = require('../util/option.js')
module.exports = (query, request) => { module.exports = (query, request) => {
return request( return request(`/api/logout`, {}, createOption(query))
`/api/logout`,
{},
{
...createOption(query, 'weapi'),
uaType: 'pc',
},
)
} }

View File

@ -5,8 +5,5 @@ module.exports = (query, request) => {
const data = { const data = {
type: 1111, type: 1111,
} }
return request(`/api/search/hot`, data, { return request(`/api/search/hot`, data, createOption(query))
...createOption(query, 'weapi'),
uaType: 'mobile',
})
} }

View File

@ -14,23 +14,43 @@ const anonymous_token = fs.readFileSync(
'utf-8', 'utf-8',
) )
const { URLSearchParams, URL } = require('url') const { URLSearchParams, URL } = require('url')
const iosAppVersion = '9.0.65'
const { APP_CONF } = require('../util/config.json') const { APP_CONF } = require('../util/config.json')
// request.debug = true // 开启可看到更详细信息 // request.debug = true // 开启可看到更详细信息
const chooseUserAgent = (uaType) => { const osMap = {
pc: {
os: 'pc',
appver: '3.0.18.203152',
osver: 'Microsoft-Windows-10-Professional-build-22631-64bit',
},
android: {
os: 'android',
appver: '8.20.20.231215173437',
osver: '14',
},
iphone: {
os: 'iOS',
appver: '9.0.90',
osver: '16.2',
},
}
const chooseUserAgent = (crypto, uaType = 'pc') => {
const userAgentMap = { const userAgentMap = {
mobile: weapi: {
'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Mobile/15E148 Safari/604.1', pc: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
pc: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0', },
api: {
pc: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Chrome/91.0.4472.164 NeteaseMusicDesktop/3.0.18.203152',
android:
'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
iphone: 'NeteaseMusic 9.0.90/5038 (iPhone; iOS 16.2; zh_CN)',
},
} }
if (uaType === 'mobile') { return userAgentMap[crypto][uaType] || ''
return userAgentMap.mobile
}
return userAgentMap.pc
} }
const createRequest = (uri, data, options) => { const createRequest = (uri, data, options) => {
const cookie = options.cookie || {} let cookie = options.cookie || {}
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
options.headers = options.headers || {} options.headers = options.headers || {}
let headers = options.headers let headers = options.headers
@ -41,31 +61,34 @@ const createRequest = (uri, data, options) => {
headers['X-Forwarded-For'] = ip headers['X-Forwarded-For'] = ip
} }
// headers['X-Real-IP'] = '118.88.88.88' // headers['X-Real-IP'] = '118.88.88.88'
if (typeof options.cookie === 'object') { if (typeof cookie === 'object') {
options.cookie = { let _ntes_nuid = CryptoJS.lib.WordArray.random(32).toString()
...options.cookie, let os = osMap[cookie.os] || osMap['iphone']
__remember_me: true, cookie = {
...cookie,
__remember_me: 'true',
// NMTID: CryptoJS.lib.WordArray.random(16).toString(), // NMTID: CryptoJS.lib.WordArray.random(16).toString(),
_ntes_nuid: CryptoJS.lib.WordArray.random(16).toString(), ntes_kaola_ad: '1',
_ntes_nuid: _ntes_nuid,
_ntes_nnid: `${_ntes_nuid},${Date.now().toString()}`,
osver: cookie.osver || os.osver,
deviceId: cookie.deviceId || global.deviceId,
os: cookie.os || os.os,
channel: cookie.channel || 'netease',
appver: cookie.appver || os.appver,
} }
if (uri.indexOf('login') === -1) { if (uri.indexOf('login') === -1) {
options.cookie['NMTID'] = CryptoJS.lib.WordArray.random(16).toString() cookie['NMTID'] = CryptoJS.lib.WordArray.random(16).toString()
} }
if (!options.cookie.MUSIC_U) { if (!cookie.MUSIC_U) {
// 游客 // 游客
if (!options.cookie.MUSIC_A) { if (!cookie.MUSIC_A) {
options.cookie.MUSIC_A = anonymous_token cookie.MUSIC_A = anonymous_token
} }
} }
headers['Cookie'] = cookieObjToString(options.cookie)
} else if (options.cookie) {
// cookie string
headers['Cookie'] = options.cookie
} else {
const cookie = cookieToJson('__remember_me=true; NMTID=xxx')
headers['Cookie'] = cookieObjToString(cookie) headers['Cookie'] = cookieObjToString(cookie)
} }
// console.log(options.cookie, headers['Cookie'])
let url = '', let url = '',
encryptData = '', encryptData = '',
@ -85,7 +108,7 @@ const createRequest = (uri, data, options) => {
switch (crypto) { switch (crypto) {
case 'weapi': case 'weapi':
headers['Referer'] = APP_CONF.domain headers['Referer'] = APP_CONF.domain
headers['User-Agent'] = options.ua || chooseUserAgent('pc') headers['User-Agent'] = options.ua || chooseUserAgent('weapi')
data.csrf_token = csrfToken data.csrf_token = csrfToken
encryptData = encrypt.weapi(data) encryptData = encrypt.weapi(data)
url = APP_CONF.domain + '/weapi/' + uri.substr(5) url = APP_CONF.domain + '/weapi/' + uri.substr(5)
@ -99,24 +122,23 @@ const createRequest = (uri, data, options) => {
url: APP_CONF.apiDomain + uri, url: APP_CONF.apiDomain + uri,
params: data, params: data,
}) })
url = 'https://music.163.com/api/linux/forward' url = APP_CONF.apiDomain + '/api/linux/forward'
break break
case 'eapi': case 'eapi':
case 'api': case 'api':
// 两种加密方式都应生成客户端的cookie // 两种加密方式都应生成客户端的cookie
const cookie = options.cookie || {}
const header = { const header = {
osver: cookie.osver || '17.4.1', //系统版本 osver: cookie.osver, //系统版本
deviceId: cookie.deviceId || global.deviceId, deviceId: cookie.deviceId,
os: cookie.os || 'ios', os: cookie.os,
appver: cookie.appver || (cookie.os != 'pc' ? iosAppVersion : ''), // app版本 appver: cookie.appver, // app版本
versioncode: cookie.versioncode || '140', //版本号 versioncode: cookie.versioncode || '140', //版本号
mobilename: cookie.mobilename || '', //设备model mobilename: cookie.mobilename || '', //设备model
buildver: cookie.buildver || Date.now().toString().substr(0, 10), buildver: cookie.buildver || Date.now().toString().substr(0, 10),
resolution: cookie.resolution || '1920x1080', //设备分辨率 resolution: cookie.resolution || '1920x1080', //设备分辨率
__csrf: csrfToken, __csrf: csrfToken,
channel: cookie.channel || '', channel: cookie.channel,
requestId: `${Date.now()}_${Math.floor(Math.random() * 1000) requestId: `${Date.now()}_${Math.floor(Math.random() * 1000)
.toString() .toString()
.padStart(4, '0')}`, .padStart(4, '0')}`,
@ -129,7 +151,7 @@ const createRequest = (uri, data, options) => {
encodeURIComponent(key) + '=' + encodeURIComponent(header[key]), encodeURIComponent(key) + '=' + encodeURIComponent(header[key]),
) )
.join('; ') .join('; ')
headers['User-Agent'] = options.ua || chooseUserAgent(options.uaType) headers['User-Agent'] = options.ua || chooseUserAgent('api')
if (crypto === 'eapi') { if (crypto === 'eapi') {
// 使用eapi加密 // 使用eapi加密