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

Rails 세션 작동 방식

Rails 앱이 누가 방문했는지 알 수 없다면 어떻게 될까요? 같은 사람이 두 개의 다른 페이지를 요청했다는 사실을 몰랐다면? 응답을 반환하자마자 저장한 모든 데이터가 사라진다면?

대부분 정적 사이트에 적합할 수 있습니다. 그러나 대부분의 앱은 일부를 저장할 수 있어야 합니다. 사용자에 대한 데이터입니다. 사용자 ID, 선호하는 언어 또는 항상 iPad에서 데스크톱 버전의 사이트를 보고 싶어하는지 여부가 문제일 수 있습니다.

session 는 이러한 종류의 데이터를 저장하기에 완벽한 장소입니다. 둘 이상의 요청에 대해 보관하려는 작은 데이터.

사용하기 쉬운 세션:

session[:current_user_id] = @user.id

그러나 그들은 약간 마술적 일 수 있습니다. 세션이란 무엇입니까? Rails는 올바른 사람에게 올바른 데이터를 표시하는 방법을 알고 있습니까? 세션 데이터를 보관할 위치를 어떻게 결정합니까?

세션이란 무엇입니까?

세션은 한 번의 요청 중에 나중에 요청할 때 읽을 수 있는 데이터를 저장하는 장소일 뿐입니다.

컨트롤러 작업에서 일부 데이터를 설정할 수 있습니다.

앱/컨트롤러/세션_컨트롤러.rb
def create
  # ...
  session[:current_user_id] = @user.id
  # ...
end

그리고 다른 글에서 읽어보세요:

앱/컨트롤러/사용자_컨트롤러.rb
def index
  current_user = User.find_by_id(session[:current_user_id])
  # ...
end

보이지 않을 수도 있습니다. 그 흥미로운. 그러나 모든 것이 연결되도록 하려면 사용자의 브라우저와 Rails 앱 간의 조정이 필요합니다. 그리고 모든 것은 쿠키로 시작됩니다.

웹페이지를 요청하면 서버가 응답할 때 쿠키를 설정할 수 있습니다.

~ jweiss$ curl -I https://www.google.com | grep Set-Cookie

Set-Cookie: NID=67=J2xeyegolV0SSneukSOANOCoeuDQs7G1FDAK2j-nVyaoejz-4K6aouUQtyp5B_rK3Z7G-EwTIzDm7XQ3_ZUVNnFmlGfIHMAnZQNd4kM89VLzCsM0fZnr_N8-idASAfBEdS; expires=Wed, 16-Sep-2015 05:44:42 GMT; path=/; domain=.google.com; HttpOnly

귀하의 브라우저는 해당 쿠키를 저장합니다. 쿠키가 만료될 때까지 요청할 때마다 브라우저에서 쿠키를 서버로 다시 보냅니다.

