> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/reference/ja/ren-zheng/authentication/sign-in-with-roboflow-developer-reference.md).

# Roboflow でサインイン（開発者リファレンス）

Sign in with Roboflow の統合者向けリファレンス。アプリの登録、PKCE、認可フローについては、 [Roboflow でサインイン（はじめに）](/reference/ja/ren-zheng/authentication/sign-in-with-roboflow-getting-started.md).

## サンプルアプリ

[roboflow/siwr\_example\_app](https://github.com/roboflow/siwr_example_app) は、に対する本番用 OAuth を実装した最小限の Node.js アプリです `app.roboflow.com` と `api.roboflow.com`。トークンは Express セッション内に保持され、ブラウザにクライアントシークレットが見えることはありません。

```bash
git clone https://github.com/roboflow/siwr_example_app.git
cd siwr_example_app
cp .env.example .env
# RF_CLIENT_ID、RF_CLIENT_SECRET、SESSION_SECRET を設定
npm install && npm run dev
```

リダイレクト URI を指定して OAuth アプリを登録する `http://localhost:3001/oauth/callback` およびアプリに一致する許可スコープ（`openid`, `profile`, `email`, `workspace:read`, `project:read`, `model:infer`).

| ルート                   | 目的                      |
| --------------------- | ----------------------- |
| `GET /`               | ランディングまたはサインイン済みダッシュボード |
| `GET /oauth/start`    | OAuth を開始（PKCE リダイレクト）  |
| `GET /oauth/callback` | コードを交換し、ダッシュボードを表示      |
| `POST /logout`        | トークンを取り消してセッションをクリア     |

### PKCE と認可 URL

