feature image

2025年5月18日 | ブログ記事

[AtCoder] 死んだ自動ログインを復活させよう

PPC と見せかけて Web の話です.

はじめに

25B の みどりむし🦠 です.
受験期に競プロを離れて以来, ついぞコンテストに参加しないまま半年が経ってしまいました.

そろそろ再開のために環境を復元しようとしていたところ, 最近実装された CLOUDFLARE 認証に手元の半自動提出環境が破壊されていたので, その対処法を記録します.

必要なログイン情報

詳細は省きますが, AtCoder へログインするには (初回を除き) 少なくとも HTTP Cookie (のうち, REVEL_SESSION の値) があればよいです.

逆にこれさえ取得できれば, それをリクエストヘッダの Cookie プロパティに渡してやることで, コンテスト中にも問題ページにアクセスして問題文やサンプルをスクレイピングしたりできるようになります. (開催中のコンテストに限り自動提出も可能です. )

document.cookie を参照しても取得できないので, 別な方法で持ってきます.

適当なリクエストのレスポンスヘッダから拝借する方法

atcoder.jp にログイン済みのブラウザで開発者ツールを開き, 一旦リロードしておきます.
開発者ツールの Network タブを開き, 表示されているリクエストのうち一番上のものの Response Headers から Set-Cookie プロパティの値をそのまま控えておけばよいです.

開発者ツールから直接取得する方法

atcoder.jp にログイン済みのブラウザで開発者ツールを開き, Application > Cookies > https://atcoder.jp > REVEL_SESSION の値を控えておきます.

使用する際は以下の形で用います:

REVEL_SESSION={{控えた値}}

atcoder-cli を使用している場合

筆者はまともに使ったことがないのですが, 利用人口がそれなりにありそうですので atcoder-cli に適用する方法を述べておきます.

atcoder-cli の Cookie の保存場所は ~/.config/atcoder-cli-nodejs/session.json らしいので, これを以下のように書き換えればよいです:

{
    "cookies": [
        "REVEL_SESSION={{ここに前項で得た Cookie の REVEL_SESSION をペーストする}}"
    ]
}

おそらく現在 atcoder-cli を利用できている人もセッションの期限が切れ次第突然弾かれるようになると思いますので, その際はこの手順で手動復帰してあげてください.

online-judge-tools (oj) を使用している場合

oj は selenium.webdriver を用いてお使いのブラウザからアクセスを試みるようです.
つまり基本的には何もしなくてもよいということです.

実装例 (Node.js)

執筆前の想定よりもあっさり済んでしまったので, 尺調整としてソースを自動提出するプログラムの実装例を紹介してみます.

const Axios = require("axios");

const axios = Axios.create({
    headers: {
      "X-Requested-With": "XMLHttpRequest",
      "Accept-Encoding": "gzip",
      Cookie: "{{Cookie}}",
    },
    timeout: 15 * 1000,
});

const data = new URLSearchParams();

data.append("data.TaskScreenName", "{{Problem ID}}");
data.append("data.LanguageId", "{{Language ID}}");
data.append("sourceCode", "{{Source Code}}");
data.append("csrf_token", "{{CSRF Token}}");

axios.post("https://atcoder.jp/contests/{{Problem ID}}/submit", data);

CSRF Token

コンテスト中に自動提出をするためには CSRF Token を body に含める必要があるようです. この値は前項で取得した Cookie にも含まれてはいますが, 少々抽出が面倒なので他の方法を述べておきます.

atcoder.jp にログイン済みのブラウザで開発者ツールを開き, Console タブに下記の JavaScript コードを投げることで簡単に取得できます:

document.getElementsByName("csrf_token")[0].value

Language ID

適当な問題の提出ページに遷移し, JavaScript Console に以下のコードを投げることで一覧が得られます:

document.getElementsByName("data.LanguageId")[0]

おわりに

昔はユーザー名とパスワード (と CSRF Token) からログインを完全自動で行えたのですが, 現在ではおそらく不可能です. 甚だ残念ですが, しょうがないですね.
ただ幸いなことに, AtCoder のセッション期限はそこそこ長い (半年ほどある) ようですので, 今回述べた方法でも十分実用に足るのではと思います.

あるいは, oj のように手元のブラウザを利用してスクレイピングするという手もある気がします.


(しょうもない内容なので別媒体にて投稿するつもりだったのですが, せっかくならということで traP のブログに投げることになりました. ここまでお付き合いいただきありがとうございます. 今後ともよろしくどうぞ. )

uni_kakurenbo icon
この記事を書いた人
uni_kakurenbo

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2023年12月11日
DIGI-CON HACKATHON 2023『Mikage』
toshi00 icon toshi00
2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2024年6月21日
ハッカソン参加記 4班"Slide Center"
Alt--er icon Alt--er
2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2024年4月14日
Spotifyのクライアントを自作しよう
d_etteiu8383 icon d_etteiu8383
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記