6
4

More than 3 years have passed since last update.

VRChat APIで二段階認証する

Last updated at Posted at 2019-09-27

VRChat APIを利用する際にAPI経由でVRChatにログインしてトークンを取得することが多いのですが、二段階認証を利用している場合については記事が無かったのでメモします

ざっくり概要を書くと、
まず通常ログインでトークンを取得。ただし二段階認証が有効になっている場合、トークンは使えない
トークン取得後に二段階認証する(Google Authenticatorから取得した番号をPOSTする)とトークンが有効化される
といった流れになります。

注意

この記事で使用しているVRChat APIの仕様は非公式なドキュメントに基づくものです。
公式からは悪意のないAPI利用はいいけど他人にPW入力させたらダメと言及されていますので、その点ご注意ください。

1. VRChatから認証トークンを取得

まずはVRChatからトークンを取得します。手順は以下の通りです。
1. https://api.vrchat.cloud/api/1/config をGETしてapiKeyを取得
2. https://api.vrchat.cloud/api/1/auth/user をGETしてauthTokenを取得 (VRChatのユーザ名・パスワードでBasic認証を行う)
※Basic認証時、トークンはCookieに返ってくるので注意!

rubyで書くとこんな感じです。GETするあたりは最低限必要な分だけ書いてます。

VRChatBasicAuth
def login_vrc
    username = "VRCのユーザー名"
    password = "VRCのパスワード"
    api_base = "https://api.vrchat.cloud/api/1"

    # 後々二段階認証で使うのでapiKeyとauthTokenはセッションに保管しています
    # apiKey取得
    apikey = get_apiKey(api_base)
    session[:apiKey] = apiKey

    # authToken取得
    session[:authToken] = get_authToken(api_base, apikey, username, password)
end

def get_apikey(api_base)
    endpoint = "/config"
    url = api_base + endpoint
    uri = URI.parse(url)
    req = Net::HTTP::Get.new(uri)
    Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https'){ |http| 
      response = http.request(req)
      @json = response.body
    }
    apikey_json = JSON.parse(@json)
    return apikey_json["clientApiKey"]
end

def get_authToken(api_base, apikey, username, password)
    endpoint = "/auth/user"
    url = api_base + endpoint
    uri = URI.parse(url)
    uri.query = URI.encode_www_form(apiKey: apikey)
    req = Net::HTTP::Get.new(uri)
    req.basic_auth(username, password)
    Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') { |http| 
      response = http.request(req)
      @cookie = response.get_fields('Set-Cookie')
    }

    #取得したCookieからauthTokenを抽出する(かなり強引なので正直直したい)
    cookie = @cookie.select { |x|
      x.include?("auth")
    }
    unless cookie[0].nil?
      return cookie[0]
    end
end

2. トークンを有効化

先ほど取得したapiKeyとauthToken、それとGoogle Authenticatorから取得した番号をhttps://api.vrchat.cloud/api/1/auth/twofactorauth/totp/verify にPOSTします。

認証が成功するとverified = tureが返ってきて、authTokenが各種APIで利用できるようになります。

VRChat2FA
def twofa_vrc
    num = "Google Authenticatorから取得した番号"
    api_base = "https://api.vrchat.cloud/api/1"
    endpoint = "/auth/twofactorauth/totp/verify"
    url = api_base + endpoint
    uri = URI.parse(url)
    uri.query = URI.encode_www_form(apiKey: session[:apikey])
    req = Net::HTTP::Post.new(uri)
    req["Cookie"] = session[:auth_token]
    req.set_form_data('code' => num)
    Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') { |http| 
      response = http.request(req)
      @json = response.body
    }

    #認証成功するとtwofa_result = trueになります
    twofa_result = JSON.parse(@json)["verified"]
end

参考

6
4
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
6
4