Discourse 멤버가 로그아웃됩니다 – 어떻게 해결할 수 있나요?

안녕하세요, 포럼 회원 중 일부가 20~30분 후에 자동으로 로그아웃되는 문제를 겪고 있다는 보고를 받았습니다.

저는 SSO를 사용 중이므로, 문제가 메인 사이트로 로그인한 후 Discourse로 이동(이때 새 세션이 시작되는 것일까요?), 다시 메인 사이트로 돌아오는 과정(Discourse가 유휴 상태가 되는 것)에서 발생하고, 다시 Discourse로 돌아왔을 때 어떤 방식으로든 로그아웃되는 것일 수 있다고 의심하고 있습니다.

(다만, 회원이 Discourse에 들어올 때마다 "유휴 타임아웃"이 다시 0으로 설정되어야 하므로, 이 설명은 완전히 말이 되지 않는 것 같습니다.)

메타 포럼에서 타임아웃 등에 관한 몇 가지 스레드를 찾았지만, 명확한 답변이 있는 것 같지는 않았습니다.

질문: 회원이 X시간 동안 유휴 상태가 될 때까지 로그아웃되지 않도록 하는 설정이 있나요? 아무리 찾아도 찾지 못하겠습니다.

Discourse 설정에서 "최대 세션 수명"이 1시간으로 설정되어 있는 것을 볼 수 있지만, SSO 구현 환경에서는 이것이 실제로 큰 차이가 없는 것 같습니다. (참고로 회원이 메인 사이트에서 로그아웃하면 모든 것을 깔끔하게 정리하기 위해 Discourse에 /logout 메시지를 보내고 있습니다. 또한 회원이 Discourse에서 어떤 활동을 하든 메인 사이트의 마지막 활동 시간을 업데이트하므로, 메인 사이트의 타임아웃 때문이 아닙니다. 이것이 모두 정상적으로 작동하는지 확인하기 위해 추가적인 디버깅 코드를 작성하고 있습니다.)

감사합니다.
E

SSO에도 적용되므로, 이것이 문제의 원인이 될 가능성이 높습니다. 1시간 동안 비활성 상태가 되면 Discourse 세션이 종료되고, 사용자는 SSO로 다시 인증해야 합니다.

그건 괜찮고, 전혀 문제없습니다… 1시간 동안 아무 활동이 없으면 로그아웃되어야 하니까요.

문제는 20~30분 만에 로그아웃되었다는 보고를 받고 있다는 겁니다.

그 1시간 대기 시간 제한에 대한 설정이 있나요? 처음 올린 글에서 언급했듯이, 그 설정을 찾을 수가 없거든요… 그리고 그게 가장 먼저 확인해야 할 곳이 아닌가요?

가장 명백한 원인을 먼저 배제해 보자면… 사람들이 정확한 시각에 대해 오해하고 있는 것은 아닌지 생각해 볼 필요가 있습니다. 30분과 1시간은 그렇게 큰 차이가 아니니까요 :wink:

이 문제를 디버깅하기 위해 다음 단계로 user_auth_tokens 테이블과 user_auth_token_logs 테이블에 사용 가능한 데이터를 살펴보는 것을 제안합니다. 이 테이블들은 세션 토큰과 만료에 관한 모든 정보를 포함하고 있습니다.

네, OP에서 언급하신 그 설정입니다.

동의합니다 :wink: 지금 바로 테스트하고 있어요 - 제 사이트에 로그인해서 포럼으로 이동한 뒤, 브라우저는 그대로 두는 거죠!

DB 테이블에 대한 팁 감사합니다. 더 자세히 알아볼게요.

음. 사람들이 포럼을 사용하고 주제를 읽는 등, 어떤 액션(예: create_post, create_topic, edit_post 등)을 생성하면 웹훅을 통해 메시지를 받게 됩니다. 이는 메인 사이트가 사용자가 여전히 활동 중임을 알 수 있게 해주어 세션의 ‘마지막 클릭’ 값을 업데이트하고 로그아웃을 방지할 수 있게 합니다. 당연히 그래야 하는 것이죠. 모두 잘 작동합니다.

