2015-10-25 85 views
2

我有一個集成了Devise和Doorkeeper的RAILS API。我的POST請求註冊#創建工作,但PUT/PATCH/DELETE導致「401未授權」錯誤。我懷疑這可能是在Devise上進行身份驗證的一些問題,但那是我卡住的地方。也許我錯過了如何處理current_user或skip_before_filters?我已經嘗試了一些東西,如添加401使用Devise和Rails-API未經授權的PUT/PATCH/DELETE

skip_before_filter :verify_authenticity_token 
skip_before_filter :authenticate_user! 

謝謝!

的routes.rb

require 'api_constraints' 

Rails.application.routes.draw do 

    use_doorkeeper 
    devise_for :users, only: [:registrations, :passwords, :confirmations], controllers: {registrations: "api/registrations"}, defaults: { format: :json } 

    namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do 
     scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do 
      get 'users/me', to: 'users#me' 
     end 
    end 
end 

耙路由

Prefix Verb URI Pattern         Controller#Action 
          GET /oauth/authorize/:code(.:format)    doorkeeper/authorizations#show 
     oauth_authorization GET /oauth/authorize(.:format)     doorkeeper/authorizations#new 
          POST /oauth/authorize(.:format)     doorkeeper/authorizations#create 
          DELETE /oauth/authorize(.:format)     doorkeeper/authorizations#destroy 
       oauth_token POST /oauth/token(.:format)      doorkeeper/tokens#create 
      oauth_revoke POST /oauth/revoke(.:format)      doorkeeper/tokens#revoke 
     oauth_applications GET /oauth/applications(.:format)    doorkeeper/applications#index 
          POST /oauth/applications(.:format)    doorkeeper/applications#create 
    new_oauth_application GET /oauth/applications/new(.:format)   doorkeeper/applications#new 
    edit_oauth_application GET /oauth/applications/:id/edit(.:format)  doorkeeper/applications#edit 
     oauth_application GET /oauth/applications/:id(.:format)   doorkeeper/applications#show 
          PATCH /oauth/applications/:id(.:format)   doorkeeper/applications#update 
          PUT /oauth/applications/:id(.:format)   doorkeeper/applications#update 
          DELETE /oauth/applications/:id(.:format)   doorkeeper/applications#destroy 
oauth_authorized_applications GET /oauth/authorized_applications(.:format)  doorkeeper/authorized_applications#index 
oauth_authorized_application DELETE /oauth/authorized_applications/:id(.:format) doorkeeper/authorized_applications#destroy 
     oauth_token_info GET /oauth/token/info(.:format)     doorkeeper/token_info#show 
      user_password POST /users/password(.:format)     devise/passwords#create {:format=>:json} 
     new_user_password GET /users/password/new(.:format)    devise/passwords#new {:format=>:json} 
     edit_user_password GET /users/password/edit(.:format)    devise/passwords#edit {:format=>:json} 
          PATCH /users/password(.:format)     devise/passwords#update {:format=>:json} 
          PUT /users/password(.:format)     devise/passwords#update {:format=>:json} 
cancel_user_registration GET /users/cancel(.:format)      api/registrations#cancel {:format=>:json} 
     user_registration POST /users(.:format)        api/registrations#create {:format=>:json} 
    new_user_registration GET /users/sign_up(.:format)      api/registrations#new {:format=>:json} 
    edit_user_registration GET /users/edit(.:format)      api/registrations#edit {:format=>:json} 
          PATCH /users(.:format)        api/registrations#update {:format=>:json} 
          PUT /users(.:format)        api/registrations#update {:format=>:json} 
          DELETE /users(.:format)        api/registrations#destroy {:format=>:json} 
     user_confirmation POST /users/confirmation(.:format)    devise/confirmations#create {:format=>:json} 
    new_user_confirmation GET /users/confirmation/new(.:format)   devise/confirmations#new {:format=>:json} 
          GET /users/confirmation(.:format)    devise/confirmations#show {:format=>:json} 
      api_users_me GET /users/me(.:format)       api/v1/users#me {:format=>:json, :subdomain=>"api 

registrations_controller.rb(即覆蓋設計)

include ActionController::ImplicitRender 

class Api::RegistrationsController < Devise::RegistrationsController 
    clear_respond_to 
    respond_to :json 
    respond_to :html, only: [] 
    respond_to :xml, only: [] 

    skip_before_filter :verify_authenticity_token 
    before_filter :not_allowed, only: [:new, :edit, :cancel] 

    def not_allowed 
    render json: {error: "Method Not Allowed"}, status: 405 
    end 

    private 

    def sign_up_params 
    params.require(:user).permit([ 
     :email, 
     :password, 
     :password_confirmation, 
     :first_name, 
     :last_name, 
    ]) 
    end 

    def account_update_params 
    params.require(:user).permit([ 
     :email, 
     :first_name, 
     :last_name, 
     :password, 
     :password_confirmation, 
     :current_password 
    ]) 
    end 
end 

application.rb中

class ApplicationController < ActionController::API 
    respond_to :json 

    before_filter :cors_preflight_check 
    after_filter :cors_set_access_control_headers 

    def cors_preflight_check 
    if request.method == 'OPTIONS' 
     headers['Access-Control-Allow-Origin'] = '*' 
     headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS' 
     headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token' 
     headers['Access-Control-Max-Age'] = '1728000' 

     render text: '', content_type: 'text/plain' 
    end 
    end 

    def cors_set_access_control_headers 
    headers['Access-Control-Allow-Origin'] = '*' 
    headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS' 
    headers['Access-Control-Allow-Headers'] = 'Origin, Content-Type, Accept, Authorization, Token' 
    headers['Access-Control-Max-Age'] = "1728000" 
    end 

    def current_resource_owner 
    User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token 
    end 

end 
+0

'skip_before_filter:verify_authenticity_token'是禁用CSRF在控制上的保護。和'skip_before_filter:authenticate_user!'應該可以工作。 –

回答

1

您有選擇性地覆蓋Devise::RegistrationsController方法,它們是:new, :edit, :cancel

其餘方法沒有在您的班級中定義,因此他們將由Devise::RegistrationsController服務。

如果打開設計source code,您將看到:

class Devise::RegistrationsController < DeviseController 
    prepend_before_filter :require_no_authentication, only: [:new, :create, :cancel] 
    prepend_before_filter :authenticate_scope!, only: [:edit, :update, :destroy] 

正如你可以看到,:create行動不需要身份驗證,因此看不到401 POST請求作爲它create行動相匹配。

PUT/PATCH匹配update需要驗證的動作,類似地DELETE與'destroy'動作相匹配,這也需要驗證,因此您得到這個401錯誤。

要解決此問題,請在覆蓋RegistrationsController中的操作後,爲受保護的操作添加doorkeeper authorize

+0

感謝@Anial Maurya,我必須在我的自定義註冊控制器中添加'skip_before_filter:authentication_scope!'並添加'doorkeeper_authorize:api'。另外,我還必須重寫'current_user'和'update_resource'來獲取完整的CRUD操作。 –

相關問題