Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

여러 하위 도메인으로 Rails 앱 빌드

오늘의 게시물에서는 다중 하위 도메인을 지원할 수 있는 Rails 앱을 빌드하는 방법을 배웁니다. 게임 웹사이트 funkygames.co가 있다고 가정해 보겠습니다. app.funkygames.co와 같은 여러 하위 도메인을 지원하고자 합니다. , api.funkygames.codev.funkygames.co 단일 Rails 애플리케이션으로 모든 하위 도메인에 대해 적절한 인증이 수행되고 중복 경로가 없는지 확인하고자 합니다.

Rails의 강력한 라우팅 구성을 사용하여 애플리케이션에서 여러 하위 도메인을 지원합니다. 또한 로컬에서 하위 도메인을 설정하고 여러 하위 도메인에 대한 테스트를 작성합니다.

전제조건

이 게시물의 목적을 위해 모든 하위 도메인이 Rails 앱을 가리키도록 적절한 DNS 레코드를 설정했다고 가정합니다. 이 게시물에서는 Rails 측면만 다룰 것입니다.

여러 하위 도메인 처리

Rails는 routes.rb를 사용합니다. 들어오는 요청을 처리하고 특정 컨트롤러 작업에 매핑하는 파일입니다. 사소한 앱에서 routes.rb의 모든 매핑 다음과 같이 컨트롤러 작업에 경로를 매핑합니다.

  get '/games/:id', to: 'games#show'

이 접근 방식을 사용하면 routes.rb에 정의된 모든 엔드포인트가 파일은 모든 하위 도메인에 적용할 수 있습니다. 그래서 app.funkygames.co/games/1 api.funkygames.co/games/1 이 경로로 처리됩니다. 그러나 app에서 오는 요청만 원합니다. 이 경로에서 처리할 하위 도메인입니다. api 하위 도메인은 API 경로에만 사용됩니다. 들어오는 요청에 대해 특정 규칙이 충족되는 경우에만 처리되도록 몇 가지 규칙을 경로에 추가합니다.

Rails 라우팅은 constraints을 제공합니다. 주어진 경로에 대한 추가 규칙을 지정할 수 있는 도우미 메서드입니다.

  get '/games/:id', to: 'games#show', constraints: { subdomain: 'app' }

이렇게 하면 요청이 app.funkygames.co/games/1에서 오는지 확인합니다. , GamesController's에 의해 처리됩니다. 행동을 보여줍니다. app 이외의 다른 하위 도메인의 모든 요청 이 경로에서는 처리되지 않습니다.

constraints을 정의하는 것은 매우 번거로울 것입니다. 각각의 모든 경로에 대해 이와 같이 하십시오.

  get '/games/:id', to: 'games#show', constraints: { subdomain: 'app' }
  get '/games/list', to: 'games#list', constraints: { subdomain: 'app' }
  post '/games/start', to: 'games#start', constraints: { subdomain: 'app' }

constraints의 블록 형식을 사용할 수 있습니다. 단일 하위 도메인에 대한 다중 경로를 정의하는 도우미.

  constraints subdomain: 'app' do
    get '/games/:id', to: 'games#show'
    get '/games/list', to: 'games#list'
    post '/games/start', to: 'games#start'
  end

여러 하위 도메인에 대한 경로를 정의하려면 여러 constraints을 추가하기만 하면 됩니다. routes.rb의 블록 파일.

constraints subdomain: 'app' do
  ...
end
 
constraints subdomain: 'api' do
  ...
end
 
constraints subdomain: 'dev' do
  ...
end

언더 후드

Rails 라우팅은 요청 제약 조건과 세그먼트 제약 조건을 제공합니다. 세그먼트 제약 조건은 요청 경로에 규칙을 추가하는 반면 요청 제약 조건은 들어오는 요청에 조건을 추가합니다. 요청 제약 조건의 해시 키는 Request의 메서드여야 합니다. 문자열을 반환하는 개체이며 값은 예상 값이어야 합니다.

constraints subdomain: 'app' do
  ...
end

위의 경우 subdomain을 사용하고 있습니다. Request의 메소드 객체를 만들고 app와 같은 문자열과 일치시킵니다. , api 또는 dev .

자세한 내용은 Rails 라우팅 가이드를 참조하세요.

다단계 하위 도메인 처리

