使用API密钥时如何跳过Devise认证? [英] How to skip Devise authentication when using an API key?
问题描述
例如,说我的API密钥是 1234
,我有两个用户创建了两个不同的餐馆。
- 用户1 - 餐厅1(/餐厅/ 1)
- 用户2 - 餐厅2(/餐厅/ 2)
我打开一个全新的浏览器,没有登录任何东西,我传入我的URL ... / restaurants / 2.json?api_key = 1234
,我可以访问该餐厅的JSON数据,而无需以用户2
最好的方法是什么?
我遵循了 Railscast#352保护API ,所以我可以通过传递API密钥来访问JSON内容,但是我必须登录才能看到任何内容。
编辑1:使用CanCan
我应该提到我也使用CanCan角色,但不知道在这种情况下是否会发挥任何作用(双关不当)
编辑2:使用API版本控制
我跟随了Railscast#350和#352教你如何创建REST API版本控制以及如何使用API密钥来保护它。
这是我的控制器/ api / v1 / restaurants / restaurants_controller.rb的样子: p>
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])
头:未授权,除非api_key
end
end
end
end
而我的 application_controller.rb
仍然有 before_filter:authenticate_user!
代码。
解决方案
我第一次跟着轨迹#350在REST API版本控制,并将所有我的JSON API调用移动到 / apps / api / v1 /...
然后,按照史蒂夫·约根森在下面的解决方案,确保y API模块继承自 ActionController :: Base
而不是 ApplicationController
,以便绕过Devise的 before_filter :$ authenticate_user!
ApplicationController
中的代码
所以,我的编辑2代码看起来像这样:
模块Api
模块V1
class RestaurantsController< ApplicationController
...
至
模块Api
模块V1
#将ApplicationController替换为ActionController :: Base
class RestaurantsController< ActionController :: Base
...
没有人提到的一个选项是对于不从 ApplicationController
继承的API拥有完全独立的控制器。
我已经看到API控制器用在诸如 /app/controllers/api/v1/somethings.rb
的文件中的模式,可以通过诸如 / API / V1 /出头
。每个特定的API控制器继承自继承自 ActionController :: Base
的基本API控制器,因此不包括在 ApplicationController上定义的任何过滤器
。
I'm using Devise on my application and would like to create a global API key that can access JSON data of anyone's account without having to log-in.
For example, say my API Key is 1234
and I have two users who have created two different restaurants.
- User 1 - Restaurant 1 (/restaurants/1)
- User 2 - Restaurant 2 (/restaurants/2)
And I open a brand new browser and haven't logged into anything and I pass into my URL .../restaurants/2.json?api_key=1234
, I should be able to access the JSON data of that restaurant without having to log-in as User 2
Whats the best way to do this?
I've followed the Railscast #352 Securing an API so I'm able to access JSON stuff by passing in the API key but I have to log-in to see anything.
Edit 1: Using CanCan
I should mention that I'm also using CanCan for roles but not sure if that'll play any role (pun not intended) in this situation.
Edit 2: Implimenting with API Versioning
I followed the Railscast #350 and #352 which teach you how to create REST API Versioning and how to secure it with an API Key.
Here's what my controllers/api/v1/restaurants/restaurants_controller.rb looks like:
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
And my application_controller.rb
still has the before_filter :authenticate_user!
code in it.
Solution
I first followed the Railscast #350 on REST API Versioning and moved all my JSON API calls to /apps/api/v1/...
Then, following Steve Jorgensen's solution below, made sure my API module inherited from ActionController::Base
instead of ApplicationController
so that it bypassed Devise's before_filter :authenticate_user!
code within the ApplicationController
.
So, my Edit 2 code when from looking like this:
module Api
module V1
class RestaurantsController < ApplicationController
...
to
module Api
module V1
#Replace 'ApplicationController' with 'ActionController::Base'
class RestaurantsController < ActionController::Base
...
One option no one has mentioned is to have a completely separate set of controllers for the API that do not inherit from ApplicationController
.
I have seen the pattern used where API controllers live in files such as /app/controllers/api/v1/somethings.rb
and are accessible via routes such as /api/v1/somethings
. Each of the specific API controllers inherits from a base API controller that inherits from ActionController::Base
, so does not include any of the filters defined on ApplicationController
.
这篇关于使用API密钥时如何跳过Devise认证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!