OpenId Connect 플러그인과 AWS Cognito를 사용한 자동 로그인

안녕하세요. Discourse를 처음 사용해 보는 사용자입니다. AWS에서 실행 중인 앱이 있고, 이 앱은 Cognito를 인증에 사용하고 있습니다. 이 앱을 새로 개설한 Discourse 호스팅 포럼과 연결하고 싶습니다. 좋은 시작을 했다고 생각하지만, 이 작업을 완료하기 위한 최종 단계에 대해 조언을 구합니다.

목표는 제 앱과 Discourse 포럼 간의 로그인 경험을 매끄럽게 만드는 것입니다. 즉:

  • 사용자가 제 앱에 로그인된 상태에서 Discourse 포럼에 접속하면, Discourse가 이를 인식하여 재로그인을 요구하지 않도록 합니다.

  • 마찬가지로, 사용자가 처음 Discourse 포럼에 접속하여 로그인되어 있지 않은 경우, Discourse가 사용자를 제 앱의 로그인 페이지(또는 필요시 호스팅된 로그인 UI)로 리디렉션합니다.

OpenId Connect Authentication Plugin이 이 용도에 잘 맞는 것 같습니다. 이 플러그인을 사용할 수 있도록 확실히 하기 위해 Discourse 비즈니스 플랜에 가입했습니다.

@david님이 제공한 설명서를 확인하고 Cognito 측에서 제가 생각하기에 설정이 완료되었다고 믿는 작업을 수행했습니다:

  1. Cognito에서 "openid connect discovery document"와 "openidconnect client id"를 가져왔습니다.

  2. 제 Discourse 설정에서 openId_Connect 섹션 아래에 이 값들을 입력하고 저장했습니다.

  3. "enable openID connect authentication"을 체크하고, openid connect authorize scope 아래에 "openid email"을 입력했습니다. 이 설정들을 저장했습니다.

플러그인 설명에 따르면, 이렇게 하면 준비가 완료된 것이 맞나요?

하지만 제 앱에 로그인한 후 포럼으로 이동하면 아무 일도 일어나지 않습니다. "가입"과 “로그인” 버튼이 있는 일반 홈 페이지만 표시됩니다. Cognito와 확인한 후 자동으로 로그인되기를 희망했는데, 그렇지 않습니다. 무엇을 더 해야 하나요?

또한, 사용자가 제 앱에 로그인한 적 없이 새로 포럼 사이트에 접속하는 경우, Discourse의 가입 및 로그인 버튼을 보여서는 안 됩니다. 대신, 클릭하면 제 앱의 로그인으로 리디렉션되는 버튼을 보여야 합니다. 이를 어떻게 추가하나요?

마지막으로, 사용자는 제 앱에 가입하고 프리미엄 기능을 사용하기 위해 비용을 지불합니다. 이 정보는 Cognito에서 사용자의 커스텀 속성으로 저장됩니다(구독 상태 여부를 나타내는 커스텀 속성이 있습니다). 구독한 사용자만 포럼에 게시할 수 있어야 합니다. 따라서 Discourse가 Cognito에서 사용자 정보를 가져올 때 사용자의 커스텀 속성을 확인하고, 사용자가 구독 상태일 경우에만 게시 권한을 부여해야 합니다. 이를 어떻게 구현하나요?

Discourse에 익숙하지 않아, 이 질문들에 대해 누군가가 가진 정보가 있다면 큰 도움이 될 것입니다. 감사합니다!

안녕하세요 @JQ331 :wave:

자동 로그인은 사이트가 비공개(즉, login_required 사이트 설정이 활성화되어 있는 경우)일 때만 지원됩니다.

이미 그렇게 작동해야 합니다. '로컬 로그인’을 포함한 모든 다른 로그인 방법을 비활성화했는지 확인해 주세요.

불행히도 OIDC 플러그인을 사용하여 이를 구현할 수는 없습니다.

@david 님, 답변해 주셔서 정말 감사합니다. 도움이 많이 됩니다.

이 “login_required” 사이트 설정은 어디에 있나요? "비공개"라고 하셨을 때, 사용자가 로그인해야만 사이트 콘텐츠를 볼 수 있다는 의미인가요? 당연히 제가 원하는 것은 그런 것이 아닙니다. 저는 사용자가 게시글을 작성하려면 로그인해야 하고, 로그인하는 유일한 방법이 제 별도 앱을 통해서만 가능하도록 설정하고 싶습니다.

