honoを使ってBlueskyのサブドメイン ハンドル認証を実装しといた

自分のドメインはあるけど、Bluesky（bsky）で使いたいハンドルが異なる場合に使えるhonoサーバーを実装してみましたので、もし条件が合ったら使ってみてください。

要するに、私がサイト bar.tld を運営していることでそこそこ有名なfooというハンドルの人だとすると、このコードがお役に立つかもしれません。

- `@bar.tld` としてBlueskyを使いたいわけではない
- ハンドルは `foo` から始まってほしい
- ハンドルが `@foo.bar.tld` なら最高か
- foo.bar.tld というサブドメインは今まで使ったことがない

上記を満たしている場合は、ぜひ使ってみてください！ `@foo.bar.tld` というハンドルを `https://foo.bar.tld` で認証して、Bluesky で使えるようにしましょう。

## 使う技術を紹介

### Bluesky のハンドル認証

サブドメインを Bluesky ハンドルとして認証する際に特にわかりやすくて便利なのは、Bluesky に生成された文字列を該当サブドメインの `/.well-known/atproto-did` から返す方法です。

### hono

APIなどに人気のwebフレームワーク。

### Cloudflare Worker

Cloudflare社が提供しているサーバーレス関数のサービスです。honoで作ったシンプルなアプリならすごくデプロイしやすいと思います。

## 実装と使い方

honoで、二つのエンドポイントを持つアプリを実装します：

- `/.well-known/atproto-did`: 該当のBlueskyハンドルの認証に必要なDID文字列を返す
- `/`: 訪れたユーザーを任意のURLに転送する

コードは極めてシンプルです：

```ts
import { Hono } from "hono";
import { env } from "hono/adapter";

const app = new Hono();

app.get("/.well-known/atproto-did", (c) => {
  const { BSKY_DID } = env<{ BSKY_DID: string }>(c);
  return c.text(BSKY_DID);
});

app.get("/", (c) => {
  const { REDIRECT_URL } = env<{ REDIRECT_URL: string }>(c);
  return c.redirect(REDIRECT_URL);
});

export default app;
```

### 必要なもの

- [Cloudflare](https://www.cloudflare.com/)アカウント、もしくはアプリをデプロイできる別の方法
  - 該当ドメインのDNSをCloudflareで管理しているとなおやりやすい
- パッケージ管理には [pnpm](https://pnpm.io/installation) を使っている前提で書いています
- [プロジェクトのコード](https://github.com/alecrem/bluesky-verification-server)
  - GitHubアカウントが必ずしも必要ではない
    - Fork → `git clone` の流れの代わりにzipファイルをダウンロードして進めても良い
- Blueskyが期待する、該当のサブドメインをハンドルとして認証するためのDID文字列が必要
  1. Blueskyにログインして[アカウント設定](https://bsky.app/settings/account)を開く
  2. 「ハンドル」をクリックする
  3. 「自分のドメインを持っています」をクリックする
  4. 「使用するドメインを入力してください」を埋める
  5. 「DNSパネルがない場合」を選択する
  6. 「その内容は以下の通りです：」に出てくるDID文字列を控える (`did:plc:`から始まる)

### 自分のものにする

`wrangler.toml` に設定や環境変数を貼ります：

```toml
name = "karawapo-alecrem-com"
main = "src/index.ts"
compatibility_date = "2024-11-29"

routes = [
  { pattern = "karawapo.alecrem.com", custom_domain = true }
]

[vars]
BSKY_DID = "did:plc:h4rnbdanbl3u2czpvkbve2se"
REDIRECT_URL = "https://alecrem.com/"
```

下記の箇所を書き換える必要がある：

- Cloudflare Worker に任意の名前をつける: `name = "karawapo-alecrem-com"`
- 希望のBlueskyハンドルを貼る（`@` なし）: `pattern = "karawapo.alecrem.com"`
- `BSKY_DID`: Blueskyで取得したDID文字列を貼る
- `REDIRECT_URL`: `/` へのリクエストをどこに転送したいか

### 依存関係をインストールしてローカルサーバーを回す

```shell
pnpm install
pnpm run dev
```

- [http://localhost:8787](http://localhost:8787) へのHTTPS要求が指定した転送用URLに転送されることを確認する
- [http://localhost:8787/.well-known/atproto-did](http://localhost:8787/.well-known/atproto-did) へのHTTPS要求が希望のハンドルのDID文字列を返すことを確認する（私のDID文字列ではなくて）

### Cloudflare Workerとしてデプロイ

```shell
pnpm run deploy
```

- Cloudflareアカウントにログインする必要がある
- コードを変えるたびにデプロイし直すことができる

### Cloudflare Worker にカスタムドメインを設定する

1. Cloudflareアカウントにログインしたまま、左側にナビゲーションメニューから「Workers & Pages」を開く
1. 作ったWorkerを選択して開く
1. Workerの「設定」タブを開く
1. 「ドメインとルート」セクションにある「+ 追加」ボタンをクリックする
1. 開くペインで「カスタム ドメイン」を選択する
1. `wrangler.toml` に貼った通りのBlueskyハンドルを貼る
1. 「ドメインを追加」をクリックして、設定を完了させる
- `https://foo.bar.tld` へのHTTPS要求が指定した転送用URLに転送されることを確認する
- `https://foo.bar.tld/.well-known/atproto-did` へのHTTPS要求が希望のハンドルのDID文字列を返すことを確認する（私のDID文字列ではなくて）

### Bluesky上でハンドルを設定する

  1. Blueskyにログインして[アカウント設定](https://bsky.app/settings/account)を開く
  2. 「ハンドル」をクリックする
  3. 「自分のドメインを持っています」をクリックする
  4. 「使用するドメインを入力してください」を埋める
  5. 「DNSパネルがない場合」を選択する
  6. 「テキストファイルを確認」をクリックする

## おわりに

このちょっとしたプロジェクトのおかげで、honoとCloudflare Workersを初めて使うことになりました。もし触ったことがないようでしたら、使ってみるのがいかがでしょうか？