いくつかの試行錯誤の末、これを動作させることができました。
私が従っている基本的な手順を以下に示します。私が独自にコーディングした別のアプリがあり、そのアプリを使ってユーザーが Discourse サイトに対して API 呼び出しを行えるようにしたい場合の手順です。
そのためには、Node.js/JavaScript 環境では、少なくとも各特定のユーザーに代わって呼び出しを行うための、ユーザーごとの API トークンを生成する必要があります。
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 キーを取得したら、以下の 2 つのことを行う必要があります。
- URL エンコードされたバージョンではなく、実際のキーを取得する:URL からパラメータを取得する場合、それはよく URL エンコードされていることがあります(% が所々に追加されるなど)。これを整理する必要があります。JavaScript では、
decodeURIComponentがこれに有効であることがわかりました。 - 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": [トークン]
}
これで、Discourse と対話するための、ユーザーごとの認証方法が動作するはずです。