Ruby on Rails:cURL DELETE令牌认证

时间:2014-06-07 01:29:35

标签: ruby-on-rails ruby rest curl ruby-on-rails-4

我想为RoR中的服务器做REST API,移动应用程序将使用它。

我的项目非常基于

http://lucatironi.github.io/tutorial/2012/10/15/ruby_rails_android_app_authentication_devise_tutorial_part_one/

并且因为在DEVISE gem的最新版本中没有令牌认证,我也使用这种方式:

https://gist.github.com/josevalim/fb706b1e933ef01e4fb6

现在出现了我的问题 - 当我使用cURL测试API时,POST(登录)是正确的,但是DELETE(注销)无法正常工作。我正在输入终端:

curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X DELETE http://localhost:3000/api/v1/sessions/\?auth_token\=CvX8WZr2MjVhWYxxEXYy

curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X DELETE http://localhost:3000/api/v1/sessions -d "{\"auth_token\":\"CvX8WZr2MjVhWYxxEXYy\"}"

(当然,我的特定令牌)我有答案:

{"error":"You need to sign in or sign up before continuing."} with HTTP/1.1 401 Unauthorized

另外还有服务器日志:

Started DELETE "/api/v1/sessions" for 127.0.0.1 at 2014-06-07 03:11:17 +0200
Processing by Api::V1::SessionsController#destroy as JSON
  Parameters: {"auth_token"=>"CvX8WZr2MjVhWYxxEXYy", "session"=>{"auth_token"=>"CvX8WZr2MjVhWYxxEXYy"}}
Completed 401 Unauthorized in 1ms

我的密钥文件代码:

application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

    before_filter :authenticate_user_from_token!
    before_filter :authenticate_user!

    private
    def authenticate_user_from_token!
        user_email = params[:user_email].presence
        user = user_email && User.find_by_email(user_email)

        if user && Devise.secure_compare(user.authentication_token, params[:user_token])
            sign_in user, store: false
        end
    end
end

sessions_controller.rb

class Api::V1::SessionsController < Devise::SessionsController
  skip_before_filter :verify_authenticity_token,
                     :if => Proc.new { |c| c.request.format == 'application/json' }

  respond_to :json

  def create
    warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
    render :status => 200,
           :json => { :success => true,
                      :info => "Logged in",
                      :data => { :auth_token => current_user.authentication_token } }
  end

  def destroy
    warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
    current_user.update_column(:authentication_token, nil)
    render :status => 200,
           :json => { :success => true,
                      :info => "Logged out",
                      :data => {} }
  end

  def failure
    render :status => 401,
           :json => { :success => false,
                      :info => "Login Failed",
                      :data => {} }
  end
end

user.rb

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable

  attr_accessible :name, :email, :password, :password_confirmation, :remember_me

  before_save :ensure_authentication_token

  def ensure_authentication_token
      if authentication_token.blank?
          self.authentication_token = generate_authentication_token
      end
  end

  def skip_confirmation!
      self.confirmed_at = Time.now
  end

  private

  def generate_authentication_token
      loop do
          token = Devise.friendly_token
          break token unless User.where(authentication_token: token).first
      end
  end
end

的routes.rb

Ihome::Application.routes.draw do
  get "welcome/index"
  devise_for :users

  root 'welcome#index'

  namespace :api do
    namespace :v1 do
      devise_scope :user do
        post 'sessions' => 'sessions#create', :as => 'login'
        delete 'sessions' => 'sessions#destroy', :as => 'logout'
      end
    end
  end
end

什么是错误的,因为我分析了整个程序而我找不到错误的原因?

2 个答案:

答案 0 :(得分:0)

我在SimpleTokenAuthentication的GitHub问题中引用了这个问题,这是一个实现令牌认证模式的gem。有关gem的更多信息,请参阅https://github.com/gonzalo-bulnes/simple_token_authentication

我最初认为您的问题与我遇到的问题相同,因为我也只是在注销操作上获得401。但是,@ gonzalo-bulnes似乎已经发现了你的问题。

请参阅https://github.com/gonzalo-bulnes/simple_token_authentication/issues/76#issuecomment-46836215

  

...不是ukson忘记提供user_email参数吗?代币   仅使用auth_token无法执行身份验证。 (事实上​​,   JoséValim的要点是解释如何执行该操作   e-mail cross-checking   实现令牌认证时。)

从我自己对你的代码的评论来看,他似乎是正确的。尝试添加此参数,看看是否有帮助!

答案 1 :(得分:0)

我认为问题可能是您用来传递令牌值的参数名称以及电子邮件值丢失的事实(已经做出了什么样的贡献)。

在authenticate_entity_from_token中! act_as_token_authentication_handler.rb文件中的方法有以下内容:

params_token_name =“#{entity_class.name.singularize.underscore} _token”.to_sym params_email_name =“#{entity_class.name.singularize.underscore} _email”.to_sym

在你的情况下,这意味着curl命令应该是:

curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X DELETE http://127.0.0.1:3000/api/v1/sessions/\?user_token\=CvX8WZr2MjVhWYxxEXYy\&user_email=user@example.com