설정 → 로그인 → 로컬 로그인 활성화(이 항목의 체크를 해제)를 말씀하시는 거죠? 그래서 로컬 로그인 관련 항목의 체크를 모두 해제했습니다. 그런데 여기서 무엇을 체크해야 하나요? 예를 들어, 로그인 연동을 위해 별도 앱을 사용하는 플러그인을 사용하는 경우, 그 별도 앱은 "sso"에 해당하나요, 아니면 "oauth2"에 해당하나요? (예를 들어 "sso overrides email"을 선택해야 하는지, 아니면 "oauth2 overrides email"을 선택해야 하는지 궁금합니다.)

유료 사용자만 게시글을 작성할 수 있도록 하는 것에 대해:

이것은 근본적인 요구 사항이므로, 아마도 창의적인 방법을 찾아야 할 것 같습니다. SSO 플러그인 외에 다른 옵션이 있나요? 만약 없다면, 다음 중 하나가 가능하면 이 기능이 작동할 수 있다고 봅니다:

  1. Discourse에는 다양한 수준의 사용자 권한이 있습니다. 따라서 사용자는 로그인되어 있지만, 실제로 게시글을 작성하거나 답글을 달 수 있는 권한은 없는 상태로 설정할 수 있는지요. 이 경우, Discourse가 Cognito에서 가져온 정보(구독 여부)에 따라 사용자의 권한 수준을 설정해야 합니다.

  2. 만약 이것이 불가능하다면, Discourse에 작동하는 Stripe 플러그인이 있는지요? 이 플러그인을 통해 사용자가 로그인되어 있으면서도, Stripe 시스템을 통해 결제가 완료된 경우에만 게시글을 작성할 수 있도록 할 수 있나요?

  3. 만약 이 두 가지 모두 불가능하다면(예를 들어, Discourse에 제가 설정할 수 있는 사용자 권한 수준을 구별하는 기능이 없는 경우)——그렇다면 사용자는 로그인되어 있거나 아니면 아예 없는 상태여야 하고, 로그인된 사용자만 게시글을 작성할 수 있어야 한다는 뜻인가요? 제 이해가 맞나요?

만약 그렇다면, 제 별도 앱 쪽에서 사용자가 내 앱에서 결제를 완료한 경우에만 Discourse에 로그인되도록 지시하는 방법을 알아내야 할 것입니다.

감사합니다.

그렇다면 현재 자동 로그인은 지원되지 않습니다. 사용자가 로그인 버튼을 클릭해야 합니다.

좋습니다. 이제 로그인 버튼이 직접 ID 제공업체로 연결되어야 합니다. 잘 작동하고 있나요?

네, 모든 카테고리를 “모두”가 읽을 수 있도록 설정할 수 있습니다. 하지만 특정 그룹에 속한 사용자만 토픽을 생성하거나 답글을 달 수 있습니다. 자동화하려면 API를 사용하여 그룹에 사람을 추가하거나 제거할 수 있습니다.

좋네요—거의 성공한 것 같습니다. 확인 차 여쭤볼게요:

저는 다음 조건을 원합니다:

  1. 모든 사용자(로그인 여부 불문)가 사이트 콘텐츠를 읽을 수 있습니다.
  2. 로그인한 사용자만 게시물을 작성할 수 있습니다.
  3. 제 앱에 로그인된 상태로 Discourse에 접속하면, Discourse가 Cognito와 통신하여 자동으로 로그인 처리되고, 게시물을 작성할 수 있게 됩니다.

(3)번이 불가능하다는 말씀이신가요? 즉, 사이트 콘텐츠가 대중에게 숨겨져 있을 때만 자동 로그인이 된다는 뜻인가요?


이것이 제가 원하는 방식인 것 같습니다. "API를 사용하라"고 하신 것으로 보아, 다음과 같은 절차를 말씀하시는 것 같습니다:

  1. 사용자가 제 포럼에 로그인하려고 합니다.
  2. 제 앱으로 로그인하도록 리디렉션됩니다.
  3. 제 앱에 로그인하면, 앱이 사용자가 요금을 지불했는지 확인합니다. 만약 지불된 상태라면, 제 앱은 Discourse API를 호출하여 해당 사용자를 게시 및 답글 작성 권한이 있는 "그룹"에 추가합니다.

