Я использую Devise для своего приложения и хотел бы создать глобальный ключ API, который может получить доступ к данным JSON любой учетной записи без необходимости входа в систему.
Например, скажем, мой API-ключ 1234
, и у меня есть два пользователя, которые создали два разных ресторана.
- Пользователь 1 - Ресторан 1 (/рестораны/1)
- Пользователь 2 - Ресторан 2 (/рестораны/2)
И я открываю совершенно новый браузер и нигде не вошел, и я перехожу в свой URL .../restaurants/2.json?api_key=1234
, я должен иметь доступ к данным JSON этого ресторана без необходимости входа в систему как User 2
Каков наилучший способ сделать это?
Я следил за Railscast # 352 Защита API, поэтому я могу получить доступ к материалам JSON, передав ключ API, но я должны войти в систему, чтобы увидеть что-нибудь.
Изменить 1: Использование CanCan
Я должен упомянуть, что я также использую CanCan для ролей, но не уверен, что это сыграет какую-либо роль (каламбур не предназначен) в этой ситуации.
Редактировать 2: Имплементирование с версией API
Я следил за Railscast # 350 и # 352, которые рассказывают вам, как создавать REST API Versioning и как его защищать с помощью API-ключа.
Здесь мои контроллеры /api/v 1/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!
.
Решение
Я сначала выполнил Railscast # 350 в REST API Versioning и переместил все мои вызовы API JSON на /apps/api/v1/...
Затем, следуя приведенному ниже решению Стив Йоргенсена, убедитесь, что мой API-модуль унаследован от ActionController::Base
вместо ApplicationController
, чтобы он обошел код Devise 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
...