LoginSignup
5
5

More than 5 years have passed since last update.

Rails4.2 + Grape0.1 + Doorkeeper2.1

Last updated at Posted at 2015-02-08

GrapeでDoorkeeperのバージョン2系を使う

Doorkeeperがバージョン2.0で後方非互換なアップデート

Railsを使ってOAuth2でいい感じなAPIを作ってみようと思って調べてみたところ

がいい感じそう。
で、GrapeからDoorkeeperを使うのに、

というgemもしっかりあって素晴らしい。

・・・のかと思いきや、今ではDoorkeeperは2.1にメジャーバージョンアップ済み。
doorkeeper_for メソッドが doorkeeper_authorize! に置き換えられたりといろいろ変わっている。

で、grape-doorkeeperはどうやらいまのところ1.x系のDoorkeeperにしか対応してない模様。\(^o^)/

対応

詰んだかと思いかけたけど、こんな感じにしたらなんとなく動いた。

  • Grape::API でhelpersとして Doorkeeper::Rails::Helpersを読み込み
    • doorkeeper_authorize! メソッドを呼び出せるようにする
    helpers Doorkeeper::Rails::Helpers
  • ここから力技
  • doorkeeper_authorize! を呼び出す前に、 request オブジェクトに authorizationparametersメソッドを追加
    • Grape::API 内の request は、通常のRailsコントローラとは違って Grape::Request < Rack::Request
    • そのままだとDoorkeeperが呼び出そうとするメソッドが無くて落ちるので
      • authoriztion は強引に ActionPack::Request と同じメソッドを定義
      • parameters は別名の params 変数がそれにあたるはずなのでそっちを返してやる
      def authorize!
        def request.authorization
          env['HTTP_AUTHORIZATION']   ||
          env['X-HTTP_AUTHORIZATION'] ||
          env['X_HTTP_AUTHORIZATION'] ||
          env['REDIRECT_X_HTTP_AUTHORIZATION']
        end

        def request.parameters
          params
        end

        doorkeeper_authorize!
      end
  • doorkeeper_error_renderer メソッドをオーバーライド
    • エラー時にステータスコードをセットする方法もGrape流の方法に変更
      def doorkeeper_error_renderer(error, options = {})
        error! error.status, 408
      end

これで、Doorkeeperでapplication登録してauthorizeして発行された有効なaccess_tokenを持っていないリクエストは弾けるようになった。

全体のソースは以下の通り。

module GrapeDoorkeeper
  class API < Grape::API

    helpers Doorkeeper::Rails::Helpers
    helpers do
      def authorize!
        def request.authorization
          env['HTTP_AUTHORIZATION']   ||
          env['X-HTTP_AUTHORIZATION'] ||
          env['X_HTTP_AUTHORIZATION'] ||
          env['REDIRECT_X_HTTP_AUTHORIZATION']
        end

        def request.parameters
          params
        end

        doorkeeper_authorize!
      end

      def doorkeeper_error_renderer(error, options = {})
        error! error.status, 408
      end
    end

    version 'v1', using: :path
    format :json

    resource :test do
      before do
        authorize!
      end

      get do
        "Test"
      end
    end

  end
end

あとは共通クラスかモジュールに切り出すなりなんなり。

RailsもOAuthも初心者な状態なので、正しいやり方かどうかは自信無し。抜けや漏れがある可能性も大ですが、一応できたことの共有。

メソッドの追加とか我ながら強引すぎる感・・・。ご指摘などありましたら是非。

二重投稿。Rails4.2 + Grape0.1 + Doorkeeper2.1 | bookside.log

5
5
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
5
5