VRChat APIを利用する際にAPI経由でVRChatにログインしてトークンを取得することが多いのですが、二段階認証を利用している場合については記事が無かったのでメモします
ざっくり概要を書くと、
まず通常ログインでトークンを取得。ただし二段階認証が有効になっている場合、トークンは使えない
トークン取得後に二段階認証する(Google Authenticatorから取得した番号をPOSTする)とトークンが有効化される
といった流れになります。
##注意
この記事で使用しているVRChat APIの仕様は非公式なドキュメントに基づくものです。
公式からは悪意のないAPI利用はいいけど他人にPW入力させたらダメと言及されていますので、その点ご注意ください。
1. VRChatから認証トークンを取得
まずはVRChatからトークンを取得します。手順は以下の通りです。
- https://api.vrchat.cloud/api/1/config をGETしてapiKeyを取得
-
https://api.vrchat.cloud/api/1/auth/user をGETしてauthTokenを取得 (VRChatのユーザ名・パスワードでBasic認証を行う)
※Basic認証時、トークンはCookieに返ってくるので注意!
rubyで書くとこんな感じです。GETするあたりは最低限必要な分だけ書いてます。
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で利用できるようになります。
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
##参考