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

# Get User データベースアクションスクリプトとテンプレート

> Get User スクリプトは、Auth0 がユーザーの存在状況を確認する必要があるときに実行されます。

Get User スクリプトは、ユーザーの存在状況を確認する際に実行される関数を実装します。この関数には `getUser` という名前を付けることをお勧めします。

このスクリプトは、[Auth0 への自動移行](/docs/ja-jp/manage-users/user-migration/configure-automatic-migration-from-your-database)に必要です。また、移行が有効でない場合は、接続に設定された操作に応じて必要になることがあります。Auth0 では、重複ユーザーの作成を避けるため、返されるユーザープロファイルに永続的な `user_id` を設定することを推奨します。

**Import Users to Auth0** が有効な場合、ユーザーがサインアップを試みると、外部ユーザーストアにそのユーザーがすでに存在するかどうかを確認するために Get User スクリプトが実行されます。

ユーザーが以下を試みる場合も、Get User スクリプトが実行されます。

* メールアドレスを変更する ([Change Email](/docs/ja-jp/authenticate/database-connections/custom-db/templates/change-email) スクリプト)
* ログインする ([Login](/docs/ja-jp/authenticate/database-connections/custom-db/templates/login) スクリプト)
* パスワードを変更する ([Change Password](/docs/ja-jp/authenticate/database-connections/custom-db/templates/change-password) スクリプト)

**Import Users to Auth0** が無効な場合も、ユーザーがサインアップを試みると、外部ユーザーストアにそのユーザーがすでに存在するかどうかを確認するために Get User スクリプトが実行されます。ユーザーがすでに外部ユーザーストアに存在する場合、Create スクリプトは実行されません。

ユーザーが以下を試みる場合も、Get User スクリプトが実行されます。

* サインアップする  ([Create](/docs/ja-jp/authenticate/database-connections/custom-db/templates/create) スクリプト)
* メールアドレスを変更する  ([Change Email](/docs/ja-jp/authenticate/database-connections/custom-db/templates/change-email) スクリプト)
* パスワードを変更またはリセットする  ([Change Password](/docs/ja-jp/authenticate/database-connections/custom-db/templates/change-password) スクリプト)

<div id="get-user-function">
  ## Get User 関数
</div>

`getUser` 関数は、次の処理を行う必要があります。

* ユーザーの識別子を外部データベースの API に送信する。
* ユーザーが見つかった場合は、そのユーザーのプロファイルデータを返す。
* ユーザーが存在するかどうかの判定時に問題が発生した場合は、エラーを返す。

<div id="definition">
  ### 定義
</div>

`getUser` 関数は2つのパラメータを受け取り、`callback` コールバック関数を返します。

```js lines theme={null}
getUser(email, callback): function
```

| パラメータ      | 型        | 説明                                    |
| ---------- | -------- | ------------------------------------- |
| `email`    | String   | ユーザーのメールアドレス。                         |
| `callback` | Function | エラーまたはプロファイルデータをパイプラインを通じて渡すために使用されます |

これは、`getUser` 関数の実装方法を示した擬似Javascriptの例です。

```javascript lines expandable theme={null}
function getUser(email, callback) {
  // 外部データベースAPIにユーザー識別子を送信する
  let options = {
    url: "https://example.com/api/search-users",
    body: {
      email: email
    }
  };

  send(options, (err, profileData) => {
    // ユーザーの検索中に問題が発生した場合、コールバックでエラーを返す
    if (err) {
      return callback(new Error("Could not determine if user exists or not."));
    } else {
      // ユーザーが見つからなかった場合はコールバックでnullを返し、見つかった場合はプロファイルデータを返す
      if (!profileData) {
        return callback(null);
      } else {
        let profile = {
          email: profileData.email,
          user_id: profileData.userId
        };

        return callback(null, profile);
      }
    }
  });
}
```

<div id="callback-function">
  ## コールバック関数
</div>

`callback` 関数は、ユーザープロファイルデータやエラーデータをパイプライン内で受け渡すために使用されます。

<div id="definition">
  ### 定義
</div>

`callback` 関数は最大2つのパラメータを受け取り、関数を返します。

