Fil*_*ero 12 authentication api json ruby-on-rails devise
我正在我的应用程序上使用Devise,并希望创建一个全局API密钥,可以访问任何人的帐户的JSON数据,而无需登录.
例如,假设我的API密钥是1234,我有两个用户创建了两个不同的餐厅.
我打开一个全新的浏览器,没有登录任何东西,我传入我的URL .../restaurants/2.json?api_key=1234,我应该能够访问该餐厅的JSON数据,而无需登录用户2
什么是最好的方法呢?
我已经按照Railscast#352保护API,所以我可以通过传入API密钥来访问JSON的东西,但我必须登录才能看到任何内容.
我应该提一下,我也在使用CanCan作为角色,但不确定在这种情况下是否会扮演任何角色(双关语).
我按照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
Run Code Online (Sandbox Code Playgroud)
我application_controller.rb仍然有before_filter :authenticate_user!代码.
我首先在REST API版本控制上遵循Railscast#350并将所有JSON API调用移到/apps/api/v1/...
然后,遵循下面的Steve Jorgensen的解决方案,确保我的API模块继承ActionController::Base而不是ApplicationController绕过Devise的before_filter :authenticate_user!代码ApplicationController.
所以,我的Edit 2代码看起来像这样:
module Api
module V1
class RestaurantsController < ApplicationController
...
Run Code Online (Sandbox Code Playgroud)
至
module Api
module V1
#Replace 'ApplicationController' with 'ActionController::Base'
class RestaurantsController < ActionController::Base
...
Run Code Online (Sandbox Code Playgroud)
Sea*_*ean 14
我知道自从被问到这个问题已经有一段时间了,但我想我会再投入一个我过去使用过的选项
class Api::ApplicationController < ApplicationController
skip_before_filter :authenticate_user!
Run Code Online (Sandbox Code Playgroud)
这假设您的API目录中有一个应用程序控制器,您的所有api控制器都继承自该控制器.如果没有,您可以将跳过放在每个控制器中.
Gaz*_*ler 10
您可以before_filter在控制器中执行此操作.
目前,你可能有类似的东西:
class SomeController < ApplicationController
before_filter :authenticate_user!
end
Run Code Online (Sandbox Code Playgroud)
您可以定义一个不同的方法(理想情况下在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
Run Code Online (Sandbox Code Playgroud)
我建议使用更强大的身份验证方法,如OAuth,但这应该适用于简单的基于1键的身份验证.
没有人提到的一个选项是为API提供一组完全独立的控制器,这些控制器不会从中继承ApplicationController.
我已经看到了API控制器存在于文件中的模式,例如,/app/controllers/api/v1/somethings.rb可通过以下路由访问/api/v1/somethings.每个特定的API控制器都继承自继承自的基本API控制器ActionController::Base,因此不包括在其上定义的任何过滤器ApplicationController.
Gazler的另一种选择是使用以下:
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
Run Code Online (Sandbox Code Playgroud)
这样您就不会将整个应用程序打开给密钥持有者(根据您的需要,您是否需要).如果您需要多个方法打开键,您可能还可以使用以下内容:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16152 次 |
| 最近记录: |