如何使用API​​密钥时跳过设计验证? [英] How to skip Devise authentication when using an API key?

查看:213
本文介绍了如何使用API​​密钥时跳过设计验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用我的应用程序设计,并想创建可以访问任何人的帐户的JSON数据,而无需登录在全球API密钥。

举例来说,说我的API密钥 1234 和我有谁创建了两个不同的餐厅,两个用户。


  • 用户1 - 餐厅1(/餐厅/ 1)

  • 用户2 - 餐厅2(/餐厅/ 2)

和我打开一个全新的浏览器,并没有记录到任何东西,我通过了我的网址 ... /餐厅/ 2.json?API_KEY = 1234 ,我应该能够访问该餐厅的JSON数据,而无需登录作为的用户2

最新最好的方式做到这一点?

我跟着 Railscast#352保护的API 所以我能够访问JSON东东通过传入API密钥,但我必须登录才能看到任何东西。

编辑1:使用惨惨

我要指出,我还使用了黄灿灿的角色,但不知道这会起到这种情况下,任何角色(双关语不打算)。

编辑2:API版本Implimenting

我跟着Railscast#350和#352这教你如何创建REST API版本,以及如何使用API​​密钥将其固定。

下面是我的控制器/ API / V1 /餐厅/ restaurants_controller.rb的样子:

 模块API
  模块V1
    类RestaurantsController< ApplicationController中
      的before_filter:RESTRICT_ACCESS      respond_to代码:JSON      高清指数
        respond_with Restaurant.all
      结束      高清节目
        respond_with Restaurant.find(PARAMS [:ID])
      结束    私人的      高清RESTRICT_ACCESS
        API_KEY = ApiKey.find_by_access_token(PARAMS [:API_KEY])
        头:未经授权,除非API_KEY
      结束
    结束
  结束
结束

和我的 application_controller.rb 仍具有的before_filter:!的authenticate_user code在它

解决方案

我第一次跟着 Railscast#350的REST API版本并感动了所有我的JSON API调用 /应用/ API / V1 /...

然后,按以下史蒂夫·约根森的解决方案,确信我的API模块从的ActionController :: Base的而不是继承的ApplicationController 使其绕过制定的的before_filter:!的authenticate_user code在的ApplicationController

所以,我的编辑2 code时,从这样看:

 模块API
  模块V1
    类RestaurantsController< ApplicationController中
    ...

 模块API
  模块V1
    #ReplaceApplicationController中与的ActionController ::基地
    类RestaurantsController< ActionController的基地::
    ...


解决方案

没有人提到一种选择是有一个完全独立的一套控制器,用于不从的ApplicationController

我在哪里见过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​​密钥时跳过设计验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