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_USERNAME`: Pixiv username
- `PIXIV_PASSWORD`: Pixiv password
- `PIXIV_PIXIV_REFRESHTOKEN`: Please refer to [this article](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) to get a `refresh_token`
- `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_USERNAME`: Pixiv 用户名
- `PIXIV_PASSWORD`: Pixiv 密码
- `PIXIV_PIXIV_REFRESHTOKEN`: Pixiv Refresh Token, 请参考 [此文](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) 获取,或自行对客户端抓包获取
- `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,
suffix: envs.SUFFIX,
pixiv: {
username: envs.PIXIV_USERNAME,
password: envs.PIXIV_PASSWORD,
refreshToken: envs.PIXIV_REFRESHTOKEN,
bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false',
bypassCdnHostname: envs.PIXIV_BYPASS_HOSTNAME || 'public-api.secure.pixiv.net',
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;
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>';
}

View File

@@ -2,7 +2,7 @@ const getToken = require('./token');
const getIllustFollows = require('./api/getIllustFollows');
const config = require('@/config').value;
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>';
}
if (!getToken()) {

View File

@@ -33,7 +33,7 @@ const links = {
};
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>';
}

View File

@@ -4,7 +4,7 @@ const searchIllust = require('./api/searchIllust');
const config = require('@/config').value;
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>';
}

View File

@@ -3,43 +3,16 @@ const logger = require('@/utils/logger');
const wait = require('@/utils/wait');
const got = require('./pixiv-got');
const maskHeader = require('./constants').maskHeader;
const md5 = require('@/utils/md5');
const pixivConfig = config.pixiv;
let token = null;
const authorizationInfo = {
client_id: 'MOBrBDS8blbauoSck0ZfDbtuzpyT',
client_secret: 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj',
hash_secret: '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c',
username: pixivConfig.username,
password: pixivConfig.password,
hash_secret: '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c'
};
async function getToken() {
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) {
async function refreshToken() {
const response = await got({
method: 'post',
url: 'https://oauth.secure.pixiv.net/auth/token',
@@ -47,41 +20,42 @@ async function refreshToken(refresh_token) {
...authorizationInfo,
get_secure_url: 1,
grant_type: 'refresh_token',
refresh_token: refresh_token,
refresh_token: config.pixiv.refreshToken,
},
headers: {
...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() {
const res = await getToken();
if (res) {
const res = await refreshToken();
if (res && res.access_token) {
logger.info('Pixiv login success.');
token = res.access_token;
let refresh_token = res.refresh_token;
let expires_in = res.expires_in * 0.9;
/* eslint-disable no-constant-condition, no-await-in-loop */
while (true) {
await wait(expires_in * 1000);
try {
const refresh_res = await refreshToken(refresh_token);
const refresh_res = await refreshToken();
if (refresh_res && refresh_res.access_token) {
logger.debug('Pixiv refresh token success.');
token = refresh_res.access_token;
refresh_token = refresh_res.refresh_token;
expires_in = refresh_res.expires_in * 0.9;
} catch (err) {
} else {
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 */
}
}
if (config.pixiv && config.pixiv.username && config.pixiv.password) {
if (config.pixiv && config.pixiv.refreshToken) {
tokenLoop();
}

View File

@@ -3,7 +3,7 @@ const getIllusts = require('./api/getIllusts');
const config = require('@/config').value;
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>';
}