【发布时间】:2012-08-02 19:43:13
【问题描述】:
我在我的应用程序中使用 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/...
然后,按照 Steve Jorgensen 的以下解决方案,确保我的 API 模块继承自 ActionController::Base 而不是 ApplicationController,以便绕过 ApplicationController 中的 Devise 的 before_filter :authenticate_user! 代码。
所以,我的 Edit 2 代码看起来像这样:
module Api
module V1
class RestaurantsController < ApplicationController
...
到
module Api
module V1
#Replace 'ApplicationController' with 'ActionController::Base'
class RestaurantsController < ActionController::Base
...
【问题讨论】:
标签: ruby-on-rails json api authentication devise