> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ユーザー取得スクリプトのテンプレート

> ユーザーを検索するための、カスタムデータベースのアクションスクリプト用テンプレートについて説明します。

ユーザー取得スクリプトは、ユーザーの現在の存在状態を特定するための関数を実装します。この関数の名前は`getUser`にすることをお勧めします。

このスクリプトは[自動移行](/docs/ja-jp/manage-users/user-migration/configure-automatic-migration-from-your-database)には必須で、接続に構成された操作によっては、レガシー認証に条件付きで必須になります。

接続に自動移行を構成していて、ユーザープロファイルが作成されていない場合には、以下の操作が起きると必ずこのスクリプトが実行されます。

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

接続にレガシー認証が構成されている場合には、以下の操作が起きると必ずこのスクリプトが実行されます。

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

## ユーザー取得関数

`getUser`は以下を行う必要があります。

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

### 定義

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

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

| パラメーター     | 種類  | 説明                                  |
| ---------- | --- | ----------------------------------- |
| `email`    | 文字列 | ユーザーのメールアドレス。                       |
| `callback` | 関数  | パイプラインを介してエラーまたはプロファイルデータを渡すのに使用される |

### 例

これは疑似JavaScriptを使った例で、どのようにすれば`getUser`関数を実装できるかがわかります。言語固有の例については、「[言語固有のスクリプトの例](#language-specific-script-examples)」をお読みください。

```javascript lines expandable theme={null}
function getUser(email, callback) {
  // Send user identifier to external database API
  let options = {
    url: "https://example.com/api/search-users",
    body: {
      email: email
    }
  };

  send(options, (err, profileData) => {
    // Return error in callback if there was an issue finding the user
    if (err) {
      return callback(new Error("Could not determine if user exists or not."));
    } else {
      // Return null in callback if user was not found, return profile data in callback if user was found
      if (!profileData) {
        return callback(null);
      } else {
        let profile = {
          email: profileData.email,
          user_id: profileData.userId
        };

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

## コールバック関数

`callback`関数は、パイプラインを通してユーザープロファイルデータやエラーデータを渡すのに使用されます。

### 定義

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

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

| パラメーター    | 種類     | 必須 | 説明                 |
| --------- | ------ | -- | ------------------ |
| `error`   | オブジェクト | 必須 | エラーデータを含む。         |
| `profile` | オブジェクト | 任意 | ユーザーのプロファイルデータを含む。 |

### ユーザープロファイルを返す（ユーザーが見つかった場合）

<Warning>
  Get Userスクリプトがユーザーについて返すプロファイルデータは、Loginスクリプトが返すプロファイルデータと整合性がなければなりません。
</Warning>

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

#### 例

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

### ユーザープロファイルを返さない（ユーザーが見つからなかった場合）

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

#### 例

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

### エラーの場合

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

#### 例

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

## 言語固有のスクリプトの例

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)

### JavaScript

```javascript lines theme={null}
function getByEmail(email, callback) {
  // This script should retrieve a user profile from your existing database,
  // without authenticating the user.
  // It is used to check if a user exists before executing flows that do not
  // require authentication (signup and password reset).
  //
  // There are three ways this script can finish:
  // 1. A user was successfully found. The profile should be in the following
  // format: https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.
  //     callback(null, profile);
  // 2. A user was not found
  //     callback(null);
  // 3. Something went wrong while trying to reach your database:
  //     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));
}
```

### ASP.NET Membership Provider（MVC3 - Universal Providers）

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

### ASP.NET Membership Provider（MVC4 - Simple Membership）

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

### MongoDB

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

### MySQL

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

### PostgreSQL

```javascript lines theme={null}
function loginByEmail(email, callback) {
  //this example uses the "pg" library
  //more info here: 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) {
      // NOTE: always call `done()` here to close
      // the connection to the database
      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
      });
    });
  });
}
```

### SQL Server

```javascript lines expandable theme={null}
function getByEmail(email, callback) {
  //this example uses the "tedious" library
  //more info here: 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);
  });
}
```

### Windows Azure SQL Database

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

### Axios

```js lines expandable theme={null}
async function getUserAsync(email, callback) {
  //should be updated as new versions of axios are made available (https://auth0-extensions.github.io/canirequire/#axios)
  const axios = require("axios@0.22.0");

  let response;

  try {
    response = await axios.post(
      //store API url in connection settings to better support SDLC environments
      configuration.baseAPIUrl + "/getUser",
      //user credentials passed as request body
      {
        email: email,
      },
      {
        timeout: 10000, //end call gracefully if request times out so script can do necessary callback
        headers: {
          //securing api call with apiKey stored in connection settings.
          //quick and easy approach however using M2M tokens is more secure as
          // a secret must not be shared between client and API.
          "x-api-key": configuration.apiKey,
        },
      }
    );
  } catch (e) {
    if (e.response.status === 404) {
      //assuming api returns 404 when no user with specified email/username found
      return callback(null, null);
    }
    //callback for any other error type
    return callback(new Error(e.message));
  }

  try {
    let user = response.data;

    //if using multiple custom db connections in your tenant prefix the
    //user_id with a connection specific key ex: "connName|" + user.user_id
    //this ensures unique user ids across all db connections
    return callback(null, {
      user_id: user.user_id,
      email: user.email,
    });
  } catch (e) {
    return callback(new Error(e.message));
  }
}
```

### Stormpath

```javascript lines expandable theme={null}
function getByEmail(email, callback) {
  // Replace the {yourStormpathClientId} with your Stormpath ID
  var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts';
  // Add your Stormpath API Client ID and Secret
  var apiCredentials = {
    user : '{yourStormpathApiId}',
    password: '{yourStormpathApiSecret}'
  };
  // Make a GET request to find a user by email
  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
      // Add any additional fields you would like to carry over from Stormpath
    });
  });
}
```

## もっと詳しく

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