draft
optional
このNIPはクライアントが一時的なイベントに署名することでリレーに対して認証する方法を定義する。
リレーは、制限されたリソースにアクセスしようとするクライアントに認証を要求したくなる場合がある。例えば:
- リレーはクライアントからのイベントの送信に対して支払いまたはその他の形式のホワイトリスト登録を要求する可能性がある。 -- これは素朴には送信できるイベントをホワイトリストに登録された鍵で署名されたもののみに制限することで達成されるが、このNIPを使用すれば、認証されたユーザから送信されたイベントであればどのようなイベントでもリレーはそれを受け入れるかを選択できる。
- リレーは
kind: 4
DMへのアクセスをそれを交換している当事者のみに制限する可能性があり、そしてそのためにクラアントが同kindをクエリする前に認証を要求したいかもしれない。 - リレーはあらゆる種類の購読を課金ユーザまたは他の何らかの手段でホワイトリスト登録されたユーザのみに限定する可能性があり、そのために認証が必要かもしれない。
このNIPは新しいメッセージAUTH
を定義する。このメッセージを、リレーは認証をサポートするときクライアントに、クライアントは認証したいときリレーに送信してもよい (CAN)。リレーによって送信された場合、メッセージは以下の形式を取る:
["AUTH", <challenge-string>]
クライアントによって送信された場合は、以下の形式を取る:
["AUTH", <signed-event-json>]
クライアントによって送信されたAUTH
メッセージに対しては、EVENT
メッセージに対してそうするように、OK
メッセージで応答されなければならない (MUST)。
署名されたイベント (<signed-event-json>
) は送信またはクエリされることを意図していない一時的なイベントであり、kind: 22242
でなければならず、かつ少なくとも2つのタグ -- すなわちひとつにリレーのURLを、そしてもうひとつにリレーから受け取ったチャレンジ文字列 (<challenge-string>
) を持っているべきである。リレーはkind: 22242
イベントをクライアントへのブロードキャストから除かなければならない (MUST)。created_at
は現在時刻であるべきだ。イベントの例を次に示す:
{
"kind": 22242,
"tags": [
["relay", "wss://relay.example.com/"],
["challenge", "challengestringhere"]
],
// other fields...
}
このNIPは(クライアントによるイベント書き込みへの応答としての)OK
と(クライアントが要求したが拒否された購読への応答としての)CLOSED
の中で使用可能な2つの新しい接頭辞を定義する。
"auth-required: "
- リレーがクエリまたはイベントの書き込みを受理するため必要であるにも関わらず、クライアントがAUTH
を完了していない場合。"restricted: "
- クライアントはAUTH
を正常に完了したが、認証に使用された鍵がまだリレーに許可されていないか、その認可を超過している場合。
リレーはいつでもチャレンジ文字列を含むAUTH
メッセージをクライアントに送信してもよい。このチャレンジは接続期間中、または異なるチャレンジがリレーから送信されるまで有効である。クライアントはいかなる瞬間に対応するAUTH
イベントを送信することを決定してもよく(MAY)、認証されたセッションは接続を通して有効である。
特定の処理のみ、例えばREQ
への応答やEVENT
書き込みの受理のみにリレーはクライアントに認証を求める可能性が高いことを加味すれば、これらが期待される一般的な流れとなる:
relay: ["AUTH", "<challenge>"]
client: ["REQ", "sub_1", {"kinds": [4]}]
relay: ["CLOSED", "sub_1", "auth-required: we can't serve DMs to unauthenticated users"]
client: ["AUTH", {"id": "abcdef...", ...}]
relay: ["OK", "abcdef...", true, ""]
client: ["REQ", "sub_1", {"kinds": [4]}]
relay: ["EVENT", "sub_1", {...}]
relay: ["EVENT", "sub_1", {...}]
relay: ["EVENT", "sub_1", {...}]
relay: ["EVENT", "sub_1", {...}]
...
このケースにおいて、リレーからのAUTH
メッセージはクライアントが接続した直前に送信されてもよいし、CLOSED
が送信される直前に送信されてもよい。唯一の要件は、auth-required
なCLOSED
メッセージに反応してクライアントが適切に振る舞えるよう、リレーと関連づいたチャレンジを保存しておかなければならない ということである。
クライアントがEVENT
をリレーに書き込みたいときにも同じ流れが有効である。ただし、この場合リレーはCLOSED
メッセージの代わりにOK
メッセージで応答する。
relay: ["AUTH", "<challenge>"]
client: ["EVENT", {"id": "012345...", ...}]
relay: ["OK", "012345...", false, "auth-required: we only accept events from registered users"]
client: ["AUTH", {"id": "abcdef...", ...}]
relay: ["OK", "abcdef...", true, ""]
client: ["EVENT", {"id": "012345...", ...}]
relay: ["OK", "012345...", true, ""]
AUTH
メッセージを検証するため、リレーは以下を確認しなければならない:
- その
kind
が22242
である - そのイベントの
created_at
が現在時刻に近い (例: 10分以内) - その
"challenge"
タグの値が以前送ったチャレンジと合致する - その
"relay"
タグの値がリレーのURLと合致する- URL正規化技術が適用されている可能性がある。ほとんどの場合、ドメイン名が正しいかどうかを確認するだけで十分である。