Skip to content

Commit 6065eaf

Browse files
solidlimeclaude
andcommitted
fix: post-redirect URL を受け取ったら中継ページで return_to リンクを表示
accounts.pixiv.net/post-redirect で止まるケース向けに: - post-redirect URL が貼られたら return_to を抽出して中継ページを表示 - 中継ページに「認証を続ける」リンク (新しいタブ) とコード入力フォームを配置 - session import を flask トップレベルから行うよう統一 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3279ff5 commit 6065eaf

1 file changed

Lines changed: 57 additions & 11 deletions

File tree

‎src/web_setup.py‎

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import urllib.request
2020
from pathlib import Path
2121

22-
from flask import Flask, redirect, render_template_string, request, send_from_directory
22+
from flask import Flask, redirect, render_template_string, request, send_from_directory, session
2323

2424
app = Flask(__name__)
2525
app.secret_key = secrets.token_hex(32)
@@ -285,6 +285,47 @@ def upsert_env_value(key: str, value: str) -> None:
285285
"""
286286
)
287287

288+
_PIXIV_CONTINUE_HTML = (
289+
_BASE_STYLE
290+
+ """
291+
<div class="card shadow-sm">
292+
<div class="card-body p-4">
293+
<h5 class="card-title mb-3">Pixiv 認証 — ステップ 2/2</h5>
294+
295+
<div class="alert alert-info small mb-3">
296+
ログインは完了しています。<br>
297+
下のボタンで<strong>認証の続き</strong>を新しいタブで開いてください。<br>
298+
ページが表示されたら、アドレスバーの URL をコピーして下のフォームに貼り付けてください。<br>
299+
<span class="text-muted">(ページが真っ白やエラーでも OK。URL に <code>?code=</code> が入っていれば成功)</span>
300+
</div>
301+
302+
<a href="{{ return_to_url }}" target="_blank" class="btn btn-danger w-100 mb-4">
303+
認証を続ける(新しいタブで開く)
304+
</a>
305+
306+
<p class="small text-muted mb-1">
307+
コピーする URL の例:<br>
308+
<code>https://app-api.pixiv.net/web/v1/users/auth/pixiv/callback?code=XXXXX…</code>
309+
</p>
310+
311+
<form method="post" action="/pixiv-oauth/exchange">
312+
<div class="input-group">
313+
<input type="text" class="form-control form-control-sm font-monospace"
314+
name="callback_url" required
315+
placeholder="https://app-api.pixiv.net/…/callback?code=...">
316+
<button type="submit" class="btn btn-primary btn-sm">取得して保存</button>
317+
</div>
318+
</form>
319+
320+
<div class="mt-3">
321+
<a href="/" class="small text-muted">← セットアップに戻る</a>
322+
</div>
323+
</div>
324+
</div>
325+
</body></html>
326+
"""
327+
)
328+
288329
_GALLERY_INDEX_HTML = (
289330
_BASE_STYLE
290331
+ """
@@ -438,8 +479,6 @@ def save_pixiv_token():
438479
@app.route("/pixiv-oauth/start")
439480
def pixiv_oauth_start():
440481
"""PKCE コードを生成して Pixiv 認証 URL を返す。"""
441-
from flask import session
442-
443482
# gallery-dl と同じ方法で生成 (hex 文字列)
444483
code_verifier = os.urandom(32).hex()
445484
digest = hashlib.sha256(code_verifier.encode()).digest()
@@ -459,23 +498,30 @@ def pixiv_oauth_start():
459498
@app.route("/pixiv-oauth/exchange", methods=["POST"])
460499
def pixiv_oauth_exchange():
461500
"""コールバック URL からコードを取り出してリフレッシュトークンに交換する。"""
462-
from flask import session
463-
464501
callback_url = request.form.get("callback_url", "").strip()
465-
code_verifier = session.pop("pixiv_code_verifier", None)
502+
code_verifier = session.get("pixiv_code_verifier")
466503

467504
if not code_verifier:
468505
return redirect("/?pixiv_error=セッションが切れました。もう一度やり直してください。")
469506

470-
params = urllib.parse.parse_qs(urllib.parse.urlparse(callback_url).query)
507+
parsed = urllib.parse.urlparse(callback_url)
508+
params = urllib.parse.parse_qs(parsed.query)
471509
codes = params.get("code", [])
510+
511+
# post-redirect URL が貼られた場合は return_to を取り出して中継ページへ
512+
if not codes and ("post-redirect" in callback_url or "return_to" in params):
513+
return_to = params.get("return_to", [""])[0]
514+
if return_to:
515+
return render_template_string(_PIXIV_CONTINUE_HTML, return_to_url=return_to)
516+
msg = "URLを解析できませんでした。ページをリロードして最初からやり直してください。"
517+
return redirect(f"/?pixiv_error={urllib.parse.quote(msg)}")
518+
472519
if not codes:
473-
if "post-redirect" in callback_url or "return_to" in callback_url:
474-
msg = "リダイレクト途中のURLが貼られています。ブラウザがapp-api.pixiv.net/.../callback?code=...に到達してからコピーしてください。"
475-
else:
476-
msg = "URLにcodeが含まれていません。アドレスバーのURLをそのままコピーしてください。"
520+
msg = "URLにcodeが含まれていません。アドレスバーのURLをそのままコピーしてください。"
477521
return redirect(f"/?pixiv_error={urllib.parse.quote(msg)}")
478522

523+
session.pop("pixiv_code_verifier", None)
524+
479525
data = urllib.parse.urlencode({
480526
"client_id": _PIXIV_CLIENT_ID,
481527
"client_secret": _PIXIV_CLIENT_SECRET,

0 commit comments

Comments
 (0)