entry-header-eye-catch.html
entry-title-container.html

entry-header-author-info.html
Article by

VRoid Hubにデバイスフローを実装した話

VRoid部でエンジニアとしてアルバイトをしているxxarupakaxx(@arupaka03254)です。

2月末にVRoid SDK v0.1.3がリリースされましたね!!🎉 

そのリリースには新しい機能が追加されました。デバイスフローという認可フローの追加です。

ちなみに、デバイスフローとはスマートテレビやVRのようなブラウザ操作が難しいデバイスに対する認可の仕方のことです。

VRoid SDKを用いてVRアプリケーションを作成するときに今まではVR内でブラウザを開き、ログインするためにIDとpasswordを入力して、、、といったVRでは面倒でユーザー体験の悪いものがデバイスフローの実装により、非常に改善されました。

デバイスフローとは

最初に簡単に説明しましたが、OAuthプロトコルの認可フローの一つでブラウザが搭載されていないデバイスまたは文字入力が困難なデバイスに対する認可フローのことです。

例えば、VRアプリケーションでユーザーの連携を行うとすると、スマホやPCなどでアプリ上に表示されている認可URLを開き、アプリ上に表示されている6桁のコードを入力します。それだけでアプリのユーザーの連携が完了してしまうのだ、という感じです。

デバイスフロー簡易図

技術的な解説

シーケンス図を用いて説明していきます。

  • POST /authorize_device

まず、POST /authorize_device を叩くことでDevice Flowを開始します。以下のパラメータを含めてapplication/x-www-form-urlencoded でリクエストします。

パラメータ 説明
client_id クライアントID
scope アクセス範囲の設定

レスポンスとして以下のデータがかえってきます。

{
    // デバイスの認可コード
    device_code: abcdekgla
    // エンドユーザーの認可コード
    user_code: 111111
    // エンドユーザーがアクセスする認可URL
    verification_uri: https://hub.vroid.com/code
    // エンドユーザーがアクセスする認可URLにuser_codeが入力されたもの
    verification_uri_complete: https://hub.vroid.com/code?user_code=111111
    // user_codeの有効期限
    expires_in: 180
    // トークンエンドポイントのポーリング間隔
    interval: 5
}

上記のデータを使って、エンドユーザーにユーザーコード認可先URLを示した認可画面を提示します。

  • POST /token 一定の間隔でポーリング

①と同時にトークンエンドポイントに一定の間隔で以下のパラメータでリクエストを投げます。認可が完了したときにトークンを取得できるようになりポーリングが終了します。

パラメータ 説明
client_id クライアントID
device_code デバイスコード
grant_type urn:ietf:params:oauth:grant-type:device_code

ポーリング中は以下のエラーコードがレスポンスとして返ってきます。authorization_pendingslow_down のエラーコードが返ってきた場合にトークンエンドポイントにポーリングを継続するようになっています。そして有効期限内に(今回は180秒)エンドユーザーが認可すれば、トークンが取得できるようになります。

エラーコード 説明
authorization_pending エンドユーザーがまだ認可していない
slow_down authorization_pending と同じだがポーリング間隔を5秒増加する
access_denied 認可が却下された
expired_token 有効期限が切れた

エンドユーザーが、①で得られた認可先URL https://hub.vroid.com/code にアクセスすると以下の画面が表示されます。ここで認可画面に表示されている6桁の数字のユーザーコードを入力します。

  • POST /code

エンドユーザーが正常にユーザーコードを入力し上記の画像のボタンを押せば、POST /code に以下のパラメータでリクエストされます。このエンドポイントにより⑤でトークンが取得できるようになります。

パラメータ 説明
user_code ユーザーコード

また、ユーザー認証の検証や有効期限である180秒が過ぎれば再認可を促すような検証を行うエンドポイントでもあります。

  • ⑥ 連携完了

アクセストークンが正常に取得できれば、以下の画面が表示され連携完了です。

どうやって実装した??

OAuthって言われると難しいと思っちゃいますが実装にはあまり困りませんでした。なぜなら、VRoidのバックエンドは、Railsが使われているんです。つまりそういうことですね。

doorkeeperに拡張できるライブラリを使用して実装しました。doorkeeperとは簡単にいうとOAuth 2 プロバイダを簡単に導入できるライブラリです。

使用したライブラリはdoorkeeper-device_authorization_grantというものでREADMEに書かれているようなコマンドを叩くとほぼ実装が終わります。それにモンキーパッチをあてVRoid用にカスタマイズしていきました。たとえば、数字の入力を英数字8桁を数字6桁にするなどVRアプリで使いやすいようにしました。

github.com

実際に使ってみよ!!!

実際にVRoid SDKのExampleを用いてデバイスフローで連携してみたいと思います!!
今回は、VRではなくUnityからVRoidと連携してみます。(UnityをVRとしてみてね)
VRだとコントローラーで文字を一つ一つ入力するというのが難しいので非常にスムーズなものになったかと思います。

www.youtube.com

最後に

去年の春インターンに来ていただいた方に実装を任せていましたが、ようやくリリースされて嬉しいですね。いつかVRにQRコードが読み込みができるようになれば、認可先URLのQRコードを読み込むだけで認可が完了するようにしたいな!!

VRoid SDKの開発者を募集しています。興味のある方は是非!

inside.pixiv.blog

xxarupakaxx
VRoidでエンジニアアルバイトをしています。最近はgRPCにハマってます。