Skip to content

Commit

Permalink
1、添加用户登录api,支持密码登录、验证码登录、扫码登录
Browse files Browse the repository at this point in the history
  • Loading branch information
MakcRe committed Jun 22, 2023
0 parents commit 171aa7b
Show file tree
Hide file tree
Showing 24 changed files with 1,907 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local
test

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
19 changes: 19 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"arrowParens": "always",
"bracketSameLine": false,
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": false,
"printWidth": 150,
"proseWrap": "always",
"quoteProps": "preserve",
"requirePragma": false,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"vueIndentScriptAndStyle": false
}
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## 酷狗音乐 API
酷狗音乐 Node.js API service

## 环境要求
需要 NodeJS 12+ 环境
7 changes: 7 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { startService } from './server';

async function start () {
await startService();
}

start().then(() => {});
21 changes: 21 additions & 0 deletions module/captcha_sent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { mapToObject } from '../util/util';

export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
const dataMap = new Map();

dataMap.set('businessid', 5);
dataMap.set('mobile', params?.mobile);
dataMap.set('plat', 3);


return useAxios({
url: '/v7/send_mobile_code',
method: 'POST',
data: mapToObject(dataMap),
encryptType: 'android',
cookie: params?.cookie || {},
headers: { 'x-router': 'loginservice.kugou.com' },
});
}

export default useModule;
49 changes: 49 additions & 0 deletions module/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { mapToObject } from '../util/util';
import { cryptoAesDecrypt, cryptoAesEncrypt, cryptoRSAEncrypt } from '../util/crypto';

export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
const dateNow = Date.now();
const encrypt = cryptoAesEncrypt({ pwd: params?.password || '', code: '' , clienttime_ms: dateNow});
const dataMap = new Map();
dataMap.set('plat', 1);
dataMap.set('support_multi', 1);
dataMap.set('clienttime_ms', dateNow);
dataMap.set('t1', 0);
dataMap.set('t2', 0);
dataMap.set('t3', 'MCwwLDAsMCwwLDAsMCwwLDA=');
dataMap.set('username', params?.username);
dataMap.set('params', encrypt.str);
dataMap.set('pk', cryptoRSAEncrypt({'clienttime_ms': dataMap.get('clienttime_ms'), key: encrypt.key}).toUpperCase());

return new Promise((resolve, reject) => {
useAxios({
url: '/v9/login_by_pwd',
method: 'POST',
data: mapToObject(dataMap),
encryptType: 'android',
cookie: params?.cookie || {},
headers: { 'x-router': 'login.user.kugou.com' },
}).then(res => {
const { body } = res;
if (body?.status && body?.status === 1) {
if (body?.data?.secu_params) {
const getToken = cryptoAesDecrypt(body.data.secu_params, encrypt.key);
if (typeof getToken === 'object') {
res.body.data = { ...body.data, ...getToken};
Object.keys(getToken).forEach(key => res.cookie.push(`${key}=${getToken[key]}`));
} else {
res.body.data['token'] = getToken;
res.cookie.push(`token=${getToken}`);
}
res.cookie.push(`userid=${res.body.data?.userid || 0}`)

resolve(res);
return;
}
}
resolve(res);
}).catch(e => reject(e));
});
}

export default useModule;
51 changes: 51 additions & 0 deletions module/login_cellphone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { mapToObject } from '../util/util';
import { cryptoAesDecrypt, cryptoAesEncrypt, cryptoRSAEncrypt } from '../util/crypto';
import { signParamsKey } from '../util/helper';

export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
const mobile = params?.mobile && `${(params.mobile.toString()).substring(0, 2)}*****${(params.mobile.toString()).substring(10, 11)}`;
const encrypt = cryptoAesEncrypt({ mobile: params?.mobile || '', code: params?.code || '' });
const dataMap = new Map();
dataMap.set('plat', 1);
dataMap.set('support_multi', 1);
dataMap.set('clienttime_ms', Date.now());
dataMap.set('t1', 0);
dataMap.set('t2', 0);
dataMap.set('t3', 'MCwwLDAsMCwwLDAsMCwwLDA=');
dataMap.set('mobile', mobile);
dataMap.set('params', encrypt.str);
dataMap.set('key', signParamsKey(dataMap.get('clienttime_ms')));
dataMap.set('pk', cryptoRSAEncrypt({'clienttime_ms': dataMap.get('clienttime_ms'), key: encrypt.key}).toUpperCase());

return new Promise((resolve, reject) => {
useAxios({
url: '/v7/login_by_verifycode',
method: 'POST',
data: mapToObject(dataMap),
encryptType: 'android',
cookie: params?.cookie || {},
headers: { 'x-router': 'login.user.kugou.com' },
}).then(res => {
const { body } = res;
if (body?.status && body?.status === 1) {
if (body?.data?.secu_params) {
const getToken = cryptoAesDecrypt(body.data.secu_params, encrypt.key);
if (typeof getToken === 'object') {
res.body.data = { ...body.data, ...getToken};
Object.keys(getToken).forEach(key => res.cookie.push(`${key}=${getToken[key]}`));
} else {
res.body.data['token'] = getToken;
res.cookie.push(`token=${getToken}`);
}
res.cookie.push(`userid=${res.body.data?.userid || 0}`)

resolve(res);
return;
}
}
resolve(res);
}).catch(e => reject(e));
});
}

