mirror of
https://github.com/DIYgod/RSSHub.git
synced 2025-12-07 21:47:57 +08:00
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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 开启
|
||||||
|
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user