「애플리케이션 액세스 승인」 건너뛰기

저희는 Discourse를 협업 도구로 사용하며, 문서를 검색하기 위해 다른 앱을 함께 활용하고 있습니다. 문서에 대한 댓글을 Discourse에 통합하고자 합니다. 두 앱 모두 저희 인프라 내에서 외부 SSO/Oauth 제공자를 사용하고 있습니다.

두 앱이 통신할 수 있도록 User API Key를 사용하여 연결하고 있습니다. 현재는 정상적으로 작동하지만, OAuth 기반의 신뢰할 수 있는 환경임에도 불구하고 “Authorize application access” 양식을 클릭해야 하는 번거로움을 피하고 싶습니다.

이 “인가” 접근 단계를 생략하거나 우회하여 User API Key 생성으로 바로 이동할 수 있는 방법이 있을까요? 이 페이지가 표시되지 않고 사용자가 이 추가 단계를 수행하지 않도록 요청 시 특정 매개변수를 제공할 수 있는 방법이 있을까요?

먼저 UserApiKeysController.create를 호출해 보았지만(대신 UserApiKeysController.new를 호출하는 대신) CSRF 오류가 발생했습니다. 그래서 토큰 검증을 건너뛰기 위해 다음과 같이 시도해 보았습니다:

class UserApiKeysController < ApplicationController
  skip_before_action :verify_authenticity_token

하지만 이것도 작동하지 않았습니다.

다른 해결 방법이 있을까요?

미리 감사드립니다

브루노, 여기 오신 것을 환영합니다! 함께하게 되어 반갑습니다 :slight_smile: @david나 @blake가 이 문제에 대해 몇 가지 아이디어를 가지고 있을지도 모릅니다.

확실히 말씀드리자면, 이것은 올바른 방법이 아닙니다. 현재 플러그인을 사용하고 계신가요, 아니면 HTTP를 통해만 상호작용하고 계신가요?

플러그인을 사용하고 계신다면, 대부분의 경우 app/controllers/ 인스턴스와 직접 상호작용해서는 안 됩니다.

HTTP를 통해 상호작용하고 그리고 서버 간 통신을 사용하고 있다면, Admin이 생성한 API 키를 사용하는 것이 더 나은 선택입니다.

User API는 클라이언트에서 코드 무결성을 보장할 수 없는 클라이언트-서버 간 통신을 위해 설계되었습니다.

네, 우리는 디스코urs 플러그인을 개발할 계획이며, 우리의 JS 앱은 HTTP 요청으로만 상호작용할 것입니다.
우리는 구성 요소 간의 결합을 최소화하기 위해 서버 간 통신(예: 관리자 API 키 사용)을 개발해야 하는 상황을 피하고 싶습니다.

이상적으로는 디스코urs 컨트롤러를 건드리지 않아야 한다는 것을 이해하지만, 동시에 템플릿 메서드 패턴 및 기타 확장 지점처럼 오버라이드되도록 설계된 많은 메서드들이 있습니다. 그리고 지금까지 본 바로 많은 플러그인들이 그렇게 하고 있습니다.

그렇다면 올바른 방법은 무엇일까요?

플러그인을 개발하고 있다면, 필요한 작업을 직접 수행하는 플러그인 마운트 컨트롤러에서 새로운 라우트를 개발해야 합니다. 이러한 라우트는 모두 Access-Control-Allow-{Origin, Headers, Credentials} 응답 헤더를 설정하는 before_action을 공유할 수 있습니다(앱이 실행되어야 할 도메인 목록에 포함된 경우 Origin 요청 헤더를 그대로 반환합니다).

이렇게 하면 JS 코드에서 API 키 없이 단순히 fetch(..., { credentials: "include", ...})를 호출할 수 있습니다.

리플을 남겨주신 @riking 님, 감사합니다. 브라우저에 discourse 세션이 열려 있으면 이 방법은 잘 작동합니다.

우리는 SiteSetting.enable_local_logins = false이고 oauth를 통한 인증 메커니즘이 하나만 있으므로, http://discourse_site/login을 직접 호출하여 수동으로 새 세션을 시작할 수 있습니다. 브라우저는 우리의 oauth 제공자로 리다이렉트를 따르며, 이후 discourse로 리다이렉트됩니다. 이는 /user-api-key/new를 호출할 때 내부적으로 일어나던 것과 동일한 동작입니다.

현재 세션이 없는 상태에서 앱에서 discourse 세션을 프로그래매틱으로 시작하는 방법은 무엇일까요?