fix: [breaking] [config] pixiv support refresh token login (#6911)

* fix: support refresh token login (#6883)

* docs: update pixiv login

* docs: update pixiv login
This commit is contained in:
小白-白
2021-02-14 17:55:45 +08:00
committed by GitHub
parent a1252450ea
commit 9cd6cda696
9 changed files with 22 additions and 53 deletions

View File

@@ -453,9 +453,7 @@ See docs of specified route and `lib/config.js` for detail information.
- pixiv: [Registration](https://accounts.pixiv.net/signup) - pixiv: [Registration](https://accounts.pixiv.net/signup)
- `PIXIV_USERNAME`: Pixiv username - `PIXIV_PIXIV_REFRESHTOKEN`: Please refer to [this article](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) to get a `refresh_token`
- `PIXIV_PASSWORD`: Pixiv password
- `PIXIV_BYPASS_CDN`: bypass Cloudflare bot check by directly accessing Pixiv source server, defaults to disable, set `true` or `1` to enable - `PIXIV_BYPASS_CDN`: bypass Cloudflare bot check by directly accessing Pixiv source server, defaults to disable, set `true` or `1` to enable

View File

@@ -479,9 +479,7 @@ RSSHub 支持使用访问密钥 / 码,白名单和黑名单三种方式进行
- pixiv 全部路由:[注册地址](https://accounts.pixiv.net/signup) - pixiv 全部路由:[注册地址](https://accounts.pixiv.net/signup)
- `PIXIV_USERNAME`: Pixiv 用户名 - `PIXIV_PIXIV_REFRESHTOKEN`: Pixiv Refresh Token, 请参考 [此文](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) 获取,或自行对客户端抓包获取
- `PIXIV_PASSWORD`: Pixiv 密码
- `PIXIV_BYPASS_CDN`: 绕过 Pixiv 前置的 Cloudflare CDN, 使用`PIXIV_BYPASS_HOSTNAME`指示的 IP 地址访问 Pixiv API, 可以解决因 Cloudflare 机器人验证导致的登录失败问题,默认关闭,设置 true 或 1 开启 - `PIXIV_BYPASS_CDN`: 绕过 Pixiv 前置的 Cloudflare CDN, 使用`PIXIV_BYPASS_HOSTNAME`指示的 IP 地址访问 Pixiv API, 可以解决因 Cloudflare 机器人验证导致的登录失败问题,默认关闭,设置 true 或 1 开启

View File

@@ -50,8 +50,7 @@ const calculateValue = () => {
nodeName: envs.NODE_NAME, nodeName: envs.NODE_NAME,
suffix: envs.SUFFIX, suffix: envs.SUFFIX,
pixiv: { pixiv: {
username: envs.PIXIV_USERNAME, refreshToken: envs.PIXIV_REFRESHTOKEN,
password: envs.PIXIV_PASSWORD,
bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false', bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false',
bypassCdnHostname: envs.PIXIV_BYPASS_HOSTNAME || 'public-api.secure.pixiv.net', bypassCdnHostname: envs.PIXIV_BYPASS_HOSTNAME || 'public-api.secure.pixiv.net',
bypassCdnDoh: envs.PIXIV_BYPASS_DOH || 'https://1.1.1.1/dns-query', bypassCdnDoh: envs.PIXIV_BYPASS_DOH || 'https://1.1.1.1/dns-query',

View File

@@ -4,7 +4,7 @@ const getUserDetail = require('./api/getUserDetail');
const config = require('@/config').value; const config = require('@/config').value;
module.exports = async (ctx) => { module.exports = async (ctx) => {
if (!config.pixiv || !config.pixiv.username || !config.pixiv.password) { if (!config.pixiv || !config.pixiv.refreshToken) {
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>'; throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>';
} }

View File

@@ -2,7 +2,7 @@ const getToken = require('./token');
const getIllustFollows = require('./api/getIllustFollows'); const getIllustFollows = require('./api/getIllustFollows');
const config = require('@/config').value; const config = require('@/config').value;
module.exports = async (ctx) => { module.exports = async (ctx) => {
if (!config.pixiv || !config.pixiv.username || !config.pixiv.password) { if (!config.pixiv || !config.pixiv.refreshToken) {
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>'; throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>';
} }
if (!getToken()) { if (!getToken()) {

View File

@@ -33,7 +33,7 @@ const links = {
}; };
module.exports = async (ctx) => { module.exports = async (ctx) => {
if (!config.pixiv || !config.pixiv.username || !config.pixiv.password) { if (!config.pixiv || !config.pixiv.refreshToken) {
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>'; throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>';
} }

View File

@@ -4,7 +4,7 @@ const searchIllust = require('./api/searchIllust');
const config = require('@/config').value; const config = require('@/config').value;
module.exports = async (ctx) => { module.exports = async (ctx) => {
if (!config.pixiv || !config.pixiv.username || !config.pixiv.password) { if (!config.pixiv || !config.pixiv.refreshToken) {
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>'; throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>';
} }

View File

@@ -3,43 +3,16 @@ const logger = require('@/utils/logger');
const wait = require('@/utils/wait'); const wait = require('@/utils/wait');
const got = require('./pixiv-got'); const got = require('./pixiv-got');
const maskHeader = require('./constants').maskHeader; const maskHeader = require('./constants').maskHeader;
const md5 = require('@/utils/md5');
const pixivConfig = config.pixiv;
let token = null; let token = null;
const authorizationInfo = { const authorizationInfo = {
client_id: 'MOBrBDS8blbauoSck0ZfDbtuzpyT', client_id: 'MOBrBDS8blbauoSck0ZfDbtuzpyT',
client_secret: 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj', client_secret: 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj',
hash_secret: '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c', hash_secret: '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c'
username: pixivConfig.username,
password: pixivConfig.password,
}; };
async function getToken() { async function refreshToken() {
const localTime = new Date().toISOString().replace(/\..+/, '') + '+00:00';
const response = await got({
method: 'post',
url: 'https://oauth.secure.pixiv.net/auth/token',
form: {
...authorizationInfo,
get_secure_url: 1,
grant_type: 'password',
},
headers: {
'X-Client-Time': localTime,
'X-Client-Hash': md5(localTime + authorizationInfo.hash_secret),
...maskHeader,
},
}).catch(function (e) {
logger.error('Pixiv login fail.');
logger.debug(e);
});
return response && response.data && response.data.response;
}
async function refreshToken(refresh_token) {
const response = await got({ const response = await got({
method: 'post', method: 'post',
url: 'https://oauth.secure.pixiv.net/auth/token', url: 'https://oauth.secure.pixiv.net/auth/token',
@@ -47,41 +20,42 @@ async function refreshToken(refresh_token) {
...authorizationInfo, ...authorizationInfo,
get_secure_url: 1, get_secure_url: 1,
grant_type: 'refresh_token', grant_type: 'refresh_token',
refresh_token: refresh_token, refresh_token: config.pixiv.refreshToken,
}, },
headers: { headers: {
...maskHeader, ...maskHeader,
}, },
}).catch(function (e) {
logger.error('Pixiv refresh token failed.');
logger.debug(e);
}); });
return response.data.response; return response && response.data && response.data.response;
} }
async function tokenLoop() { async function tokenLoop() {
const res = await getToken(); const res = await refreshToken();
if (res) { if (res && res.access_token) {
logger.info('Pixiv login success.'); logger.info('Pixiv login success.');
token = res.access_token; token = res.access_token;
let refresh_token = res.refresh_token;
let expires_in = res.expires_in * 0.9; let expires_in = res.expires_in * 0.9;
/* eslint-disable no-constant-condition, no-await-in-loop */ /* eslint-disable no-constant-condition, no-await-in-loop */
while (true) { while (true) {
await wait(expires_in * 1000); await wait(expires_in * 1000);
try { const refresh_res = await refreshToken();
const refresh_res = await refreshToken(refresh_token); if (refresh_res && refresh_res.access_token) {
logger.debug('Pixiv refresh token success.'); logger.debug('Pixiv refresh token success.');
token = refresh_res.access_token; token = refresh_res.access_token;
refresh_token = refresh_res.refresh_token;
expires_in = refresh_res.expires_in * 0.9; expires_in = refresh_res.expires_in * 0.9;
} catch (err) { } else {
expires_in = 30; expires_in = 30;
logger.error(`Pixiv refresh token failed, retry in ${expires_in} seconds.`, err); logger.error(`Pixiv refresh token failed, retry in ${expires_in} seconds.`);
} }
} }
/* eslint-enable no-await-in-loop */ /* eslint-enable no-await-in-loop */
} }
} }
if (config.pixiv && config.pixiv.username && config.pixiv.password) { if (config.pixiv && config.pixiv.refreshToken) {
tokenLoop(); tokenLoop();
} }

View File

@@ -3,7 +3,7 @@ const getIllusts = require('./api/getIllusts');
const config = require('@/config').value; const config = require('@/config').value;
module.exports = async (ctx) => { module.exports = async (ctx) => {
if (!config.pixiv || !config.pixiv.username || !config.pixiv.password) { if (!config.pixiv || !config.pixiv.refreshToken) {
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>'; throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#%E9%83%A8%E5%88%86-rss-%E6%A8%A1%E5%9D%97%E9%85%8D%E7%BD%AE">relevant config</a>';
} }