```js lines theme={null}
callback(error[,profile]): function
```

| パラメータ     | 型      | 必須 | 説明                    |
| --------- | ------ | -- | --------------------- |
| `error`   | オブジェクト | 必須 | エラーデータが含まれます。         |
| `profile` | オブジェクト | 任意 | ユーザーのプロファイルデータが含まれます。 |

<div id="return-the-user-profile-user-found">
  ### ユーザープロファイルを返す (ユーザーが見つかった場合)
</div>

<Warning>
  ユーザーについて Get User スクリプトが返すプロファイルデータは、Login スクリプトが返すプロファイルデータと一致している必要があります。
</Warning>

ユーザーが見つかった場合は、`error` パラメータに `null` を渡し、`profile` パラメータには[正規化された形式](/docs/ja-jp/manage-users/user-accounts/user-profiles/normalized-user-profile-schema)のユーザーのプロファイルデータを渡します。

```js lines theme={null}
return callback(null, {
    username: "username",
    user_id: "my-custom-db|username@domain.com",
    email: "username@domain.com",
    email_verified: false,
    user_metadata: {
        language: "en"
    },
    app_metadata: {
        plan: "full"
    },
    mfa_factors: [
      {
        phone: {
          value: "+15551234567"
        }
      },
    ]
});
```

標準フィールドに加えて、`user_metadata`、`app_metadata`、`mfa_factors` フィールドを含めることもできます。

<div id="return-no-user-profile-user-not-found">
  ### ユーザープロファイルを返さない (ユーザーが見つからない場合)
</div>

ユーザーが見つからない場合は、`error` パラメータには `null` を渡し、`profile` パラメータは省略します：

```js lines theme={null}
return callback(null);
```

<div id="return-an-error">
  ### エラーを返す
</div>

エラーが発生した場合は、問題の内容がわかる関連情報とともに、エラーデータを `error` パラメータに渡します。

```js lines theme={null}
return callback(new Error("My custom error message."));
```

詳しくは、[カスタムデータベースのトラブルシューティング](/docs/ja-jp/authenticate/database-connections/custom-db/error-handling)を参照してください。

<div id="language-specific-script-examples">
  ## 言語別のスクリプト例
</div>

Auth0 では、以下の言語／テクノロジー向けのサンプルスクリプトを提供しています。

