LoginSignup
2
1

RustでAtCoderのログイン認証を通す

Last updated at Posted at 2023-09-29

はじめに

RustでAtCoderにログイン認証を通すコードを作成したので備忘録として残しておきます。

処理の流れ

  1. https://atcoder.jp/login にアクセスしてCookieとcsrf_tokenを取得
  2. csrf_token、ユーザ名、パスワードをクエリパラメータに設定してログイン

コード

reqwestのfeaturesに"blocking""cookies"を追加する必要があります。

use scraper::Selector;

use reqwest::{blocking::Client, cookie::Jar};
use std::{io, sync::Arc};

fn get_user_id() -> String {
    let mut input = String::new();
    print!("ユーザ名を入力してください: ");
    io::stdout().flush().unwrap();
    io::stdin()
        .read_line(&mut input)
        .expect("Failed to read line");
    input.trim().to_string()
}

fn login() -> Result<(), reqwest::Error> {
    let user = get_user_id();
    let pass = rpassword::prompt_password("パスワードを入力してください: ")
        .expect("Failed to read password");

    // Cookieストアを作成
    let cookie_store = Arc::new(Jar::default());

    // Cookieストアを持つClientを作成
    let client = Client::builder()
        .cookie_store(true) // クライアントでCookieストアを有効にする
        .cookie_provider(Arc::clone(&cookie_store)) // カスタムCookieストアを設定
        .build()?;

    // csrf_tokenを取得
    let selector = Selector::parse("input[name=\"csrf_token\"]").unwrap();
    let body = client.get("https://atcoder.jp/login").send()?.text()?;
    let document = scraper::Html::parse_document(&body);
    let csrf_token = document
        .select(&selector)
        .next()
        .unwrap()
        .value()
        .attr("value")
        .unwrap()
        .to_string();

    let params = [
        ("username", &user),
        ("password", &pass),
        ("csrf_token", &csrf_token),
    ];

    let response = client
        .post("https://atcoder.jp/login")
        .query(&params)
        .send()?;

    response.error_for_status()?;

    println!("ログイン成功");

    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    login()?;

    Ok(())
}

まとめ

cookieの保存のあたりで苦戦しましたがRustフォーラムの記事に助けられました。

参考文献

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1