我在我的应用程序上使用 Devise,并希望创建一个全局 API 密钥,无需登录即可访问任何人帐户的 JSON 数据。
例如,假设我的 API Key 是1234
,我有两个用户创建了两个不同的餐厅。
- 用户 1 - 餐厅 1 (/restaurants/1)
- 用户 2 - 餐厅 2 (/restaurants/2)
我打开了一个全新的浏览器并且没有登录任何东西,然后我传入了我的 URL .../restaurants/2.json?api_key=1234
,我应该能够访问该餐厅的 JSON 数据,而无需以用户 2身份登录
最好的方法是什么?
我遵循了Railscast #352 Securing an API,因此我可以通过传入 API 密钥来访问 JSON 内容,但我必须登录才能看到任何内容。
编辑 1:使用 CanCan
我应该提到我也在使用 CanCan 作为角色,但不确定在这种情况下它是否会扮演任何角色(双关语不是有意的)。
编辑 2:使用 API 版本控制实现
我遵循了 Railscast #350 和 #352,它们教你如何创建 REST API 版本控制以及如何使用 API 密钥保护它。
这是我的控制器/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!
代码。
解决方案
我首先遵循Railscast #350 on REST API Versioning并将所有 JSON API 调用移至/apps/api/v1/...
然后,按照下面史蒂夫乔根森的解决方案,确保我的 API 模块继承自ActionController::Base
而不是,ApplicationController
这样它就绕过before_filter :authenticate_user!
了ApplicationController
.
所以,我的编辑 2 代码看起来像这样:
module Api
module V1
class RestaurantsController < ApplicationController
...
到
module Api
module V1
#Replace 'ApplicationController' with 'ActionController::Base'
class RestaurantsController < ActionController::Base
...