export default useModule;
21 changes: 21 additions & 0 deletions module/login_qr_check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 0 为二维码过期,1 为等待扫码,2 为待确认,4 为授权登录成功(4 状态码下会返回 token)
export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
return new Promise((resolve, reject) => {
useAxios({
baseURL: 'https://login-user.kugou.com',
url: '/v1/get_userinfo_qrcode',
method: 'GET',
params: { appid: 1005, type: 1, qrcode: params?.key },
encryptType: 'web',
cookie: params?.cookie || {},
}).then(resp => {
if (resp.body?.data?.status == 4) {
resp.cookie.push(`token=${resp.body?.data?.token}; PATH=/`);
resp.cookie.push(`userid=${resp.body?.data?.userid}; PATH=/`);
}
resolve(resp);
}).catch(e => reject(e));
});
};

export default useModule;
19 changes: 19 additions & 0 deletions module/login_qr_create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { toDataURL } from 'qrcode';
export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
return new Promise(async (resolve) => {
const url = `https://h5.kugou.com/apps/loginQRCode/html/index.html?qrcode=${params.key}`
return resolve({
code: 200,
status: 200,
body: {
code: 200,
data: {
url: url,
base64: params?.qrimg ? await toDataURL(url) : '',
},
},
})
})
}

export default useModule;
12 changes: 12 additions & 0 deletions module/login_qr_key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
return useAxios({
baseURL: 'https://login-user.kugou.com',
url: '/v1/qrcode',
method: 'GET',
params: { appid: params?.type === 'web' ? 1014 : 1001, type: 1 },
encryptType: 'web',
cookie: params?.cookie || {},
});
}

export default useModule;
59 changes: 59 additions & 0 deletions module/login_token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { mapToObject } from '../util/util';
import { cryptoAesDecrypt, cryptoAesEncrypt, cryptoRSAEncrypt } from '../util/crypto';

const key = '90b8382a1bb4ccdcf063102053fd75b8';
const iv = 'f063102053fd75b8';

export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
const dateNow = Date.now();
const token = params?.token || params?.cookie?.token || '';
const userid = params?.userid || params?.cookie?.userid || '0';
const encrypt = cryptoAesEncrypt({ clienttime: Math.floor(dateNow / 1000), token }, { key, iv });
const encryptParams = cryptoAesEncrypt({});
const pk = cryptoRSAEncrypt({ clienttime_ms: dateNow, key: encryptParams.key });

const dataMap = new Map();
dataMap.set('dfid', params?.cookie.dfid || '-');
dataMap.set('p3', encrypt);
dataMap.set('plat', '1');
dataMap.set('t1', 0);
dataMap.set('t2', 0);
dataMap.set('t3', 'MCwwLDAsMCwwLDAsMCwwLDA=');
dataMap.set('pk', pk);
dataMap.set('params', encryptParams.str);
dataMap.set('userid', userid);
dataMap.set('clienttime_ms', dateNow);

return new Promise((resolve, reject) => {
useAxios({
baseURL: 'http://login.user.kugou.com',
url: '/v5/login_by_token',
method: 'POST',
data: mapToObject(dataMap),
cookie: params?.cookie,
encryptType: 'android',
headers: {'x-router': 'login.user.kugou.com'}
}).then(res => {
const { body } = res;
if (body?.status && body?.status === 1) {
if (body?.data?.secu_params) {
const getToken = cryptoAesDecrypt(body.data.secu_params, encryptParams.key);
if (typeof getToken === 'object') {
res.body.data = { ...body.data, ...getToken};
Object.keys(getToken).forEach(key => res.cookie.push(`${key}=${getToken[key]}`));
} else {
res.body.data['token'] = getToken;
res.cookie.push(`token=${getToken}`);
}
res.cookie.push(`userid=${res.body.data?.userid || 0}`)

resolve(res);
return;
}
}
resolve(res);
}).catch(e => reject(e));
});
}

export default useModule;
22 changes: 22 additions & 0 deletions module/register_dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { mapToObject } from '../util/util';

export const useModule = (params: UseModuleParams, useAxios: UseAxios) => {
const dataMap = new Map();

dataMap.set('mid', params?.mid || '');
dataMap.set('uuid', params?.uuid || '');
dataMap.set('appid', '1014');
dataMap.set('userid', params?.userid || '0')

return useAxios({
baseURL: 'https://userservice.kugou.com',
url: '/risk/v1/r_register_dev',
method: 'POST',
data: Buffer.from(JSON.stringify(mapToObject(dataMap))).toString('base64'),
params: { ...mapToObject(dataMap), 'p.token': '', platid: 4 },
encryptType: 'register',
cookie: params?.cookie || {},
});
}

export default useModule;
25 changes: 25 additions & 0 deletions nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"restartable": "rs",
"ignore": [
".git",
"node_modules/",
"dist/",
"coverage/"
],
"watch": [
"module/**",
"plugins/**",
"util/**",
"types/**",
"./server.ts",
"./index.ts",
"./main.ts"
],
"execMap": {
"ts": "ts-node --files index.ts"
},
"env": {
"NODE_ENV": "development"
},
"ext": "js,json,ts"
}
27 changes: 27 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "KuGouMusicApi",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "nodemon --config nodemon.json index.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/express": "^4.17.17",
"@types/node": "^18.11.9",
"@types/qrcode": "^1.5.0",
"nodemon": "^2.0.20",
"prettier": "^2.7.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3"
},
"dependencies": {
"axios": "^1.1.3",
"express": "^4.18.2",
"qrcode": "^1.5.3",
"safe-decode-uri-component": "^1.2.1"
}
}
Loading

0 comments on commit 171aa7b

Please sign in to comment.