User API keys specification

여러 번 시행착오를 거친 끝에 결국 성공했습니다.

다음은 제가 따르는 기본적인 단계입니다. 제가 직접 코딩한 별도의 애플리케이션이 있고, 사용자가 해당 애플리케이션을 통해 Discourse 사이트로 API 호출을 하도록 하고자 할 때 적용하는 방법입니다.

이를 위해서는 각 사용자를 대신하여 호출을 수행하기 위해 사용자별 API 토큰을 생성해야 합니다(적어도 nodejs/javascript 환경에서는 그렇습니다).


참고로 javascript 쪽과 관련하여, @KengoTODA 님이 여기에서 제공한 코드가 매우 유용했습니다: discourse-api-key-generator/src/index.ts at main · KengoTODA/discourse-api-key-generator · GitHub


제가 따랐던 단계는 다음과 같습니다:

첫째: 공개 키와 비밀 키 쌍을 생성합니다.

이것은 애플리케이션이 생성해야 하는 사항으로, 공개 키와 비밀 키가 필요합니다. GitHub gist에 이를 수행하는 한 가지 방법이 나와 있습니다.

둘째: 리다이렉트 URL을 준비합니다.

이것은 Discourse가 최종 API 토큰을 페이로드에 담아 리다이렉트할 URL입니다. 데스크톱 애플리케이션(즉, 브라우저 URL이 없는 경우)을 사용하는 경우, 리다이렉트 URL은 브라우저에 입력하면 해당 애플리케이션을 여는 데 사용되는 사용자 정의 프로토콜 기반으로 설정됩니다.

참고로 리다이렉트 URL은 대상 Discourse 사이트의 사이트 설정에 화이트리스트로 등록되어야 합니다.

Discourse 사이트에는 또한 "사용자 API 키 허용"이라는 사이트 설정이 체크되어 있어야 할 가능성이 높습니다. 이 주제에 대한 원본 게시물의 “사이트 설정” 부분을 참고하세요.

셋째: Discourse 요청 URL로 API 요청을 보냅니다.

따라서 애플리케이션은 다음과 같은 형식의 URL로 호출을 보내야 합니다:

https://[대상 discourse 사이트 .com]/user-api-key-new"

그리고 다음 매개변수를 추가합니다:

  • 애플리케이션 이름
  • “client_id” (데스크톱 애플리케이션의 경우, 위에서 언급한 GitHub gist와 마찬가지로 const {hostname} = require('os')의 hostname()을 사용할 수 있었습니다)
  • 스코프 (API를 통해 사용자가 수행할 수 있도록 하려는 스코프로, “write”, “read” 등)
  • 공개 키 (위 1단계에서 생성한 것)
  • 리다이렉트 URL (위 2단계에서 설정한 것)
  • nonce (임의로 선택할 수 있는 값입니다 — '1’을 사용하는 것만으로도 작동하는 것으로 보입니다)

넷째: 사용자가 요청 URL에 의해 열린 Discourse 사이트 페이지에서 애플리케이션을 승인합니다

요청 URL을 성공적으로 보내면, Discourse 사이트에서 사용자에게 해당 애플리케이션이 사이트에 액세스하려고 한다는 내용을 알려주는 페이지가 열립니다.

해당 페이지에는 이를 허용하도록 하는 버튼이 있습니다. 사용자가 이 버튼을 클릭하면 Discourse 사이트가 제공한 리다이렉트 URL로 리다이렉트되고, ?payload=[API 키]를 매개변수로 첨부합니다. 여기서의 API 키는 애플리케이션에서 디코딩해야 할 키입니다.

다섯째: 애플리케이션이 리다이렉트 URL 값(페이로드 값 포함)을 수신하고 API 키를 디코딩합니다

거의 다 왔습니다. 애플리케이션은 Discourse가 이동한 리다이렉트 URL을 파싱하여 페이로드에 포함된 API 키를 가져와야 합니다.

해당 API 키를 얻으면 두 가지 작업을 수행해야 합니다:

  1. 실제 키를 가져옵니다. URL 인코딩된 버전이 아닙니다: URL에서 매개변수를 가져오는 경우, 보통 URL 인코딩되어 있습니다(여기저기에 %가 추가되는 등). 이를 정리해야 합니다. javascript의 경우 decodeURIComponent가 이 용도로 작동하는 것으로 확인되었습니다.
  2. Discourse에서 반환된 정리된 API 키를 얻으면, 이를 디코딩해야 합니다. 이를 위해 javascript의 비밀 키 디코딩을 사용할 수 있습니다. 기본적으로 1단계에서 생성한 비밀 키를 사용하여 정리된 API 키를 디코딩합니다. 위에서 언급한 GitHub gist에 해당 예제 javascript가 있습니다: discourse-api-key-generator/src/index.ts at main · KengoTODA/discourse-api-key-generator · GitHub

디코딩 코드를 실행하면 토큰 자체를 얻게 되며, 이제 이를 사용하여 사용자를 대신하여 인증된 API 호출을 수행할 수 있습니다.

여섯째: 토큰(즉, 최종적으로 정리되고 디코딩된 API 키)을 사용하여 사용자를 대신하여 API 호출을 수행합니다

해당 토큰을 사용하면 API 호출 시 사용자 이름을 입력할 필요가 없는 것으로 보입니다. GET, POST, PUT 등의 호출에 다음 헤더를 포함하는 것으로 충분하다고 생각합니다:

headers: {
"User-Api-Key": [토큰]
}

이로써 hopefully Discourse와 상호작용하기 위한 작동하는 사용자별 인증 방법을 갖추게 됩니다.

7개의 좋아요