doorkeeper で Resource Owner Password Credentials flow を試してみた

こんにちは。ガイヤーンをたべました、きたけーです。

doorkeeper gem で、OAuth2 で定義されているアクセス権委譲のフローの中から「Resource Owner Password Credentials グラント種別」を試してみました(フローの種類のことを「グラント種別」というらしい)。

Resource Owner Password Credentials グラント種別 は 他のグラント種別と比較して、アクセストークンを得るまでの手続きが少ない。そのかわりに、(OAuthのロールでいう)クライアントがリソース所有者(アプリケーションのユーザー)のパスワードを知ってしまう。 なので、このグラント種別を選択するのは、クライアントとAPIのプロバイダが同じ場合のような、クライアントを信頼できるケース(公式のモバイルアプリなど)。

doorkeeperの導入

Gemfileに以下を追記。

gem "doorkeeper"

bundleした後に、

bin/rails g doorkeeper:install
bin/rails g doorkeeper:migration

で、doorkeeperのジェネレーターをはしらせる。 doorkeeperの設定のためのファイルがconfig/initializersに設置されたり、ルーティングの設定がconfig/routes.rbに追記されたり、 クライアントとかトークンを管理するためのテーブルを作成するマイグレーションスクリプトが生成される。

マイグレーションスクプトを走らせる。

bin/rake db:migrate

ビューファイルを上書きしたりとか他にも色々やることはあるかもしれないけど、最低限これでおしまい。サーバーを起動する。

bin/rails s

clientの登録

サーバーを起動した後に http://localhost:3000/oauth/applications から登録できる。 アプリケーションを登録した後に、client id, client secretを控えておく。

Resource Owner Password Credentials flowの設定

多分、今日一番大事なところ。Resource Owner Password Credentials flowを使うために、config/initializers/doorkeeper.rbを編集する。こんなかんじ。(Userモデルは適当に用意しておく。本当はここでパスワードのチェックもおこなう)

Doorkeeper.configure do
  # ...

  resource_owner_from_credentials do |routes|
    User.find_by(name: params[:username]) || fail("Resource Owner not found")
  end
end

設定を編集したのでサーバーを再起動する。

アクセストークンの取得

アクセストークンの取得はこんなかんじでできる。

require 'oauth2'

client_id = 'clientの登録で控えたやつ'
client_secret = 'clientの登録で控えたやつ'
client = OAuth2::Client.new(client_id, client_secret, site: 'http://localhost:3000')

access_token = client.password.get_token('kitak', 'PASSWORD')
access_token.expires_at # 有効期限
access_token.token # アクセストークン!

参考にしたもの