2014-03-13 2 views
1

모든 경로에 기본적으로 사용자 로그인이 필요한 Sinatra 앱이 있습니다. 이런 식으로 뭔가 :필터를 조건으로하기 전에

before do 
    env['warden'].authenticate! 
end 

get :index do 
    render :index 
end 

가 지금은 예외를 만들기 위해 사용자 정의시나 조건을 사용하고 싶지만, 조건에 해당하면 내가 읽을 수있는 방법을 찾을 수 없습니다/허위/전무

def self.public(enable) 
    condition { 
    if enable 
     puts 'yes' 
    else 
     puts 'no' 
    end 
    } 
end 

before do 
    # unless public? 
    env['warden'].authenticate! 
end 

get :index do 
    render :index 
end 

get :foo, :public => true do 
    render :index 
end 

이후 조건이 정의되지 않은 경우에도 인증 확인을 수행해야합니다. 그래도 before 필터를 사용해야하지만 내 사용자 정의 조건에 액세스하는 방법을 모르겠습니다.

+0

public 메서드는 클래스 메서드로 정의 되었기 때문에 컨텍스트에서 사용할 수 없습니다. 메소드가 인스턴스 메소드 (자체 없음)로 정의 된시기를 확인 했습니까? – MikeZ

+0

메소드를 인스턴스 (자체 없음)로 정의하면이를 규칙 조건으로 사용할 수 없으며 DSL에서 공개 URL을 작성하는 방식을 유지하고자합니다. 요청 객체의 조건을 읽거나 ** 모든 규칙에 대한 기본 조건으로 ** public => false **를 정의하기 전에 **에 대해 생각했습니다. 어쨌든 기본 규칙에 대한 몇 가지 예외를 지정하는 쉬운 방법이 필요했습니다. – SystematicFrank

+0

내가 주목 한 것은 필터가 ** 필터를 거쳐 파싱 된 것 같은데, 그게 아이디어가 다 떨어지는 시점이었습니다. – SystematicFrank

답변

1

Sinatra의 helpers을 사용하여이 문제를 해결할 수 있었고 Sinatra의 internals을 파고들 수있었습니다. 나는 이것이 당신을 위해 일해야한다고 생각합니다 :

helpers do 
    def skip_authentication? 
    possible_routes = self.class.routes[request.request_method] 

    possible_routes.any? do |pattern, _, conditions, _| 
     pattern.match(request.path_info) && 
     conditions.any? {|c| c.name == :authentication } 
    end 
    end 
end 

before do 
    skip_authentication? || env['warden'].authenticate! 
end 

set(:authentication) do |enabled| 
    condition(:authentication) { true } unless enabled 
end 

get :index do 
    render :index 
end 

get :foo, authentication: false do 
    render :index 
end 
관련 문제