2016-10-17 9 views
3

Rails API를 구현하기 위해 Rails 프로젝트에 Grape를 마운트 중입니다.포도에서 특정 작업을 처리하기 전에 필터를 처리하는 방법은 무엇입니까?

이제 일부 종단점에는 인증이 필요한 작업과 인증이 필요없는 작업이 있습니다. 당신이 볼 수 있듯이, password/forget을 제외한 모든 작업은 로그인 한/인증 할 수있는 사용자가 필요로 지금

module Backend 
    module V1 
    class Users < Grape::API 
     include Backend::V1::Defaults 

     before { authenticate! } 

     resource :users do 

     desc "Return a user" 
     params do 
      requires :id, type: Integer, desc: 'User id' 
     end 
     get ':id' do 
      UsersService::Fetch.new(current_user,params).call 
     end 

     desc "Update a user" 
     params do 
      requires :id, type: Integer, desc: 'User id' 
      requires :display_name, type: String, desc: 'Display name' 
      requires :email, type: String, desc: 'Email' 
     end 
     post ':id' do 
      UsersService::Save.new(current_user,params).call 
     end 

     desc "Reset user password" 
     params do 
      requires :old_password, type: String, desc: 'old password' 
      requires :password, type: String, desc: 'new password' 
     end 
     post 'password/reset' do 
      PasswordService::Reset.new(current_user,params).call 
     end 

     desc "Forget password" 
     params do 
      requires :email, type: String 
     end 
     post 'password/forget' do 
      PasswordService::Forget.new(current_user,params).call 
     end    

     end 
    end 
    end 
end 

: 예로서

내가 좋아하는 뭔가를 보이는 users 엔드 포인트가 있습니다. 새로운 종단점을 만드는 것도 의미가 없지만 passwords라고 말하면서 password/forget을 논리적으로 말하면이 종단점은 사용자 리소스와 관련이 있어야합니다.

포도와 함께 문제가 before 필터에는 except, only과 같은 옵션이 없습니다. 특정 옵션에 필터를 적용 할 수 있습니다.

대개 어떻게 그런 케이스를 깨끗하게 처리합니까?

답변

3

namespace를 사용하여 될 수 있도록 더러운 방법, 뭔가 같은 :

module Backend 
    module V1 
    class Users < Grape::API 
     include Backend::V1::Defaults 

     namespace :users do 
     desc "Forget password" 
     params do 
      requires :email, type: String 
     end 
     post 'password/forget' do 
      PasswordService::Forget.new(current_user,params).call 
     end 

     namespace do 
      before { authenticate! } 

      desc "Return a user" 
      params do 
      requires :id, type: Integer, desc: 'User id' 
      end 
      get ':id' do 
      UsersService::Fetch.new(current_user,params).call 
      end 

      desc "Update a user" 
      params do 
      requires :id, type: Integer, desc: 'User id' 
      requires :display_name, type: String, desc: 'Display name' 
      requires :email, type: String, desc: 'Email' 
      end 
      post ':id' do 
      UsersService::Save.new(current_user,params).call 
      end 

      desc "Reset user password" 
      params do 
      requires :old_password, type: String, desc: 'old password' 
      requires :password, type: String, desc: 'new password' 
      end 
      post 'password/reset' do 
      PasswordService::Reset.new(current_user,params).call 
      end    

     end 
     end 
    end 
    end 
end 

우리는 users/password/forget에 대한 필터하기 전에 실행 못해하지만 나머지 우리가 내가 할 수있는 before { authenticate! }

+0

이 upvoted .. 지금은 허용 대답보다이처럼 – fabriciofreitag

2

한 가지 방법을 실행이 방법 생각해 보면 auth를 우회하고자하는 경로에 대해 사용자 지정 속성을 추가하려면 route_setting을 사용하는 것이 좋습니다. authenticate!을 호출하기 전에 before 필터에서 이러한 속성을 확인하십시오. 아래처럼 뭔가 작업을해야합니다 :

module Backend 
    module V1 
    class Users < Grape::API 
     include Backend::V1::Defaults 

     before { authenticate! unless route.settings[:auth] && route.settings[:auth][:disabled] } 

     resource :users do 

     desc "Return a user" 
     params do 
      requires :id, type: Integer, desc: 'User id' 
     end 
     get ':id' do 
      UsersService::Fetch.new(current_user,params).call 
     end 

     desc "Update a user" 
     params do 
      requires :id, type: Integer, desc: 'User id' 
      requires :display_name, type: String, desc: 'Display name' 
      requires :email, type: String, desc: 'Email' 
     end 
     post ':id' do 
      UsersService::Save.new(current_user,params).call 
     end 

     desc "Reset user password" 
     params do 
      requires :old_password, type: String, desc: 'old password' 
      requires :password, type: String, desc: 'new password' 
     end 
     post 'password/reset' do 
      PasswordService::Reset.new(current_user,params).call 
     end 

     desc "Forget password" 
     route_setting :auth, disabled: true 
     params do 
      requires :email, type: String 
     end 
     post 'password/forget' do 
      PasswordService::Forget.new(current_user,params).call 
     end    

     end 
    end 
    end 
end 
+0

을 수행하는 더 우아한 방법이 궁금. 네임 스페이스 접근 방식은 이전 동작이 중첩 된 네임 스페이스 내에 있어야한다는 것을 의미합니다. 이렇게하면 api 기반에 등록 할 수 있으며 일부 특정 엔드 포인트에서 제외시킬 수 있습니다 (잠재적으로 다른 파일에 있음). – erich2k8