12

アプリケーションでDeviseを使用しており、ログインせずに誰のアカウントのJSONデータにもアクセスできるグローバルAPIキーを作成したいと考えています。

たとえば、私のAPIキーが1234であり、2つの異なるレストランを作成した2人のユーザーがいるとします。

  • ユーザー1-レストラン1-(/レストラン/ 1)
  • ユーザー2-レストラン2(/レストラン/ 2)

そして、新しいブラウザを開いて何もログインしていないので、URLを渡すと、ユーザー2.../restaurants/2.json?api_key=1234としてログインしなくても、そのレストランのJSONデータにアクセスできるはずです。

これを行うための最良の方法は何ですか?

Railscast#352 APIの保護に従って、APIキーを渡すことでJSONにアクセスできるようにしましたが、何かを表示するにはログインする必要があります。

編集1:CanCanの使用

私は役割にもCanCanを使用していることを言及する必要がありますが、この状況でそれが何らかの役割を果たすかどうかはわかりません(しゃれは意図されていません)。

編集2:APIバージョニングによる実装

Railscast#350と#352に従って、REST APIバージョン管理を作成する方法と、APIキーで保護する方法を説明しました。

私のcontrollers/api / v1 / restaurants/restaurants_controller.rbは次のようになります。

module Api
  module V1
    class RestaurantsController < ApplicationController
      before_filter :restrict_access

      respond_to :json

      def index
        respond_with Restaurant.all
      end

      def show
        respond_with Restaurant.find(params[:id])
      end

    private

      def restrict_access
        api_key = ApiKey.find_by_access_token(params[:api_key])
        head :unauthorized unless api_key        
      end
    end
  end
end

そして、私はapplication_controller.rbまだその中にbefore_filter :authenticate_user!コードを持っています。

解決

私は最初にRESTAPIバージョニングでRailscast#350に従い、すべてのJSONAPI呼び出しをに移動しました/apps/api/v1/...

次に、以下のSteve Jorgensenのソリューションに従って、APIモジュールがではActionController::Baseなくから継承されていることを確認して、内のApplicationControllerDeviseのbefore_filter :authenticate_user!コードをバイパスしましたApplicationController

だから、私のEdit 2コードは、次のようになっています。

module Api
  module V1
    class RestaurantsController < ApplicationController
    ...

module Api
  module V1
    #Replace 'ApplicationController' with 'ActionController::Base'
    class RestaurantsController < ActionController::Base
    ...
4

4 に答える 4

15

これが尋ねられてからしばらく経っていることは知っていますが、過去に使用したオプションをもう1つ追加すると思いました

class Api::ApplicationController < ApplicationController

skip_before_filter :authenticate_user!

これは、すべての API コントローラーが継承する API ディレクトリにアプリケーション コントローラーがあることを前提としています。そうでない場合は、各コントローラーにスキップを配置できます。

于 2014-03-03T20:39:05.457 に答える
12

before_filterコントローラーでこれを行うことができます。

現在、おそらく次のようなものがあります。

class SomeController < ApplicationController
  before_filter :authenticate_user!
end

これを呼び出す代わりに、別のメソッドを定義できます (理想的には ApplicationController で)。

class ApplicationController < ActionController::Base
  before_filter :authenticate_or_token

  private
  def authenticate_or_token
    if params[:api_key] == 1234
      @current_user = User.new(:admin => true, :any => "other", :required => "fields")
      return current_user
    end
    authenticate_user!
  end

OAuth などのより堅牢な認証方法を使用することをお勧めしますが、これは単純な 1 キー ベースの認証で機能するはずです。

于 2012-08-02T20:43:59.497 に答える
7

誰も言及していないオプションの 1 つは、ApplicationController.

API コントローラが などのファイルに存在し、 など/app/controllers/api/v1/somethings.rbのルートを介してアクセスできる場合に使用されるパターンを見てきまし/api/v1/somethingsた。特定の API コントローラはそれぞれ、 を継承するベース API コントローラから継承されるActionController::Baseため、 で定義されたフィルタは含まれませんApplicationController

于 2012-08-03T06:40:50.943 に答える
5

Gazler の代替手段は、except を使用することです。

class ApplicationController < ActionController::Base
  before_filter :authenticate_user!, except: :some_json_method

  def some_json_method
    render :nothing unless params[:api_key] == '1234'

    render :json
  end
end

このようにして、アプリ全体をキーホルダーに開かないようにします (必要かどうかにかかわらず、必要に応じて)。キーに対して複数のメソッドを開く必要がある場合は、おそらく次のようなものも使用できます。

class ApplicationController < ActionController::Base
  JSON_METHODS = [method_1, method2]
  before_filter :authenticate_user!, except: JSON_METHODS
  before_filter :authenticate_token, only: JSON_METHODS

  private
  def authenticate_token
    params[:api_key] == '1234'
  end
end
于 2012-08-03T06:15:35.897 に答える