...
> GET / HTTP/1.1
> User-Agent: curl/7.37.1
> Host: www.google.com
> Accept: */*
> Cookie: NID=67=J2xeyegolV0SSneukSOANOCoeuDQs7G1FDAK2j-nVyaoejz-4K6aouUQtyp5B_rK3Z7G-EwTIzDm7XQ3_ZUVNnFmlGfIHMAnZQNd4kM89VLzCsM0fZnr_N8-idASAfBEdS; expires=Wed, 16-Sep-2015 05:44:42 GMT; path=/; domain=.google.com; HttpOnly
...

많은 쿠키는 그냥 횡설수설처럼 보입니다. 그리고 그들은해야합니다. 쿠키 안의 정보는 사용자를 위한 것이 아니기 때문입니다. Rails 앱은 쿠키의 의미를 파악하는 역할을 합니다. 앱에서 설정할 수 있으므로 앱에서 읽을 수 있습니다.

이것이 세션과 어떤 관련이 있습니까?

그래서 쿠키가 있습니다. 한 요청 중에 데이터를 입력하고 다음 요청에서 동일한 데이터를 얻습니다. 세션과 세션의 차이점은 무엇인가요?

기본적으로 Rails에서는 큰 차이가 없습니다. Rails는 쿠키를 더 안전하게 만들기 위해 일부 작업을 수행합니다. 그러나 그 외에도 예상대로 작동합니다. Rails 앱은 일부 데이터를 쿠키에 넣고 동일한 데이터가 쿠키에서 나옵니다. 이것이 전부였다면 쿠키와 세션을 구분할 이유가 없었을 것입니다.

그러나 쿠키가 항상 세션 데이터에 대한 정답은 아닙니다.

  • 쿠키에는 약 4kb의 데이터만 저장할 수 있습니다.

    이것은 보통입니다. 충분하지만 때로는 그렇지 않습니다.

  • 쿠키는 귀하가 요청할 때마다 전송됩니다.

    큰 쿠키는 더 큰 요청과 응답을 의미하므로 웹사이트 속도가 느려집니다.

  • 실수로 secret_key_base를 노출한 경우 , 사용자는 쿠키에 넣은 데이터를 변경할 수 있습니다.

    여기에 current_user_id와 같은 항목이 포함된 경우 , 누구나 원하는 사용자가 될 수 있습니다!

  • 쿠키 내부에 잘못된 종류의 데이터를 저장하는 것은 안전하지 않을 수 있습니다.

조심하면 큰 문제가 되지 않습니다.

그러나 다음과 같은 이유로 쿠키에 세션 데이터를 저장할 수 없는 경우 Rails에는 세션을 보관할 수 있는 몇 가지 다른 위치가 있습니다.

대체 세션 저장소

다음이 아닌 모든 세션 저장소 쿠키 세션 저장소는 거의 같은 방식으로 작동합니다. 그러나 실제 예를 사용하는 것을 생각하는 것이 가장 쉽습니다.

ActiveRecord로 세션을 추적하고 있었다면:

  1. session[:current_user_id] = 1을 호출할 때 앱에 세션이 이미 존재하지 않는 경우:

  2. Rails는 session에 새 레코드를 생성합니다. 임의의 세션 ID가 있는 테이블(예:09497d46978bf6f32265fefb5cc52264 ).

  3. {current_user_id: 1}를 저장합니다. (Base64 인코딩) data 해당 레코드의 속성입니다.

  4. 생성된 세션 ID 09497d46978bf6f32265fefb5cc52264를 반환합니다. , Set-Cookie를 사용하여 브라우저에 .

다음에 페이지를 요청할 때

  1. 브라우저는 Cookie:를 사용하여 동일한 쿠키를 앱에 보냅니다. 헤더.

    (예:Cookie: _my_app_session=09497d46978bf6f32265fefb5cc52264;
    path=/; HttpOnly )

  2. session[:current_user_id]을 호출할 때 :

  3. 앱은 쿠키에서 세션 ID를 가져오고 session에서 해당 레코드를 찾습니다. 표.

  4. 그런 다음 current_user_id를 반환합니다. data에서 해당 레코드의 속성입니다.

세션을 데이터베이스에 저장하든 Memcached에 저장하든 Redis에 저장하든 대부분 동일한 프로세스를 따릅니다. 귀하의 쿠키 세션 ID가 포함되어 있고 Rails 앱이 해당 ID를 사용하여 세션 저장소의 데이터를 조회합니다.

작동하면 세션을 쿠키에 저장하는 것이 가장 쉬운 방법입니다. 추가 인프라나 설정이 필요하지 않습니다.

그러나 쿠키 세션 저장소 이상으로 이동해야 하는 경우 두 가지 옵션이 있습니다.

세션을 데이터베이스에 저장하거나 캐시에 저장합니다.

캐시에 세션 저장

부분 또는 데이터를 캐시하기 위해 이미 Memcache와 같은 것을 사용하고 있을 수 있습니다. 그렇다면 캐시 저장소는 이미 설정되어 있으므로 세션 데이터를 저장하는 두 번째로 쉬운 장소입니다.

이전 세션이 너무 커지면 캐시에서 자동으로 쫓겨나기 때문에 세션 저장소가 제어할 수 없게 증가하는 것에 대해 걱정할 필요가 없습니다. 캐시가 메모리에 보관될 가능성이 높기 때문에 속도도 빠릅니다.

하지만 완벽하지는 않습니다.

  • 실제로 오래된 세션을 유지하는 데 관심이 있다면 아마 원하지 않을 것입니다. 캐시에서 쫓겨나게 합니다.

  • 세션과 캐시된 데이터는 공간을 놓고 다투게 됩니다. 메모리가 충분하지 않으면 캐시 누락이 많이 발생하고 세션이 조기에 만료될 수 있습니다.

  • 캐시를 재설정해야 하는 경우(예:Rails를 업그레이드했는데 이전에 캐시된 데이터가 더 이상 정확하지 않음) 모든 사용자의 만료 없이 재설정할 수 있는 방법은 없습니다. 세션.

그래도 이것이 우리가 Avvo에서 세션 데이터를 저장하는 방법이며 지금까지 잘 작동했습니다.

데이터베이스에 세션 저장

세션 데이터가 합법적으로 만료될 때까지 유지하려면 일종의 데이터베이스에 보관하는 것이 좋습니다. 그것이 Redis, ActiveRecord 또는 다른 무엇이든.

그러나 데이터베이스 세션 저장소에도 단점이 있습니다.

  • 일부 데이터베이스 저장소의 경우 세션이 자동으로 정리되지 않습니다.

    따라서 만료된 세션을 직접 살펴보고 정리해야 합니다.

  • 데이터베이스가 세션 데이터로 가득 차 있을 때 데이터베이스가 어떻게 작동하는지 알아야 합니다.

    Redis를 세션 저장소로 사용하고 있습니까? 모든 세션 데이터를 메모리에 유지하려고 합니까? 서버에 충분한 메모리가 있습니까? 아니면 너무 심하게 스와핑을 시작하여 ssh를 할 수 없게 될까요? 수정하시겠습니까?

  • 세션 데이터를 생성할 때 더 주의해야 합니다. 그렇지 않으면 데이터베이스가 쓸모없는 세션으로 채워집니다.

    예를 들어, 모든 요청에서 실수로 세션을 터치하면 googlebot이 수십만 개의 쓸모없는 세션을 생성할 수 있습니다. 그리고 그것은 나쁜 시간이 될 것입니다.

이러한 문제의 대부분은 매우 드뭅니다. 하지만 여전히 알고 있어야 합니다.

그러면 세션을 어떻게 저장해야 하나요?

쿠키 저장소의 제한 사항에 부딪히지 않을 것이라고 확신하는 경우 사용하십시오. 많은 설정이 필요하지 않으며 유지 관리가 어렵지도 않습니다.

세션을 캐시에 저장하는 것과 데이터베이스에 저장하는 것은 세션을 일찍 만료시키는 것이 얼마나 나쁜지에 대한 판단입니다. 세션 데이터를 임시로 취급하므로 캐시 저장소가 잘 작동합니다. 그래서 일반적으로 쿠키를 먼저 시도한 다음 캐시를 시도한 다음 데이터베이스를 시도합니다.

하지만 당신은 어떻습니까? 귀하의를 어떻게 보관합니까? 세션? 댓글로 알려주세요!

Ruby와 Rails 내부가 어떻게 작동하는지 자세히 알고 싶다면 다음 기사를 살펴보세요. 보석은 어떻게 작동합니까? 또는 웹이 작동하는 방식에 더 관심이 있다면 웹 서버와 앱 서버를 확인하세요.