app.staging.funkygames.co를 사용한다고 가정해 보겠습니다. 우리의 스테이징 환경을 위해. 위의 설정이 있는 경우 app에 도달해야 하는 모든 요청이 하위 도메인은 404를 반환합니다. 더 디버그하면 하위 도메인에 대한 제약 조건이 실패하고 있음을 알 수 있습니다.

request.subdomain #=> app.staging

하위 도메인이 app을(를) 반환할 것으로 예상했습니다. 하지만 대신 app.staging을 반환합니다. . 물론, 우리는 환경별 코드를 추가하지 않고 이것을 해결하고 싶습니다! 요청 하위 도메인의 구문 분석은 config.action_dispatch.tld_length에 의해 관리됩니다. 옵션. 이 구성의 기본값은 기본적으로 한 수준의 하위 도메인을 지원하는 1입니다. 두 가지 수준의 하위 도메인이 있으므로 config.action_dispatch.tld_length 값을 설정해야 합니다. 2.

# config/application.rb
config.action_dispatch.tld_length = Integer(ENV['TLD_LENGTH'] || 1)

스테이징과 프로덕션 환경에서 동일한 코드를 사용할 수 있도록 환경 변수를 사용하여 설정할 수 있습니다. 이제 라우팅 설정이 app.staging.funkygames.co에서 작동합니다. 뿐만 아니라.

세션 관리

이제 여러 하위 도메인에서 오는 요청을 처리하도록 경로가 정의되었으므로 모든 하위 도메인에 대한 인증을 처리해야 합니다. 두 가지 방법으로 이를 수행할 수 있습니다. 동일한 사용자 세션이 모든 하위 도메인에서 사용되도록 허용하거나 별도의 하위 도메인에 대해 별도의 세션을 가질 수 있습니다.

간단한 인증

Rails는 기본적으로 쿠키를 사용하여 사용자 세션 키를 저장합니다. 사용자가 로그인하면 사용자의 세션 정보는 선택한 세션 저장소에 저장되고 세션 키는 브라우저에 쿠키로 저장됩니다. 따라서 사용자가 다음에 당사 웹사이트를 방문할 때 동일한 세션 쿠키가 브라우저에서 서버로 전송되고 서버는 들어오는 세션 쿠키에 대한 세션이 존재하는지 여부에 따라 사용자의 로그인 여부를 결정합니다.

세션의 기본 구성은 Rails 앱에서 다음과 같습니다.

Rails.application.config.session_store :cookie_store, key: "_funkygames_session"

_funkygames_session 세션 쿠키의 이름으로 사용되며 그 값은 세션 ID가 됩니다.

쿠키 입문서

기본적으로 쿠키는 요청 도메인의 브라우저에서 설정합니다. 따라서 app.funkygames.co에서 애플리케이션을 실행하는 경우 그러면 세션 쿠키가 app.funkygames.co에 대해 설정됩니다. . 각 하위 도메인은 자체 세션 쿠키를 설정하므로 기본적으로 사용자 세션은 하위 도메인 간에 공유되지 않습니다.

서로 다른 하위 도메인 간의 세션 공유

하위 도메인 간에 사용자 세션을 공유하려면 funkygames.co에서 세션 쿠키를 설정해야 합니다. 모든 하위 도메인이 액세스할 수 있도록 도메인 자체. 이것은 domain을 전달하여 달성할 수 있습니다. 세션 저장소 설정에 대한 옵션입니다.

Rails.application.config.session_store :cookie_store, key: "_funkygames_session", domain: :all

domain 전달 :all로 , 우리는 기본적으로 funkygames.co와 같은 애플리케이션의 최상위 도메인에 세션 쿠키를 설정하도록 Rails에 지시합니다. 개별 하위 도메인을 포함할 수 있는 요청 호스트 대신. 이렇게 하면 다른 하위 도메인 간에 세션을 공유할 수 있습니다.

<블록 인용>

domains에 도메인 목록을 전달할 수도 있습니다. 여러 도메인을 지원하는 배열 형식의 옵션.

모든 하위 도메인에 대한 쿠키를 올바르게 설정하려면 구성해야 하는 옵션이 하나 더 있습니다. tld_length입니다. 옵션. domain: :all 사용 시 , 이 옵션은 도메인의 TLD를 해석하기 위해 도메인을 구문 분석하는 방법을 지정할 수 있습니다. 우리의 경우 app.funkygames.co의 경우 , tld_length를 설정해야 합니다. Rails가 TLD를 funkygames.co로 해석하려면 2로 변경 쿠키를 설정할 때. 따라서 여러 하위 도메인에 대한 최종 세션 저장소 구성은 다음과 같습니다.

