{
  "ogp": {
    "url": "https://whtwnd.com/api/cache?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreichz6p2q6nfime7zeqcw7rkotov7nwdxtil4yj64ymvwv6pcu7r4m",
    "width": null,
    "height": null
  },
  "$type": "com.whtwnd.blog.entry",
  "blobs": [
    {
      "name": "header.png",
      "blobref": {
        "$type": "blob",
        "ref": {
          "$link": "bafkreichz6p2q6nfime7zeqcw7rkotov7nwdxtil4yj64ymvwv6pcu7r4m"
        },
        "mimeType": "image/png",
        "size": 159551
      },
      "encoding": "image/png"
    },
    {
      "name": "ScreenShot 2026-03-26 21.21.21.png",
      "blobref": {
        "$type": "blob",
        "ref": {
          "$link": "bafkreid4ecb62rvb6jgj6gmbnyo6gfar7xx7y6rvbb7y7nxeprcurg67ru"
        },
        "mimeType": "image/png",
        "size": 151067
      },
      "encoding": "image/png"
    },
    {
      "name": "ScreenShot 2026-03-26 22.04.48.png",
      "blobref": {
        "$type": "blob",
        "ref": {
          "$link": "bafkreid2nqgpc5v75vb2idtjkwj3hevy425ihuv7cmjhgqxxu4ucrm35rq"
        },
        "mimeType": "image/png",
        "size": 143934
      },
      "encoding": "image/png"
    },
    {
      "name": "ScreenShot 2026-03-26 21.46.42.png",
      "blobref": {
        "$type": "blob",
        "ref": {
          "$link": "bafkreig3wklqrbdwdtsqfmec4qabzcuyrj5yydd773z5r3purbarrspcqa"
        },
        "mimeType": "image/png",
        "size": 203573
      },
      "encoding": "image/png"
    },
    {
      "name": "ScreenShot 2026-03-26 22.11.26.png",
      "blobref": {
        "$type": "blob",
        "ref": {
          "$link": "bafkreih2xvshoukaxlhjkiikeesfjrhdprn76yn4xvyeuwxzqmpez6y57a"
        },
        "mimeType": "image/png",
        "size": 91808
      },
      "encoding": "image/png"
    },
    {
      "name": "ScreenShot 2026-03-26 21.25.25.png",
      "blobref": {
        "$type": "blob",
        "ref": {
          "$link": "bafkreiesartzwuxllfymk3stkeb6fyp2janjcpsnhoilzu7re7yuodlezi"
        },
        "mimeType": "image/png",
        "size": 143419
      },
      "encoding": "image/png"
    }
  ],
  "theme": "github-light",
  "title": "BlueskyアプリのOAuth認証画面でアプリ名をドメインにしたい",
  "content": "![](https://oyster.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreichz6p2q6nfime7zeqcw7rkotov7nwdxtil4yj64ymvwv6pcu7r4m)\n\n## 前書き\n\nBlueskyアプリを開発しているときに、OAuthを利用することも一般的になりつつあります。\n\n開発者はOAuth画面で表示されるのは、メタデータで自分が定義したアプリ名ではなく、OAuthクライアントのメタデータがおかれたURLのフルパスが表示されるシーンに遭遇することになると思います。\n\n\nOAuth認証画面(Concent)でアカウントに求める権限確認画面の表示にも使用されるメタデータですが、JSONフォーマットで書かれたものがオンラインで参照可能であれば基本的にどこに置いてあっても良い事になっており、パスの指定もファイル名の指定も特段ありません。\n\nが、そうするとアプリ名の部分にはこのメタデータのURLフルパスが表示されます。これ自体は特段問題ないですが、せっかくなので自分のアプリ名、せめてドメインで表示されて欲しいものです。\n\n実際に一部アプリを見ていると、フルパスで表示されているアプリと、ドメインだけの表示になっているアプリがあります。\n\n\nこの違いは何か。この問題を調べるべく、我々はGitHubリポジトリのジャングルに旅立った────。\n\n\n\n## TL;DR\n\nOAuthクライアントメタデータのURLを `https://{your-app.example.com}/oauth-client-metadata.json` として公開し、指定すればアプリ名はドメイン名となる。\n\n\n\n## packages/oauth/oauth-provider-ui\n\nOAuth関連のUI実装があるのはこの辺りになります。\n\n![OAuth Concent画面の例](https://oyster.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreid4ecb62rvb6jgj6gmbnyo6gfar7xx7y6rvbb7y7nxeprcurg67ru)\n\nこの中で上記のコンセント画面を出しているのは `packages/oauth/oauth-provider-ui/src/views/authorize/consent/consent-view.tsx`\n\nhttps://github.com/bluesky-social/atproto/blob/main/packages/oauth/oauth-provider-ui/src/views/authorize/consent/consent-view.tsx\n\nここから辿ると `<ConcentForm />`が表示箇所の様子。\n\nさらに `concent-form.tsx` を辿るとどうやら `<ClientName />` がクライアント名を表示していそう。\n\n![packages/oauth/oauth-provider-ui/src/views/authorize/consent/consent-form.tsx](https://oyster.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreig3wklqrbdwdtsqfmec4qabzcuyrj5yydd773z5r3purbarrspcqa)\n\n`packages/oauth/oauth-provider-ui/src/components/utils/client-name.tsx` を見ると\n\n![packages/oauth/oauth-provider-ui/src/components/utils/client-name.tsx](https://oyster.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreid2nqgpc5v75vb2idtjkwj3hevy425ihuv7cmjhgqxxu4ucrm35rq)\nhttps://github.com/bluesky-social/atproto/blob/2203d825e8a4db41858de74b5413e7efbe80c3d2/packages/oauth/oauth-provider-ui/src/components/utils/client-name.tsx#L54-L65\n\n\n`<UrlViewer />`でクライアント名としてURLの表示の制御していそう。\n少し前の実装を見ると `isConventionOAuthClientId()`が鍵になっていそう。\n\n`packages/oauth/oauth-provider-ui/src/lib/oauth-client.ts` を見ると答えがありました。\n\n![packages/oauth/oauth-provider-ui/src/lib/oauth-client.ts](https://oyster.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreih2xvshoukaxlhjkiikeesfjrhdprn76yn4xvyeuwxzqmpez6y57a)\nhttps://github.com/bluesky-social/atproto/blob/2203d825e8a4db41858de74b5413e7efbe80c3d2/packages/oauth/oauth-provider-ui/src/lib/oauth-client.ts#L12-L13\n\n## 答え\n\nメタデータのURLが特定のパスに配置されていることで表示が変わるようです。\n\n\n## 条件\n\n\n- メタデータのURIプロトコルが `https:` である。\n- メタデータのパスが `/oauth-client-metadata.json` である\n![](https://oyster.us-east.host.bsky.network/xrpc/com.atproto.sync.getBlob?did=did%3Aplc%3Ac22jdrqhoajyj5ca7e56a3ke&cid=bafkreiesartzwuxllfymk3stkeb6fyp2janjcpsnhoilzu7re7yuodlezi)\n\n## 追記\n\nhttps://bsky.app/profile/yamarten.bsky.social/post/3mhxrd7s5h26n\n\nご指摘いただいた通りドキュメントにも記載がありました。\nhttps://atproto.com/ja/guides/scopes#clients\n\nただ、ドキュメント内では\n> もし `oauth-client-metadata.json` の代わりに `client-metadata.json` を使用している場合、この変更により認可フローのページでURL文字列ではなくドメインを表示させることができます。\n\nと記載があるのですが、この記述は実装側と異なっており `/oauth-client-metadata.json` のパスにしておく必要があります。",
  "createdAt": "2026-03-26T15:08:59.429Z",
  "visibility": "public"
}