<CodeGroup>
  ```javascript Javascript lines theme={null}
  function getByEmail(email, callback) {
    // このスクリプトは、ユーザーを認証せずに既存のデータベースから
    // ユーザープロファイルを取得する必要があります。
    // 認証を必要としないフロー（サインアップおよびパスワードリセット）を実行する前に、
    // ユーザーが存在するかどうかを確認するために使用されます。
    //
    // このスクリプトは、次の3通りの方法で終了します。
    // 1. ユーザーが正常に見つかった場合。プロファイルは次の形式にする必要があります。
    // https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.
    //     callback(null, profile);
    // 2. ユーザーが見つからなかった場合
    //     callback(null);
    // 3. データベースへの接続を試みる際に問題が発生した場合：
    //     callback(new Error("my error message"));
    const msg = 'Please implement the Get User script for this database connection ' +
      'at https://manage.auth0.com/#/connections/database';
    return callback(new Error(msg));
  }
  ```

  ```javascript ASP.NET MVC3 lines expandable theme={null}
  // ASP.NET Membership Provider（MVC3 - Universal Providers）用
  function getByEmail(email, callback) {
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName: 'the username',
      password: 'the password',
      server: 'the server',
      options: {
        database: 'the db name',
        encrypt: true // for Windows Azure
      }
    });
    connection.on('debug', function(text) {
      // if you have connection issues, uncomment this to get more detailed info
      //console.log(text);
    }).on('errorMessage', function(text) {
      // SQLデータベースへの接続時またはSQLステートメントでエラーが発生した場合に表示されます
      console.log(JSON.stringify(text));
    });
    connection.on('connect', function(err) {
      if (err) return callback(err);
      var user = {};
      const query =
        'SELECT Memberships.UserId, Email, Users.UserName ' +
        'FROM Memberships INNER JOIN Users ' +
        'ON Users.UserId = Memberships.UserId ' +
        'WHERE Memberships.Email = @Username OR Users.UserName = @Username';
      const getMembershipQuery = new Request(query, function(err, rowCount) {
        if (err) return callback(err);
        if (rowCount < 1) return callback();
        callback(null, user);
      });
      getMembershipQuery.addParameter('Username', TYPES.VarChar, email);
      getMembershipQuery.on('row', function(fields) {
        user = {
          user_id: fields.UserId.value,
          nickname: fields.UserName.value,
          email: fields.Email.value
        };
      });
      connection.execSql(getMembershipQuery);
    });
  }
  ```

  ```javascript ASP.NET MVC4 lines expandable theme={null}
  // ASP.NET Membership Provider（MVC4 - Simple Membership）用
  function getByEmail(email, callback) {
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName: 'the username',
      password: 'the password',
      server: 'the server',
      options: {
        database: 'the db name',
        encrypt: true // for Windows Azure
      }
    });
    connection.on('debug', function(text) {
      // if you have connection issues, uncomment this to get more detailed info
      //console.log(text);
    }).on('errorMessage', function(text) {
      // this will show any errors when connecting to the SQL database or with the SQL statements
      console.log(JSON.stringify(text));
    });
    connection.on('connect', function(err) {
      if (err) return callback(err);
      var user = {};
      const query =
        'SELECT webpages_Membership.UserId, UserName, UserProfile.UserName from webpages_Membership ' +
        'INNER JOIN UserProfile ON UserProfile.UserId = webpages_Membership.UserId ' +
        'WHERE UserProfile.UserName = @Username';
      const getMembershipQuery = new Request(query, function (err, rowCount) {
        if (err) return callback(err);
        if (rowCount < 1) return callback();
        callback(null, user);
      });
      getMembershipQuery.addParameter('Username', TYPES.VarChar, email);
      getMembershipQuery.on('row', function (fields) {
        user = {
          user_id: fields.UserId.value,
          nickname: fields.UserName.value,
          email: fields.UserName.value
        };
      });
      connection.execSql(getMembershipQuery);
    });
  }
  ```

  ```javascript MongoDB lines theme={null}
  function getByEmail(email, callback) {
    const MongoClient = require('mongodb@5.1.0').MongoClient;
    const client = new MongoClient('mongodb://user:pass@mymongoserver.com');
    client.connect(function (err) {
      if (err) return callback(err);
      const db = client.db('db-name');
      const users = db.collection('users');
      users.findOne({ email: email }, function (err, user) {
        client.close();
        if (err) return callback(err);
        if (!user) return callback(null, null);
        return callback(null, {
          user_id: user._id.toString(),
          nickname: user.nickname,
          email: user.email
        });
      });
    });
  }
  ```

  ```javascript MySQL lines theme={null}
  function getByEmail(email, callback) {
    const mysql = require('mysql');
    const connection = mysql({
      host: 'localhost',
      user: 'me',
      password: 'secret',
      database: 'mydb'
    });
    connection.connect();
    const query = 'SELECT id, nickname, email FROM users WHERE email = ?';
    connection.query(query, [ email ], function(err, results) {
      if (err || results.length === 0) return callback(err || null);
      const user = results[0];
      callback(null, {
        user_id: user.id.toString(),
        nickname: user.nickname,
        email: user.email
      });
    });
  }
  ```

  ```javascript PostgreSQL lines theme={null}
  function loginByEmail(email, callback) {
    //この例では「pg」ライブラリを使用します
    //詳細はこちら: https://github.com/brianc/node-postgres
    const postgres = require('pg');
    const conString = 'postgres://user:pass@localhost/mydb';
    postgres.connect(conString, function (err, client, done) {
      if (err) return callback(err);
      const query = 'SELECT id, nickname, email FROM users WHERE email = $1';
      client.query(query, [email], function (err, result) {
        // 注: データベース接続を閉じるため、ここでは必ず`done()`を呼び出します
        done();
        if (err || result.rows.length === 0) return callback(err);
        const user = result.rows[0];
        return callback(null, {
          user_id: user.id,
          nickname: user.nickname,
          email: user.email
        });
      });
    });
  }
  ```

  ```javascript SQL Server lines expandable theme={null}
  function getByEmail(email, callback) {
    //この例では「tedious」ライブラリを使用します
    //詳細はこちら: http://pekim.github.io/tedious/index.html
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName:  'test',
      password:  'test',
      server:    'localhost',
      options:  {
        database: 'mydb'
      }
    });
    const query = 'SELECT Id, Nickname, Email FROM dbo.Users WHERE Email = @Email';
    connection.on('debug', function (text) {
      console.log(text);
    }).on('errorMessage', function (text) {
      console.log(JSON.stringify(text, null, 2));
    }).on('infoMessage', function (text) {
      console.log(JSON.stringify(text, null, 2));
    });
    connection.on('connect', function (err) {
      if (err) return callback(err);
      const request = new Request(query, function (err, rowCount, rows) {
        if (err) return callback(err);
        callback(null, {
          user_id: rows[0][0].value,
          nickname: rows[0][1].value,
          email: rows[0][2].value
        });
      });
      request.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(request);
    });
  }
  ```

  ```javascript Azure SQL Database lines theme={null}
  function getByEmail (name, callback) {
    var profile = {
      user_id:     "103547991597142817347",
      nickname:    "johnfoo",
      email:       "johnfoo@gmail.com",
      name:        "John Foo",
      given_name:  "John",
      family_name: "Foo"
    };
    callback(null, profile);
  }
  ```

  ```js Axios lines expandable theme={null}
  async function getUserAsync(email, callback) {
    //axiosの新しいバージョンが利用可能になったら更新してください（https://auth0-extensions.github.io/canirequire/#axios）
    const axios = require("axios@0.22.0");

    let response;

    try {
      response = await axios.post(
        //SDLC環境を適切にサポートするため、API URLは接続設定に保存します
        configuration.baseAPIUrl + "/getUser",
        //リクエスト本文として渡されるユーザー資格情報
        {
          email: email,
        },
        {
          timeout: 10000, //リクエストがタイムアウトした場合は適切に呼び出しを終了し、スクリプトが必要なコールバックを実行できるようにします
          headers: {
            //接続設定に保存されたapiKeyでAPI呼び出しを保護します。
            //手軽な方法ですが、M2M トークンを使用する方が安全です。これは、
            // シークレットをクライアントとAPIの間で共有してはならないためです。
            "x-api-key": configuration.apiKey,
          },
        }
      );
    } catch (e) {
      if (e.response.status === 404) {
        //指定されたメールアドレスまたはユーザー名のユーザーが見つからない場合、APIが404を返すことを想定します
        return callback(null, null);
      }
      //その他のエラーに対するコールバック
      return callback(new Error(e.message));
    }

    try {
      let user = response.data;

      //テナントで複数のカスタムDB接続を使用する場合は、
      //user_idの先頭に接続固有のキーを付加します。例: "connName|" + user.user_id
      //これにより、すべてのDB接続でユーザーIDの一意性が保証されます
      return callback(null, {
        user_id: user.user_id,
        email: user.email,
      });
    } catch (e) {
      return callback(new Error(e.message));
    }
  }
  ```

  ```javascript Stormpath lines expandable theme={null}
  function getByEmail(email, callback) {
    // {yourStormpathClientId}をStormpath IDに置き換えます
    var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts';
    // Stormpath APIクライアントIDとシークレットを追加します
    var apiCredentials = {
      user : '{yourStormpathApiId}',
      password: '{yourStormpathApiSecret}'
    };
    // メールアドレスでユーザーを検索するためのGETリクエストを行います
    request({
      url: url,
      method: 'GET',
      auth: apiCredentials,
      qs: { q: email },
      json: true
    }, function (error, response, body) {
      if (response.statusCode !== 200) return callback();
      var user = body.items[0];
      if (!user) return callback();
      var id = user.href.replace('https://api.stormpath.com/v1/accounts/', '');
      return callback(null, {
        user_id: id,
        username: user.username,
        email: user.email,
        email_verified: true
        // Stormpathから引き継ぎたい追加フィールドを追加します
      });
    });
  }
  ```
</CodeGroup>
