문제

모든 사용자 인증 코드를 한 곳, 즉 lib/auth.rb에 넣었습니다. 다음과 같이 보입니다.

lib/auth.rb

module Admin

  def do_i_have_permission_to?(permission)
    # Code to check all of this goes here
  end

end

이 모듈은 응용 프로그램 도우미의 일부로 포함하므로 이러한 기능은 모든보기에서 사용할 수 있습니다.

application_helper.rb

require 'auth'
module ApplicationHelper
  include Admin
  # other stuff here
end

또한 응용 프로그램 컨트롤러의 일부로 포함하므로 컨트롤러도 기능을 호출 할 수 있습니다.

application.rb

require 'auth'
class ApplicationController < ActionController::Base
  include Admin
end

여태까지는 그런대로 잘됐다.

문제는 내 응용 프로그램이 일반적인 웹 앱과 같지 않다는 것입니다. 구체적으로, 동일한 컴퓨터에서 동시에 동일한 컴퓨터에서 시스템에 하나 이상의 사용자를 로그인 할 수 있습니다 (동일한 브라우저 사용). 나는 해당 IP에서 로그인 한 모든 사람들을보고 행동에 대한 인증을 수행하고 모두가 할 수 있다면 통과합니다.

이것이 의미하는 바는, 관리자가 무언가를 원한다면 그 관리자가 다른 모든 사람들을 먼저 로그인해야하는데, 이는 성가신 것입니다. 그러나 우리는 관리자가하는 모든 일에 대한 Admin의 승인을 원합니다. 따라서 나에게 주어진 제안은 관리자가 일반적으로 액세스 할 수없는 모든 페이지에 사용자 이름/암호 콤보를 제공 할 수 있도록 (예 : 'Edit User'페이지는 이러한 추가 입력 필드를 가짐) 및 인증 루틴은 그것을 확인하십시오. 이것은 의미합니다

Admin::do_i_have_permission_to?(permission)

현재 요청 매개 변수를 가져와야합니다. 매개 변수가 정의되지 않기 때문에 컨트롤러에서와 마찬가지로 Params [: foo]를 사용할 수 없습니다. 마찬가지로 request.parameters [: foo]도 작동하지 않습니다. 내 검색이 공개되었습니다.

  • 현재 검색 매개 변수는 현재 요청에 있습니다.
  • 현재 요청은 현재 컨트롤러에 있으며
  • 현재 컨트롤러는 현재 디스패처에 있으며
  • 현재 디스패처가 어디에나 유지되는지 잘 모르겠습니다.

즉, 경험에 따르면이 많은 후프를 뛰어 넘을 때 아마도 잘못하고 있다고합니다. 그렇다면 올바른 방법은 무엇입니까? 내가 고려한 옵션은 다음과 같습니다.

  • 현재 Auth.rb의 모든 기능을 ApplicationHelper로 이동하여 요청 등에 액세스 할 수 있습니다. 효과가 있지만 도우미에서 지옥을 막습니다.
  • 모든 기능을 다른 곳으로 이동하여 해당 방법을 볼 수 있습니다 (어디서 모르겠습니다)
  • 난 그냥 뭔가 빠졌어요.
도움이 되었습니까?

해결책

일반적인 Rails 응용 프로그램에서 인증 정보는 매개 변수가 아닌 활성 세션에 저장됩니다. 따라서 원하는 것을하는 도우미를 쓰는 것은 매우 간단합니다.

그런 다음 ApplicationHelper에 포함 된 모듈을 만드는 것은 정통적인 것 같습니다. 전통적인 접근 방식은이 경우 AuthenticationHelper라고 할 별도의 도우미를 만드는 것입니다. 그런 다음 필요한 컨트롤러에 포함되거나 원하는 경우 ApplicationController에로드하여 보편적으로 사용할 수 있도록 할 수 있습니다.

일반적으로 도우미는 다른 도우미를 포함해서는 안됩니다. 주어진 컨트롤러에 여러 도우미를로드하는 것이 좋습니다.

도우미 방법은 작동중인 컨트롤러 컨텍스트 내에서 선언 된 인스턴스 변수에 완전히 액세스 할 수 있습니다. 구체적으로, 이들은 인스턴스 변수 만 (@name)로 국소 변수 (이름)가 아닙니다. 도우미 방법은 특정보기에도 실행됩니다.

또한, 사용자가 적어도 기존 웹 기반 앱에 대해 동일한 단계에서 자격 증명을 제공하고 작업을 수행하는 이유를 잘 모르겠습니다. 일반적으로 프로세스는 로그인 한 다음 별도로 작업을 수행하는 것입니다.

그러나 각 트랜잭션이 독립적 인 작업 인 API의 경우 가장 간단한 접근 방식은 인증을 다루는 관련 요청 매개 변수를 꺼내고 일부 컨트롤러 인스턴스 변수를 설정 한 다음 주어진 특정 요청을 수행하는 것입니다. 자격 증명이 부과하는 제약.

내가 이런 종류의 일에 대해 일반적으로 따르는 접근법은 ApplicationController 자체의 인증 구조를 계층화하여 필요한 검사를 수행하는 것입니다. 이들은 보호 된 방법입니다.

can_edit_user와 같은 전체 더미에 굴려가는 유혹이 있습니까? 그리고 can_create_group? 이것들은 매우 빨리 손을 떼고 있습니다. 일반 목적 Can_perform의 고리를 넣는 것이 더 간단한 디자인입니까? 아니면 has_authority_to? 작업이 통과되는 방법 및 필요한 매개 변수.

예를 들어, 매우 거친 구현 :

  class ApplicationController < ActionController::Base
  protected
    def has_authority_to?(operation, conditions = { })
      AuthenticationCheck.send(operation, conditions)
    rescue
      false
    end
  end

  module AuthenticationCheck
    def self.edit_user?(conditions)
      session_user == conditions[:user]
    end
  end

  class UserController
    # ...

    def edit
      @user = User.find(params[:id])

      unless (has_authority_to?(:edit_user, :user => @user))
        render(:partial => 'common/access_denied', :status => :forbidden)
      end
    rescue ActiveRecord::RecordNotFound
      render(:partial => 'users/not_found')
    end
  end

분명히 당신은 반복을 피하고 일관성을 촉진하기 위해 많은 권한 검사를 prever_filter 블록으로 롤링하고 싶을 것입니다.

전체 프레임 워크 예제는 팔찌 사용자 인증 시스템과 같은 더 많은 도움이 될 수 있습니다.

http://github.com/theworkinggroup/wristband/tree/master

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top