> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# アイデンティティ検証

> サーバーで生成されたJWTを使用して外部ユーザーID、メール、SMSサブスクリプションを検証することで、ユーザーのなりすましを防止します。

## 概要

OneSignalは、ユーザーのなりすましを防ぐのに役立つアイデンティティ検証という拡張セキュリティ機能を提供しています。この機能は、サーバー上で安全に生成されたJSON Web Token（[JWT](https://jwt.io/introduction)）を利用します。サブスクリプション情報を検証するために、これらのトークンがアプリとOneSignalのAPIに渡されます。

アイデンティティ検証を有効にして保護する：

* ユーザーのログイン
* メールサブスクリプションの追加
* SMSサブスクリプションの追加
* ユーザーアイデンティティの変更

<Warning>
  アイデンティティ検証は現在ベータ版です。アカウントで有効にするには `support@onesignal.com` までお問い合わせください。サポートが有効にしたら、ダッシュボードで有効化します（[ステップ 5](#enable-token-identity-verification-in-the-dashboard) を参照）。
</Warning>

## 前提条件

* プッシュプラットフォームが構成された既存のOneSignalアプリ。

* サポートされているSDKの1つと統合されたモバイルアプリ：

  * [OneSignal Android SDK 5.2.0+](https://github.com/OneSignal/OneSignal-Android-SDK/releases)
  * [OneSignal iOS SDK 5.3.0+](https://github.com/OneSignal/OneSignal-iOS-SDK/releases)

<Note>
  ラッパーSDKサポート（Flutter、React Native、Unityなど）は近日公開予定です。
</Note>

## セットアップ

<Steps>
  <Step title="新しいキーを生成する">
    OneSignalアカウントにログインし、**設定 > キーとID > アイデンティティ検証**に移動します。

    <Frame caption="アイデンティティ検証の構成">
      <img src="https://mintcdn.com/onesignal/Z6xkXGfmy814If53/images/docs/d6f1009-keys_and_ids.png?fit=max&auto=format&n=Z6xkXGfmy814If53&q=85&s=ffc30e4a1f08dcbe4e6a2e4935a7f5de" alt="Settings page showing Keys and IDs with Identity Verification section" width="2420" height="1614" data-path="images/docs/d6f1009-keys_and_ids.png" />
    </Frame>

    **新しいキーを生成**をクリックして、新しいキーペアを作成します。

    <Frame caption="新しいキーペアの作成">
      <img src="https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?fit=max&auto=format&n=56ctKxZSV4m5VEkn&q=85&s=73e56aa60fdef2dc8152bf929ebc1d52" alt="Generate New Keys button in the Identity Verification section" width="2350" height="686" data-path="images/docs/b24c1fd-Identity_Verification.png" />
    </Frame>

    PEMファイルをダウンロードするか、秘密鍵をコピーし、秘密鍵を安全に保管してください。

    <Frame caption="アイデンティティ検証のキーペア">
      <img src="https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?fit=max&auto=format&n=56ctKxZSV4m5VEkn&q=85&s=b8e99ccdb2f4aafd453063540148ca2e" alt="Identity Verification key pair with private key and PEM download" width="1128" height="966" data-path="images/docs/bc217af-id_keys.png" />
    </Frame>

    <Warning>
      秘密鍵は常にキー管理システムなどの安全な環境に保管してください。クライアントサイドコード、公開リポジトリ、またはログに秘密鍵を決して公開しないでください。
    </Warning>
  </Step>

  <Step title="バックエンドで検証JWTを生成する">
    アイデンティティ検証では、OneSignalにログインする**前に**、認証サーバーでエンドユーザーを認証する必要があります。エンドユーザーがバックエンドで認証するときに、トークンを生成し、デバイスへの認証レスポンスに含めます。アプリがバックエンドサーバーを実行していない場合は、ユーザーを検証してこれらのトークンを生成するための軽量サーバーのセットアップを検討してください。

    #### JWTペイロード

    JWTには次のプロパティを含めることができます：

    <ParamField path="iss" required="true">
      OneSignalアプリID
    </ParamField>

    <ParamField path="exp" required="true">
      トークンの有効期限。
    </ParamField>

    <ParamField path="identity" required="true">
      ユーザーのエイリアス。
    </ParamField>

    <ParamField path="subscriptions">
      ユーザーにメールおよびSMSサブスクリプションを追加する場合にのみ必要です。
    </ParamField>

    #### JWTへの署名

    ES256アルゴリズムを使用してJWTに署名します。JWTをOneSignalに送信するときに検証の問題を回避するために、バックエンドがこの署名方法を使用するように構成されていることを確認してください。これには[JWTライブラリ](https://jwt.io/libraries)を使用することをお勧めします。

    [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken)を使用した例：

    <CodeGroup>
      ```typescript Node.js theme={null}
      import jwt from 'jsonwebtoken';

      const APP_ID = process.env['ONESIGNAL_APP_ID']
      const IDENTITY_VERIFICATION_SECRET = process.env['ONESIGNAL_IDENTITY_VERIFICATION_SECRET_KEY']

      // Generates JWT, potentially with subscription claims, for the user identified by the External ID
      function signOneSignalJWT(externalId, subscriptions) {
      return jwt.sign({
      iss: APP_ID,
      exp: Math.floor(Date.now() / 1000) + 3600, // 1-hour expiration
      identity: {
      'external_id': externalId,
      },
      subscriptions
      },
      IDENTITY_VERIFICATION_SECRET,
      { algorithm: 'ES256' });
      }

      // Pass this token to your mobile app to use with the `login` SDK method
      const onesignalJWT = signOneSignalJWT('EXTERNAL_ID');

      ```
    </CodeGroup>

    秘密鍵は、ダッシュボードからダウンロードした前のステップのファイルにあります。

    #### JWT を確認する

    SDKと統合する前に、サーバーを起動してエンドポイントを呼び出すことで、JWTが正しく生成されていることを確認します：

    <CodeGroup>
      ```typescript Node.js theme={null}
        node server.js
      ```
    </CodeGroup>

    <CodeGroup>
      ```bash cURL theme={null}
        curl http://localhost:3000/generate-jwt/your-external-id
      ```
    </CodeGroup>

    次のようなレスポンスを受け取るはずです：

    ```json theme={null}
    {
      "jwt": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    }
    ```

    JWT値を[jwt.io](https://jwt.io)に貼り付け、デコードされたペイロードに次のパラメーターが含まれていることを確認します：

    ```json theme={null}
    {
      "iss": "your-onesignal-app-id",
      "exp": 1234567890,
      "identity": {
        "external_id": "your-external-id"
      }
    }
    ```

    次のステップに進む前に、以下を確認してください：

    * `iss` が **設定 > キーとID** の OneSignal アプリIDと一致している
    * `identity.external_id` が存在し、`OneSignal.login()` に渡す値と一致している
    * `exp` が将来のタイムスタンプである — 期限切れのトークンはOneSignalに拒否されます

    #### サブスクリプションを含める

    理想的には、ユーザーのログイン時に、メールアドレスや電話番号などのサブスクリプションの詳細をJWTペイロードに含めます。これらの詳細が事前に利用できない場合、検証サーバーは、サブスクリプション情報が利用可能になったときに動的にトークンを生成するエンドポイントを提供する必要があります。

    例：サブスクリプションを追加するためのJWTの生成

    <CodeGroup>
      ```typescript Node.js theme={null}
      const subscriptions = [
        {
            "type": "Email",
            "token": "[email protected]"
        },
        {
            "type": "SMS",
            "token": "+12345678"
        }
      ]
      const onesignalJWT = signOneSignalJWT('EXTERNAL_ID', subscriptions)
      ```
    </CodeGroup>
  </Step>

  <Step title="`login`メソッドにJWTを渡す">
    バックエンドがJWTを生成したら、それを使用して`login`メソッドを呼び出します。このトークンは、メールやSMSサブスクリプションの追加などの変更を行う前に、ユーザーのアイデンティティが検証されることを保証します。

    ログインの例：

    <CodeGroup>
      ```java java theme={null}
      String externalId = "YOUR_EXTERNAL_ID";
      String onesignalJWT = "YOUR_JWT_TOKEN";

      OneSignal.login(externalId, onesignalJWT);
      ```

      ```kotlin kotlin theme={null}
      val externalId = "YOUR_EXTERNAL_ID"
      val onesignalJWT = "YOUR_JWT_TOKEN"

      OneSignal.login(externalId, onesignalJWT)
      ```

      ```swift Swift theme={null}
      let externalId = "YOUR_EXTERNAL_ID"
      let onesignalJWT = "YOUR_JWT_TOKEN"

      OneSignal.login(externalId: externalId, token: onesignalJWT)
      ```

      ```c objective-c theme={null}
      NSString* externalId = @"YOUR_EXTERNAL_ID";
      NSString* onesignalJWT = @"YOUR_JWT_TOKEN";

      [OneSignal login:externalId withToken:onesignalJWT];
      ```
    </CodeGroup>
  </Step>

  <Step title="JWTライフサイクルイベントを処理する">
    トークンの無効化などのシナリオを処理するために、バックエンドに専用のエンドポイントを実装する必要があります。このエンドポイントは、OneSignalが更新を要求したときに更新されたJWTを提供する必要があります。

    トークンの無効化とJWTの更新を処理する例：

    <CodeGroup>
      ```java java theme={null}
      OneSignal.addUserJwtInvalidatedListener(event -> {
        // Get the expired user's External ID
        String externalId = event.getExternalId();

        // Fetch a new JWT from your backend for the user
        String onesignalJWT = "yourUpdatedToken";

        // Provide the new JWT to the SDK
        OneSignal.updateUserJwt(externalId, onesignalJWT);
      });
      ```

      ```kotlin kotlin theme={null}
      OneSignal.addUserJwtInvalidatedListener(
         object : IUserJwtInvalidatedListener {
             override fun onUserJwtInvalidated(event: UserJwtInvalidatedEvent) {
               val externalId = event.externalId
               val onesignalJWT = ""
               updateUserJwt(externalId, onesignalJWT)
             }
         },
      )
      ```

      ```swift Swift theme={null}
      class AppDelegate: UIResponder, UIApplicationDelegate, OSUserJwtInvalidatedListener {
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
          // Set self to listen for JWT invalidated events
          OneSignal.addUserJwtInvalidatedListener(self)

          // Remove the JWT listener as needed by calling:
          // `OneSignal.removeUserJwtInvalidatedListener(self)`
        }

        // Required to conform to `OSUserJwtInvalidatedListener` protocol
        func onUserJwtInvalidated(event: OneSignalUser.OSUserJwtInvalidatedEvent) {
          // Get the expired user's External ID
          let externalId = event.externalId

          // Fetch a new JWT from your backend for the user
          let onesignalJWT = "yourUpdatedToken"

          // Provide the new JWT to the SDK
          OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)
        }
      }
      ```

      ```c objective-c theme={null}
      @interface MyListener: NSObject<OSUserJwtInvalidatedListener>
      @end

      @implementation MyListener
      - (void)onUserJwtInvalidatedWithEvent:(OSUserJwtInvalidatedEvent * _Nonnull)event {
        // Get the expired user's External ID
        NSString *externalId = event.externalId;

        // Fetch a new JWT from your backend for the user
        NSString *onesignalJWT = @"yourUpdatedToken";

        // Provide the new JWT to the SDK
      	[OneSignal updateUserJwt:externalId withToken:onesignalJWT];
      }

      // Add or remove your User Jwt Invalidated Listener
      [OneSignal addUserJwtInvalidatedListener:myListener];
      [OneSignal removeUserJwtInvalidatedListener:myListener];
      ```
    </CodeGroup>

    これにより、ユーザーのJWTが無効化されたときに、バックエンドから新しいJWTをフェッチしてOneSignalに渡すことができます。また、この関数を使用して、メールアドレスと電話番号を含むトークンを生成し、認証中に作成されたトークンにそれらが含まれていない場合にメールとSMSサブスクリプションを管理できます。
  </Step>

  <Step title="ダッシュボードでトークンアイデンティティ検証を有効にする">
    **設定 > キーとID**から、**トークンアイデンティティ検証**をトグルして有効にします。

    <Frame caption="トークンアイデンティティ検証の有効化">
      <img src="https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?fit=max&auto=format&n=YOTSrtBSoqdrJ37A&q=85&s=26d06ca0a008e841d5206093bfbf2a8c" alt="Token Identity Verification toggle enabled in dashboard settings" width="2350" height="686" data-path="images/docs/4887367-identity_verification_enabled.png" />
    </Frame>

    有効にすると、アプリはサブスクリプションの真正性を検証するためにOneSignal JWTを送信する必要があります。さらに、アプリはアイデンティティ検証トークンサーバーによって生成されたJWTを使用して`login`メソッドを呼び出す必要があります。
  </Step>
</Steps>

## サブスクリプションを追加する

モバイルアプリからサブスクリプションを追加するために追加の手順を実行する必要はありません。loginメソッドを呼び出すと、自動的に処理されます。

<Tabs>
  <Tab title="メールを追加する">
    <CodeGroup>
      ```java java theme={null}
      OneSignal.getUser().addEmail(emailAddress);
      ```

      ```kotlin kotlin theme={null}
      OneSignal.getUser().addEmail(emailAddress)
      ```

      ```swift Swift theme={null}
      // If you have not already included it in your JWT token, update the JWT with the email
      let onesignalJWT = "newTokenThatContainsTheEmailToAdd"
      OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)

      // Add the email
      OneSignal.User.addEmail(emailAddress)
      ```

      ```c objective-c theme={null}
      // If you have not already included it in your JWT token, update the JWT with the email
      NSString *onesignalJWT = @"newTokenThatContainsTheEmailToAdd";
      [OneSignal updateUserJwt:externalId withToken:onesignalJWT];

      // Add the email
      [OneSignal.User addEmail:emailAddress];
      ```
    </CodeGroup>
  </Tab>

  <Tab title="電話番号を追加する">
    <CodeGroup>
      ```java java theme={null}
      OneSignal.getUser().addSms(smsNumber);
      ```

      ```kotlin kotlin theme={null}
      OneSignal.getUser().addSms(smsNumber)
      ```

      ```swift Swift theme={null}
      // If you have not already included it in your JWT token, update the JWT with the sms
      let onesignalJWT = "newTokenThatContainsTheSmsToAdd"
      OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)

      // Add the sms number
      OneSignal.User.addSms(smsNumber)
      ```

      ```c objective-c theme={null}
      // If you have not already included it in your JWT token, update the JWT with the sms
      NSString *onesignalJWT = @"newTokenThatContainsTheSmsToAdd";
      [OneSignal updateUserJwt:externalId withToken:onesignalJWT];

      // Add the sms number
      [OneSignal.User addSms:smsNumber];
      ```
    </CodeGroup>
  </Tab>
</Tabs>

***

## REST API

トークンアイデンティティ検証が有効になっている場合、以下のAPIへのすべてのリクエストには、ベアラートークンとしてヘッダーにサーバー生成のJWTを含める必要があります（例：`Authorization: Bearer <JWT>`）。

* [ユーザーを作成](/reference/create-user)
* [ユーザーを表示](/reference/view-user)
* [ユーザーを更新](/reference/update-user)
* [ユーザーを削除](/reference/delete-user)
* [ユーザーアイデンティティを表示](/reference/fetch-aliases)
* [エイリアスを作成](/reference/create-alias)
* [エイリアスを削除](/reference/delete-alias)
* [サブスクリプションを作成](/reference/create-subscription)
* [サブスクリプションを更新](/reference/update-subscription)

***

## よくある質問

### 本人確認は必須ですか？

いいえ、ただし強く推奨されます。これなしでは、ユーザーの外部ユーザーIDを知っている任意のクライアントがそのユーザーになりすまし、サブスクリプションやデータを変更できてしまいます。

### セッション中にJWTの有効期限が切れた場合はどうなりますか？

SDKはJWT無効化イベントを発火します。`addUserJwtInvalidatedListener`を実装して（[JWTライフサイクルイベントの処理](#handle-jwt-lifecycle-events)を参照）、バックエンドから更新されたトークンを取得して`updateUserJwt`に渡してください。

### どのSDKが本人確認をサポートしていますか？

現在、ネイティブAndroid SDK（5.2.0+）とiOS SDK（5.3.0+）です。ラッパーSDKのサポート（Flutter、React Native、Unityなど）は近日公開予定です。

### REST APIに本人確認は必要ですか？

トークン本人確認が有効な場合、[サポートされているAPI](#rest-api)へのすべてのリクエストは、`Authorization`ヘッダーにサーバー生成のJWTをベアラートークンとして含める必要があります。JWTの生成方法はSDKの使用と同じです。

### JWTはどのアルゴリズムを使用しますか？

本人確認では、**ES256**アルゴリズム（P-256とSHA-256を使用したECDSA）で署名されたJWTが必要です。他のアルゴリズムは拒否されます。

***
