---
title: "oauthに対応した"
slug: "oauth"
date: 2025-06-19
tags: ["atproto"]
draft: false
---

現在、[syu.is](https://syu.is)に[atproto](https://github.com/bluesky-social/atproto)をselfhostしています。

oauthを`bsky.social`, `syu.is`ともに動くようにしました。

![](/img/atproto_oauth_syuis.png)

ここでいうselfhostは、pds, plc, bsky, bgsなどを自前のserverで動かし、連携することをいいいます。

ちなみに、atprotoは[bluesky](https://bsky.app)のようなものです。

ただし、その内容は結構複雑で、`at://did`の仕組みで動くsnsです。

usernameは`handle`という`domain`の形を採用しています。

didの名前解決(dns)をしているのが`plc`です。`pds`はuserのdataを保存しています。timelineに配信したり表示しているのが`bsky(appview)`, 統合しているのが`bgs`です。

その他、`social-app`がclientで、`ozone`がmoderationです。

```sh
"6qyecktefllvenje24fcxnie" -> "ai.syu.is"
```

## oauthでハマったところ

現在、`bsky.team`のpds, plc, bskyには`did:plc:6qyecktefllvenje24fcxnie`が登録されています。これは`syu.is`の`@ai.syui.ai`のアカウントです。

```sh
$ did=did:plc:6qyecktefllvenje24fcxnie

$ curl -sL https://plc.syu.is/$did|jq .alsoKnownAs
[ "at://ai.syui.ai" ]

$ curl -sL https://plc.directory/$did|jq .alsoKnownAs
[ "at://ai.syu.is" ]
```

しかし、みて分かる通り、bskyではhandle-changeが反映されていますが、pds, plcは`@ai.syu.is`で登録されており、更新されていないようです。

```sh
$ handle=ai.syui.ai
$ curl -sL "https://syu.is/xrpc/com.atproto.identity.resolveHandle?handle=$handle" | jq -r .did
did:plc:6qyecktefllvenje24fcxnie

$ curl -sL "https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=$handle" | jq -r .did
null

$ curl -sL "https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=$handle" | jq -r .did
did:plc:6qyecktefllvenje24fcxnie
```

[msg type="warning" content="現在はbsky.teamのpdsにhandle-changeが反映されています。"]

oauthは、そのままではbsky.teamのpds, plcを使って名前解決を行います。この場合、まず、それらのserverにdidが登録されている必要があります。

次に、handleの更新が反映されている必要があります。もし反映されていない場合、handleとpasswordが一致しません。

localhostではhandleをdidにすることで突破できそうでしたが、本番環境では難しそうでした。

なお、[@atproto/oauth-provider](https://github.com/bluesky-social/atproto/tree/main/packages/oauth/oauth-provider)の本体を書き換えて、pdsで使うと回避は可能だと思います。

私の場合は、その方法は使わず、didの名前解決には自前のpds, plcを使用することにしました。

```js
this.oauthClient = await BrowserOAuthClient.load({
        clientId: this.getClientId(),
        handleResolver: pdsUrl,
        plcDirectoryUrl: pdsUrl === 'https://syu.is' ? 'https://plc.syu.is' : 'https://plc.directory',
});
```