제가 이해한 대로 맞나요? 맞다면, API를 통해 사용자를 그룹에 추가하는 방법에 대한 공식 문서가 따로 있을까요?

감사합니다. 정말 큰 도움이 됩니다.

아마 '자동 로그인’에 대한 정의가 다를 것 같습니다.

Discourse는 로그인에 OIDC 제공자를 연결할 수 있습니다. 이 과정은 사용자가 포럼의 ‘로그인’ 버튼을 클릭할 때 시작됩니다. 이는 설정과 관계없이 항상 작동합니다.

사이트가 로그인 필수 상태(즉, 로그인 필수 설정이 활성화됨)라면, 사용자가 버튼을 클릭할 필요 없이 바로 OIDC 로그인 화면으로 리디렉션됩니다.

네, 제가 생각했던 바로 그 내용입니다. 해당 API 엔드포인트에 대한 문서가 있습니다.

좋아요. 감사합니다! 해당 API 문서를 확인해 보겠습니다. 매우 유망해 보입니다.

“자동 로그인(auto-login)” 관련해서 — "자동 로그인 = 사용자를 자동으로 로그인 화면으로 이동시킨다"는 의미인 것 같습니다. 그렇다면 말씀하시는 내용은 사용자가 제 Discourse 포럼에 접속할 때 두 가지 옵션이 있다는 뜻이네요.
옵션 1. 사이트가 사용자를 별도의 앱 로그인 페이지로 “자동으로” 이동시킵니다. 이는 사용자가 이미 제 앱에 로그인되어 있든 아니든 상관없이 발생합니다. (이것이 바로 "자동 로그인"이라고 설명하신 부분이며, "login_required"를 설정하면 이런 일이 일어난다고 하셨습니다.)

옵션 2. 사이트가 자동 리다이렉션을 수행하지 않습니다. 대신 페이지에 기본 로그인 버튼이 있습니다. 사용자가 그 버튼을 클릭하거나 게시물을 작성하려고 하면, 포럼이 사용자를 제 앱의 로그인 페이지로 리다이렉트합니다.

저는 옵션 3을 원했습니다: 사용자가 제 앱에 로그인된 상태에서 제 Discourse 포럼에 접속하면, Discourse 포럼이 Cognito에 사용자의 로그인 여부를 확인합니다. Cognito에 로그인되어 있다면, 사용자가 별도로 다시 로그인하지 않아도 Discourse가 포럼에 사용자를 로그인 상태로 처리해 줍니다.

저는 OpenID 관련해서는 초보이지만, 이 기능이 가능하다고 확신했습니다. 사용자가 앱과 포럼 사이를 전환할 때마다 각각 별도로 로그인해야 한다면, 그것은 매끄러운 사용자 경험(seamless experience)이 아니기 때문입니다.

Discourse 포럼이 Cognito에 확인하여, 사용자가 별도의 로그인 과정을 거치지 않고도 로그인 상태를 조정할 수 있는 방법이 없나요?

참고로, Discourse를 제 앱에 직접 통합하는 것만으로는 도움이 되지 않을 것이라고 가정하고 있습니다. 가능하다면 그렇게 하고 싶지만, iframe을 통해서만 가능한 것 같고, 그것은 인증 문제를 해결하는 데 도움이 되지 않을 것입니다.

OIDC 사양상 기술적으로 가능하지만, 불행히도 Discourse는 현재 이를 지원하지 않습니다.

음. Discourse와 Cognito 같은 별도의 인증 제공자 간의 연결을 설정하는 데 두 가지 방법이 있다는 이야기를 들었습니다: OpenId 플러그인을 사용하는 방법, 또는 Discourse의 Single Sign On을 사용하는 방법입니다.

저는 Single Sign On 프로세스에 대해 전혀 익숙하지 않지만, 이것이 제가 원하는 것, 즉 사용자가 두 번 로그인하는 것을 피하는 방법일 수 있을까요?

아니면, 사용자가 제 앱에 로그인할 때 Discourse로 API 호출을 보내서 그 방식으로 로그인 처리하는 것이 더 나을 수도 있겠네요.

(제가 링크한 문서에는 그룹 멤버십을 지정하는 내용도 언급되어 있습니다. 이는 '유료 결제 사용자만 게시가 허용된 그룹에 속할 수 있다’는 제 요구사항을 충족시키는 데 도움이 될 것이라고 가정하고 있습니다.)