Rails.application.config.session_store :cookie_store,
                                       key: "_funkygames_session",
                                       domain: :all,
                                       tld_length: 2
<블록 인용>

tld_length 세션 저장소의 옵션이 config.action_dispatch.tld_length와 다릅니다. 앞서 논의했습니다.

여러 하위 도메인에 대한 테스트 작성

경로는 하위 도메인에 따라 다르므로 테스트 요청에 적절한 하위 도메인이 없으면 요청 사양 또는 통합 테스트에서 404 오류가 발생합니다. Rails 통합 테스트는 host!를 제공합니다. 테스트 파일 내에서 이루어진 모든 요청에 ​​대해 적절한 하위 도메인을 설정할 수 있는 도우미입니다.

# Configuring subdomain in Rails integration tests
setup do
  host! 'dev.example.com'
end
 
# # Configuring subdomain in RSpec request specs
before do
 host! 'dev.example.com'
end

그런 다음 routes.rb의 하위 도메인 라우팅에 따라 요청이 컨트롤러 작업으로 올바르게 라우팅됩니다. 파일.

여기서 도메인은 중요하지 않으며 테스트 중인 코드를 기반으로 하는 적절한 하위 도메인만 중요합니다.

개발을 위해 로컬로 여러 하위 도메인 설정

하위 도메인을 로컬로 설정하는 방법에는 여러 가지가 있습니다. 가장 간단한 것은 /etc/hosts를 편집하는 것입니다. 파일.

127.0.0.1 dev.funkygames.local
127.0.0.1 app.funkygames.local
127.0.0.1 api.funkygames.local

이렇게 하면 하위 도메인 설정이 로컬 환경에서 작동합니다. 로컬에서 하위 도메인을 관리하기 위해 pow와 같은 도구를 사용할 수도 있습니다.

제약 기반 하위 도메인 라우팅이 있는 문제

제약 조건 기반 하위 도메인 라우팅이 대부분의 경우 작동하지만 특정 상황에서는 문제가 될 수 있습니다.

외부 API 다루기

타사 API로 작업하고 통합을 구축할 때 .local과 같은 로컬 개발 TLD는 또는 .dev 허락되지 않는다. ngrok과 같은 도구를 사용해야 합니다. 이러한 경우 하위 도메인 기반 라우팅이 작동하지 않으며 ngrok을 통해서도 액세스할 수 있도록 특정 경로를 화이트리스트에 추가해야 합니다.

하위 도메인 제약 조건 외부의 경로

특정 경로는 하위 도메인 제약 조건 내에 배치할 수 없습니다. 일반적인 예는 healthcheck입니다. 또는 ping 끝점. Rails 앱 앞에서 로드 밸런서를 사용하는 경우 로드 밸런서는 앱이 실행 중인지 여부를 주기적으로 확인해야 합니다. healthcheck 로드 밸런서가 요청 호스트에 대해 알지 못할 가능성이 높기 때문에 이러한 경우에 사용되는 엔드포인트는 하위 도메인 제약 조건을 받을 수 없습니다.

루트 경로 부재

Rails에는 특별한 root가 있습니다. 기본적으로 애플리케이션의 기본 경로인 경로입니다. 요청과 일치하는 다른 경로가 없으면 root 경로가 사용됩니다. 하위 도메인 중 하나에 모든 경로가 있는 경우 root가 없는 상황이 있을 수 있습니다. 경로가 전혀 정의되지 않았습니다. 특정 gem은 root의 존재 여부에 따라 달라질 수 있습니다. 경로에 따라 견제와 균형을 추가해야 합니다.

결론

이 게시물에서는 몇 줄의 구성으로 여러 하위 도메인이 있는 Rails 앱을 설정했습니다. 또한 여러 하위 도메인에 대한 효과적인 테스트 작성에 대한 팁과 함께 다른 환경과 로컬로 하위 도메인을 설정하는 방법을 살펴보았습니다. Rails에서 제공하는 연결 기능을 사용하면 여러 하위 도메인이 있는 Rails 앱을 쉽게 설정하고 테스트할 수 있습니다.

추신 Ruby Magic 게시물이 언론에 공개되는 즉시 읽고 싶다면 Ruby Magic 뉴스레터를 구독하고 게시물을 놓치지 마세요!