> ## 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 スクリプトは、ユーザーが現在存在するかどうかを判定するために実行される関数を実装します。この関数の名前は `getUser` にすることを推奨します。

このスクリプトは、[自動移行](/ja/docs/manage-users/user-migration/configure-automatic-migration-from-your-database)では必須であり、レガシー認証では接続に設定されている操作に応じて条件付きで必須になります。重複するユーザーが作成されるのを防ぐため、返されるユーザープロファイルには永続的な `user_id` を設定することを Auth0 では推奨しています。

接続で自動移行が設定されていて、ユーザープロファイルがまだ作成されていない場合、このスクリプトは次の操作が発生するたびに実行されます。

* メールアドレスの変更
* サインアップ
* パスワードリセット

接続でレガシー認証が設定されている場合、このスクリプトは次の操作が発生するたびに実行されます。

* ユーザーの作成
* メールアドレスの変更
* パスワードの変更
* パスワードリセット

<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 の例です。言語ごとの例については、[言語別のスクリプト例](#language-specific-script-examples)を参照してください。

```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`   | Object | 必須 | エラーデータを含みます。         |
| `profile` | Object | 任意 | ユーザーのプロフィールデータを含みます。 |

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

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

ユーザーが見つかった場合は、`error` パラメータに `null` を渡し、`profile` パラメータにユーザーのプロファイルデータを[正規化形式](/ja/docs/manage-users/user-accounts/user-profiles/normalized-user-profile-schema)で渡します。標準フィールドに加えて、`user_metadata`、`app_metadata`、`mfa_factors` フィールドも含めることができます。

<div id="example">
  #### 例
</div>

```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"
        }
      },
    ]
});
```

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

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

<div id="example">
  #### 例
</div>

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

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

エラーが発生した場合は、何が原因で問題が起きたのかがわかる関連情報を含むエラーデータを `error` パラメーターに渡します。詳細については、[カスタムデータベースのトラブルシューティング](/ja/docs/authenticate/database-connections/custom-db/error-handling)を参照してください。

<div id="example">
  #### 例
</div>

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

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

Auth0 では、以下の言語/技術で使用できるサンプルスクリプトを提供しています。

* [JavaScript](#javascript)
* [ASP.NET Membership Provider (MVC3 - Universal Providers)](#asp-net-membership-provider-mvc3-universal-providers-)
* [ASP.NET Membership Provider (MVC4 - Simple Membership)](#asp-net-membership-provider-mvc4-simple-membership-)
* [MongoDB](#mongodb)
* [MySQL](#mysql)
* [PostgreSQL](#postgresql)
* [SQL Server](#sql-server)
* [Windows Azure SQL Database](#windows-azure-sql-database)
* [Axios](#axios)
* [Stormpath](#stormpath)

<div id="javascript">
  ### JavaScript
</div>

```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));
}
```

<div id="aspnet-membership-provider-mvc3-universal-providers">
  ### ASP.NET メンバーシップ プロバイダー (MVC3 - Universal Providers)
</div>

```javascript lines expandable theme={null}
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) {
    // 接続に問題がある場合は、詳細情報を取得するためにコメントを解除してください
    //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);
  });
}
```

<div id="aspnet-membership-provider-mvc4-simple-membership">
  ### ASP.NET メンバーシップ プロバイダー (MVC4 - Simple Membership)
</div>

```javascript lines expandable theme={null}
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 // Windows Azure の場合
    }
  });
  connection.on('debug', function(text) {
    // 接続に問題がある場合は、このコメントを解除するとより詳細な情報を確認できます
    //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 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);
  });
}
```

<div id="mongodb">
  ### MongoDB
</div>

```javascript 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
      });
    });
  });
}
```

<div id="mysql">
  ### MySQL
</div>

```javascript 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
    });
  });
}
```

<div id="postgresql">
  ### PostgreSQL
</div>

```javascript 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
      });
    });
  });
}
```

<div id="sql-server">
  ### SQL Server
</div>

```javascript 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);
  });
}
```

<div id="windows-azure-sql-database">
  ### Windows Azure SQL Database
</div>

```javascript 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);
}
```

<div id="axios">
  ### Axios
</div>

```js 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コールを保護する。
          //手軽な方法だが、クライアントとAPI間でシークレットを共有すべきでないため、
          // M2Mトークンを使用する方がより安全。
          "x-api-key": configuration.apiKey,
        },
      }
    );
  } catch (e) {
    if (e.response.status === 404) {
      //指定されたメールアドレス/usernameのユーザーが見つからない場合、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));
  }
}
```

<div id="stormpath">
  ### Stormpath
</div>

```javascript 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 から引き継ぎたい追加フィールドをここに追加してください
    });
  });
}
```

<div id="learn-more">
  ## 詳しくはこちら
</div>

* [パスワード変更用スクリプトテンプレート](/ja/docs/authenticate/database-connections/custom-db/templates/change-password)
* [作成用スクリプトテンプレート](/ja/docs/authenticate/database-connections/custom-db/templates/create)
* [削除用スクリプトテンプレート](/ja/docs/authenticate/database-connections/custom-db/templates/delete)
* [ログイン用スクリプトテンプレート](/ja/docs/authenticate/database-connections/custom-db/templates/login)
* [確認用スクリプトテンプレート](/ja/docs/authenticate/database-connections/custom-db/templates/verify)
* [メールアドレス変更用スクリプトテンプレート](/ja/docs/authenticate/database-connections/custom-db/templates/change-email)