하지만, 만약 멤버가 그저 메시지를 읽기만 하는 동안이라면… 그들이 무언가를 할 때마다 Discourse의 유휴 시간이 재설정됩니다(이것은 좋은 점이지만), 제 메인 사이트는 사용자가 활동 중임을 나타내는 웹훅 메시지를 전혀 받지 못합니다. 따라서 1시간 동안 아무 활동도 없으면(포럼에 갔다가 컴퓨터를 떠나온 것처럼 보임) 메인 사이트는 세션이 만료된 것으로 간주하고 로그아웃을 시킵니다.

여기 논리에 구멍이 있는 것 같습니다. 올바른 SSO 구현을 위해서는, 사용자가 활동 중인지(단순히 읽기만 하더라도) Discourse가 알려주는 방법이 있어야 하지 않나요? 어쩌면 멤버가 활동 중이지만 다른 웹훅 메시지를 생성하지 않은 경우, Discourse가 5분마다 핑(ping)을 보내야 할지도 모릅니다.

아니면, 제 사이트가 사용자가 시간 초과된 것으로 판단할 때 Discourse를 호출하여 해당 사용자가 거기에 있는지 물어보는 것이 좋을까요? 그렇게 할 수 있는 방법이 있을까요? (Is there an endpoint to check if a user is logged in - #3 by pfaffman 를 보았지만, 이것이 제가 원하는 것인지 확신이 서지 않으며, /session/current.json은 API 문서에 나와 있지 않습니다.) 하지만 그러면 API 호출량이 엄청나게 늘어날 텐데요-- 제 사이트에서는 비활성으로 인해 매 분당 약 15~20명의 사용자를 로그아웃시키므로, 각 사용자를 위해 호출해야 합니다(그리고 로컬에 Discourse ID 캐시가 없다면 호출이 여러 번 발생할 수도 있습니다).

여러분, 어떻게 생각하시나요? 조언을 부탁드립니다.

모든 프로필 엔드포인트에는 last_seen 값이 포함되어 있어 이를 활용할 수 있습니다.

SSO 프로토콜에서 이러한 유형의 설정을 본 적이 없고, 이와 관련된 요청도 받은 적이 없습니다. 일반적으로 두 시스템을 독립적으로 유지하는 경우가 더 흔합니다.

만약 '사용자 확인’에 대한 웹훅을 꼭 만들고 싶다면, 커스텀 플러그인을 사용하여 구현할 수 있을 것입니다.

두 시스템을 독립적으로 유지한다는 게 무슨 의미인지 정확히 이해가 안 됩니다. 제가 제시한 문제를 해결하는 명백한 방법이 있다면 알려주세요!

그렇지 않다면, 제 선택지는 다음과 같습니다:

  1. 사용자가 메인 사이트에서 타임아웃될 때, 로그아웃하기 전에 Discourse를 호출하여 last_seen 값을 확인하고, 멤버가 실제로 포럼에서 활동 중이었는지(웹훅 호출을 생성하지 않는 활동만 한 경우) 확인합니다. 장점: 구현이 쉽습니다. 단점: API 호출이 많이 발생하는데, 이는 이미 레이트 리밋을 우회하는 문제로 고생하고 있는 부분입니다.

  2. 메인 사이트를 주기적으로 핑(Ping)하도록 자체 플러그인을 만들어, 메인 사이트에서 사용자의 마지막 활동 시간을 업데이트합니다. 장점: “올바른” 해결책(푸시 메시지로 활동을 표시)처럼 느껴지고, 다소 우아합니다. 단점: 구현이 쉽지 않습니다.

  3. 메인 사이트의 로그아웃 시간을 2시간으로 변경합니다. 장점: 구현이 쉽습니다. 단점: 단점이 있을까요?

  4. 신경 쓰지 않습니다. 사용자가 Discourse 세션 중간에 로그아웃되고 거세게 불평합니다. 이것이 현재 제 상황입니다. :wink: 장점: 구현이 쉽습니다, 하하. 단점: 사용자 경험(UX)이 매우 나쁩니다.

무엇을 놓쳤을까요?

#3이 좋은 답변인 것 같지만, 메인 사이트에서 로그아웃 시간을 더 길게 가질 때의 파급 효과를 생각해봐야 합니다.

여전히 #1이 최선의 선택이라고 생각하지만, 그렇다면 수많은 레이트 리밋 문제를 어떻게 방지할지 해결해야 합니다. Discourse(그리고 nginx, 저는 Discourse Docker 설치를 사용 중입니다)에서 모든 레이트 리밋을 전역적으로 끄는 방법이 있으면 좋겠습니다. 완전히 끄고 싶습니다. 저는 그 어떤 것도 필요하지 않습니다. 제 메인 사이트만 제 Discourse 인스턴스와 통신할 뿐입니다. 사용자 API 키를 허용하지 않으며, 시스템 API 키를 가진 사람은 저 혼자입니다. 완전히 폐쇄된 시스템이고, 레이트 리밋은 제 발목을 잡는 것 외에는 아무 역할도 하지 않습니다. 아마도 이것은 다른 주제일 것입니다.

앞서 설명하신 동작을 유지해야 한다면, 네, 그 4가지가 옵션이라고 생각합니다. 하지만 동작 방식을 조금만 변경하면 현재 사용 가능한 도구들과 더 잘 호환될 것입니다.

설정에서 특이한 부분은 다음과 같습니다:

메인 사이트에서 세션이 만료될 때마다 Discourse 세션을 종료하고 있습니다. 이 부분을 제거하면 설정이 일반적인 구성과 일치할 것이라고 생각합니다.

사용자가 메인 사이트에서 의도적으로 로그아웃할 때만 /logout을 호출할 수 있습니다. 세션이 자연스럽게 만료될 때는 호출하지 마세요.

OP(질문자)의 상황을 정확히 알 수는 없지만, 매우 민감한 정보를 공유하는 초특화 사이트이거나, 대부분의 사용자가 공유되는 공용 컴퓨터에서 로그인하는 경우인가요?

여기서 가장 간단한 해결책은 사용자 세션 만료와 강제 로그아웃을 지나치게 공격적으로 설정하지 않는 것 같습니다. 사용자로서 제 선호도는 항상 "절대 로그아웃하지 마세요. 제가 직접 로그아웃 버튼을 클릭할 때만 로그아웃되게 해주세요"입니다. 그것이 불가능하다면, 최소한 1일이나 1주일 정도로 설정해 주실 수 있을까요?

아, 그렇군요. 좋은 해결책이네요. 로그인 페이지의 “로그인 상태 유지” 체크박스를 사용하는 회원이 꽤 많을 것 같아서, 주요 사이트로 다시 연결하는 과정이 매끄럽게 이루어질 것 같습니다. 만약 주요 사이트에서 세션이 만료된 상태라면, 그 시점에 (사용자가 인지하지 못하게) 자동으로 다시 로그인 처리가 될 것입니다. 음.

프라이버시에 매우 민감한 특정 인구 집단을 위한 사이트입니다. 하지만 말씀하신 내용을 이해했고, 당신(그리고 David)의 조언대로 진행해도 될 것 같습니다.

두 분 모두 정말 감사합니다. 여기의 "큰 그림"이나 다른 사이트들이 이런 상황을 어떻게 처리하는지에 대해 명확한 개념이 없었는데, 이제 알 것 같습니다 :slight_smile: 그리고 제 상황에 맞는 몇 가지 가능한 해결책도 보게 되었습니다. 정말 감사드립니다!