元 [`src/oauth.ts`](https://github.com/roboflow/siwr_example_app/blob/main/src/oauth.ts):

```typescript
export function pkcePair(): { verifier: string; challenge: string } {
    const verifier = crypto.randomBytes(48).toString("base64url");
    const challenge = crypto.createHash("sha256").update(verifier).digest("base64url");
    return { verifier, challenge };
}

export function buildAuthorizeUrl(state: string, codeChallenge: string): string {
    const url = new URL(`${config.appHost}/oauth/authorize`);
    url.searchParams.set("response_type", "code");
    url.searchParams.set("client_id", config.clientId);
    url.searchParams.set("redirect_uri", config.redirectUri);
    url.searchParams.set("scope", REQUESTED_SCOPE_STRING);
    url.searchParams.set("state", state);
    url.searchParams.set("code_challenge", codeChallenge);
    url.searchParams.set("code_challenge_method", "S256");
    return url.toString();
}
```

`GET /oauth/start` を保存します `verifier` と `state` をセッションに保存し、その後この URL にリダイレクトします。

### トークン交換（サーバー側）

```typescript
const body = new URLSearchParams({
    grant_type: "authorization_code",
    code,
    redirect_uri: config.redirectUri,
    client_id: config.clientId,
    client_secret: config.clientSecret,
    code_verifier: codeVerifier
});

const response = await fetch(`${config.appHost}/oauth/token`, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body
});
```

### コールバック: 検証 `state`

元 [`src/server.ts`](https://github.com/roboflow/siwr_example_app/blob/main/src/server.ts):

```typescript
const pending = req.session.oauth;
req.session.oauth = undefined;

if (!pending || !code || state !== pending.state) {
    // reject: state が無効、または code がありません
    return;
}

const data = await exchangeCodeForTokens(code, pending.verifier);
req.session.tokens = tokensFromTokenResponse(data);
```

コードを交換する前に、1回限りの OAuth セッションデータは必ず消去してください。

## トークンエンドポイント認証

トークンエンドポイントは、機密クライアント向けに 2 つの方法をサポートします（公開クライアントはシークレットを省略し、PKCE に依存します）：

| 方法                    | 仕組み                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------- |
| `client_secret_post`  | 送信 `client_secret` をリクエスト本文のフォームパラメータとして送信する（既定）                                      |
| `client_secret_basic` | HTTP の `Authorization: Basic` ヘッダーに資格情報を送信（base64 エンコードされた `client_id:client_secret`) |

クライアントまたはゲートウェイに合う方法を選択してください。OAuth アプリの作成または編集時に設定します **ワークスペース設定 > 開発者**.

を使ったトークン交換の例 `client_secret_basic`:

```bash
curl -X POST https://app.roboflow.com/oauth/token \\
  -u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \\
  -d "grant_type=authorization_code" \\
  -d "code=AUTHORIZATION_CODE" \\
  -d "redirect_uri=https://yourapp.com/callback" \\
  -d "code_verifier=YOUR_CODE_VERIFIER"
```

## ホスト

| サービス            | ベース URL                    |
| --------------- | -------------------------- |
| サインイン、トークン、OIDC | `https://app.roboflow.com` |
| REST API        | `https://api.roboflow.com` |

## 公開範囲

どのワークスペースが OAuth アプリでサインインできるかを制御します。

| ダッシュボードのオプション | サインインできる人                                            |
| ------------- | ---------------------------------------------------- |
| **社内向け**      | アプリを作成したワークスペースのメンバーのみ                               |
| **非公開**       | クライアント ID を持っていればどのワークスペースでも可                        |
| **公開**        | 未掲載で、さらに有効化されている場合は Sign in with Roboflow ディレクトリにも掲載 |

独立した「External」可視性タイプはありません。ワークスペースをまたぐ統合では **非公開**.

各顧客ワークスペースは、 **External OAuth apps policy** （すべて許可、クライアント ID の許可リスト、またはすべてブロック）。ワークスペース外でサインインに失敗する場合は、顧客にワークスペース設定であなたのクライアント ID を許可してもらってください。

## サインインとトークン（app.roboflow\.com）

| 目的            | 方法   | URL                                                         | 注記                                   |
| ------------- | ---- | ----------------------------------------------------------- | ------------------------------------ |
| 認可            | GET  | `https://app.roboflow.com/oauth/authorize`                  | PKCE + `state` 必須                    |
| トークン / リフレッシュ | POST | `https://app.roboflow.com/oauth/token`                      | `application/x-www-form-urlencoded`  |
| 取り消し          | POST | `https://app.roboflow.com/oauth/revoke`                     | 本文: `token=...`                      |
| Userinfo      | GET  | `https://app.roboflow.com/oauth/userinfo`                   | Bearer; が必要 `openid`                 |
| Introspect    | POST | `https://app.roboflow.com/oauth/introspect`                 | フォーム `token=...`; client id + secret |
| 検証            | GET  | `https://app.roboflow.com/oauth/validate`                   | Bearer トークン; クライアント認証情報は不要           |
| OIDC ディスカバリー  | GET  | `https://app.roboflow.com/.well-known/openid-configuration` |                                      |
| JWKS          | GET  | `https://app.roboflow.com/.well-known/jwks.json`            | 検証 `id_token` JWT                    |

## REST API でのトークンの使用

送信 `Authorization: Bearer {access_token}` での `api.roboflow.com`。参照 [REST API で認証する](/reference/ja/purattofmu/rest-api/authenticate-with-the-rest-api.md).

## よくあるエラー

| HTTP                 | 意味                         | 対処方法                                    |
| -------------------- | -------------------------- | --------------------------------------- |
| 400 `invalid_scope`  | スコープがアプリの許可リストにありません       | ダッシュボードでスコープを追加するか、リクエストから削除してください      |
| 401 `OAuthException` | トークンの期限切れまたは取り消し済み         | 1 回リフレッシュしてから、サインインを再度求めてください           |
| 403（scope）           | トークンにスコープがありません            | より広いスコープで再同意してください                      |
| 403（その他）             | ユーザーロールに権限がありません           | ワークスペース管理者がロールを調整します                    |
| リダイレクトの不一致           | `redirect_uri` 登録内容と一致しません | ダッシュボードのエントリまたは authorize URL を修正してください |

## セキュリティ

* すべての認可リクエストで PKCE を使用してください。
* 検証 `state` すべてのコールバックで。
* 公開しないでください `client_secret` またはリフレッシュトークンをブラウザに。
* サインアウト時にトークンを取り消してください。
* 最小限のスコープだけを要求してください。完全な一覧は [Getting Started](/reference/ja/ren-zheng/authentication/sign-in-with-roboflow-getting-started.md#available-scopes).
