---
title: "Auth0 HooksからAuth0 Actionsへの移行"
description: "Auth0 HooksからAuth0 Actionsへの移行を検討している方に向けたガイドラインをご案内します。"
authors:
  - name: "Andrea Chiarelli"
    url: "https://auth0.com/blog/authors/andrea-chiarelli/"
date: "Jul 21, 2023"
category: "Developers,Tutorial,Actions"
tags: ["actions", "auth0-actions", "auth0-hooks", "hooks", "migration"]
url: "https://auth0.com/blog/jp-migrating-auth0-hooks-to-auth0-actions/"
---

# Auth0 HooksからAuth0 Actionsへの移行

<div class="alert alert-danger alert-icon">
<i class="icon-budicon-487"></i>
<strong>Auth0 RulesとAuth0 Hooksは2024年11月18日までに廃止されます。</strong>変更内容の詳細については、<a href="https://auth0.com/blog/jp-preparing-for-rules-and-hooks-end-of-life/">Auth0 RulesとAuth0 Hooksの提供終了について</a>をご覧ください。
</div>

Auth0 Hooksは、Auth0 Rulesが提供するカスタマイズ機能をさらに充実させてきました。現在はAuth0 RulesとAuth0 Hooksと同様の機能を1つで実現できる、Auth0 Actionsが強力な統合環境を提供しています。この記事では既存のAuth0 HooksをAuth0 Actionsに移行する方法を説明します。

## Auth0 Actionsとカスタマイズ

Auth0の強みの1つは、拡張性に焦点を当てていることです。基本的なログインおよびログアウト機能に加えて、**特定の要件に合致するよう、Auth0の裏側の処理の一部を標準的なフローから変更できます**。たとえば、ユーザーのアプリケーション登録時に追加の認証チェックや特定の処理を実行できます。

これまで[Auth0 Rules](https://auth0.com/docs/customize/rules)と[Auth0 Hooks](https://auth0.com/docs/customize/hooks)を用いてこのフローのカスタマイズができました。Auth0 Rulesは認証フローのカスタマイズに利用できます。一方、Auth0 Hooksは、ユーザー登録前と登録後、パスワード変更、SMS送信時などいくつか定義されている時点の処理をカスタマイズできます。

現在ではAuth0 RulesやAuth0 Hooksとほぼ同等のカスタマイズを実現できる[Auth0 Actions](https://auth0.com/docs/customize/actions)を利用できます。 **Auth0 Actionsは、Auth0 RulesとAuth0 Hooksで提供していた拡張ポイントをカスタマイズするための統合された開発環境**を1つの機能として提供します。 Auth0 Actionsは、Auth0 RulesやAuth0 Hooksと同じ機能を提供するだけではありません。開発エクスペリエンスを向上する追加機能も提供します。

-  Auth0 Actionsは**統合バージョンシステム**を提供します。本番環境のAuth0 Actionsに影響を与えることなくAuth0 Actionsの変更や複数のバージョンを作成できます。また、以前のバージョンの復元も可能です。
-  Auth0 Actionsエディターはコードヒント、すべてのnpmパッケージ、および分離されたシークレット情報の管理をサポートします。
- [Auth0マーケットプレイス](https://marketplace.auth0.com/)で提供されている[ノーコードインテグレーション](https://marketplace.auth0.com/features/actions)を利用できます。弊社パートナーが構築したインテグレーションはユーザーの同意管理、プログレッシブプロファイリング、ユーザー検証などの一般的なIDユースケースを拡張します。これらのインテグレーションを利用すると、カスタムコードを利用した場合に比べて開発コストとメンテナンスコストを削減しつつ、迅速な市場投入を可能にします。

Auth0 Actionsの紹介については、こちらの[記事](https://auth0.com/blog/introducing-auth0-actions/)をお読みください。

> Auth0 Actionsは改善されたカスタマイズ環境をもたらしますが、Auth0 RulesとAuth0 Hooksは提供終了日まで引き続き利用可能であり、Auth0 Actionsと共存できます。<u>Auth0 RulesとAuth0 HooksはAuth0 Actionsの前に実行されることに注意してください。</u>

現在、Auth0 Actionsは、Auth0 RulesとAuth0 Hooksの代替として推奨されています。この記事では、Auth0 HooksをAuth0 Actionsに移行するためのガイドラインを説明します。[Auth0 RulesからAuth0 Actionsへの移行](https://auth0.com/blog/jp-migrating-auth0-rules-to-auth0-actions/)も併せてご覧ください。

## コード変換ガイドライン

Auth0 Hooksを同等のAuth0 Actionsに変換するには、このセクションのガイドラインに従ってください。


### Auth0 Hookの種類とAuth0 Actionのトリガーとのマッピング

最初のステップとして、[Auth0 Hookの種類](https://auth0.com/docs/customize/hooks/extensibility-points)に対応するAuth0 Actionのトリガーを特定します。[Auth0 Actionトリガー](https://auth0.com/docs/customize/actions/flows-and-triggers)は、フロー内で発生するイベントです。次の表は、各Auth0 Hookの種類をそれぞれのAuth0 Actionトリガーにマッピングしています。

<style>
  table {
    width: 100%;
    border-collapse: collapse;
  }
  table, td, th {
    border: 1px solid;
  }
  td {
    padding: 5px;
  }
</style>
<table>
    <tr>
        <th>Auth0 Hookの種類</th>
        <th>Auth0 Actionのトリガー</th>
    </tr>
  <tr>
    <td>
      Pre-User Registration
    </td>
    <td>
      Pre User Registration
    </td>
  </tr>
  <tr>
    <td>
      Post-User Registration
    </td>
    <td>
      Post User Registration
    </td>
  </tr>
  <tr>
    <td>
      Post-Change Password
    </td>
    <td>
      Post Change Password
    </td>
  </tr>
  <tr>
    <td>
      Send Phone Message
    </td>
    <td>
      Send Phone Message
    </td>
  </tr>
  <tr>
    <td>
      Client Credential Exchange
    </td>
    <td>
      M2M/Client-Credentials
    </td>
  </tr>
</table>
<br/>

Auth0 Hookの種類とAuth0 Actionのトリガーの名前は、ほぼ同じです。そのためAuth0 HooksをAuth0 Actionsに変換する場合は、適切なトリガーを選択して[Auth0 Actionを作成](https://auth0.com/docs/customize/actions/write-your-first-action)します。トリガーは次の図に示すようにリストから選択します。

![Auth0 Actionsトリガーリスト](https://images.ctfassets.net/23aumh6u8s0i/5gxQgwFP7FzKLPr1UVFgI8/79ff2cae324b70c21740bac057b8e365/select-auth0-action-trigger.png)

トリガーを選択すると、Auth0 Actionエディターに空の[名前付きエクスポート宣言](https://developer.mozilla.org/ja/docs/web/javascript/reference/statements/export)が表示されます。選択したトリガーによってエクスポートの名前が異なります。たとえば、Post-User Registration HookをPost User Registration Actionトリガーに変換するとAuth0 Actionエディターに次のコードが表示されます。

```JavaScript
exports.onExecutePostUserRegistration = async (event) => {
  
};
```

次の表ではAuth0 Hookの種類と対応するエクスポート名のマッピングを確認できます。

<table>
<tr>
<th>Auth0 Hookの種類</th>
<th>Auth0 Actionのトリガー</th>
<th>エクスポート名</th>
</tr>
<tr>
  <tr>
    <td>
      Pre-User Registration
    </td>
    <td>
      Pre User Registration
    </td>
    <td>
      `onExecutePreUserRegistration`
    </td>
  </tr>
  <tr>
    <td>
      Post-User Registration
    </td>
    <td>
      Post User Registration
    </td>
    <td>
      `onExecutePostUserRegistration`
    </td>
  </tr>
  <tr>
    <td>
      Post-Change Password
    </td>
    <td>
      Post Change Password
    </td>
    <td>
      `onExecutePostChangePassword`
    </td>
  </tr>
  <tr>
    <td>
      Send Phone Message
    </td>
    <td>
      Send Phone Message
    </td>
    <td>
      `onExecuteSendPhoneMessage`
    </td>
  </tr>
  <tr>
    <td>
      Client Credential Exchange
    </td>
    <td>
      M2M/Client-Credentials
    </td>
    <td>
      `onExecuteCredentialsExchange`
    </td>
  </tr>
</table>
<br/>



Auth0 Hookの実装は、新しく作成したAuth0 Actionに組みこみます。ただし、いくつかの変更を加える必要があります。

### パラメータのマッピング

Auth0 Hooksで使用されている関数は、Hookのタイプに応じて、ユーザー、クライアント、リクエストなどに関するコンテキストデータを複数のパラメータで受け取ります。そのため、ほとんどのHook関数には、`user`、`context`、および`cb`という3つのパラメータが用意されています。一部のHookタイプの関数では、さらに別のパラメータで追加のデータを受け取ります。

Auth0 Actionsは、実行環境からAction関数に渡されるデータを最大2つの引数 (`event`および`api`) に統合します。Hookの`user`オブジェクトと`context`オブジェクトのすべての読み取り専用プロパティは、Auth0 Actionsの`event`オブジェクトに含まれています。また、ユーザーメタデータの追加など、実行環境とのインタラクションは`api`オブジェクトのメソッドを通じて実装されています。

注意すべき点として、それぞれのAuth0 Actionトリガーにおける`event`オブジェクトと`api`オブジェクトは同じ名前でありながらも、トリガーごとに構造が異なります。次の表ではAuth0 Hookの種類を起点としてそれぞれのAuth0 Actionトリガーが持つ`event`オブジェクトと`api`オブジェクトのドキュメントをマッピングしています。

<table>
  <tr>
  <th>Auth0 Hookの種類</th>
  <th>Auth0 Actionエクスポート名</th>
  <th>`event` docs</th>
  <th>`api` docs</th>
  </tr>
  <tr>
    <td>
      Pre-User Registration
    </td>
    <td>
      `onExecutePreUserRegistration`
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/pre-user-registration-flow/event-object">`event` docs</a>
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/pre-user-registration-flow/api-object">`api` docs</a>
    </td>
  </tr>
  <tr>
    <td>
      Post-User Registration
    </td>
    <td>
      `onExecutePostUserRegistration`
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/post-user-registration-flow/event-object">`event` docs</a>
    </td>
    <td>
      &nbsp;
    </td>
  </tr>
  <tr>
    <td>
      Post-Change Password
    </td>
    <td>
      `onExecutePostChangePassword`
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/post-change-password-flow/event-object">`event` docs</a>
    </td>
    <td>
      &nbsp;
    </td>
  </tr>
  <tr>
    <td>
      Send Phone Message
    </td>
    <td>
      `onExecuteSendPhoneMessage`
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/send-phone-message-flow/event-object">`event` docs</a>
    </td>
    <td>
      &nbsp;
    </td>
  </tr>
  <tr>
    <td>
      Client Credential Exchange
    </td>
    <td>
      `onExecuteCredentialsExchange`
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/machine-to-machine-flow/event-object">`event` docs</a>
    </td>
    <td>
      <a href="https://auth0.com/docs/customize/actions/flows-and-triggers/machine-to-machine-flow/api-object">`api` docs</a>
    </td>
  </tr>
</table>
<br/>



### 依存関係の処理

Auth0 Hooksではさまざまな機能を追加するために依存関係を含めることができます。数千のnpmパッケージを利用できますが、[npm レジストリ](https://www.npmjs.com/)で利用可能なすべてのパッケージを利用できるわけではありませんでした。Auth0 Hooksで利用できないパッケージ(またはnpmパッケージの特定のバージョンのみ)が必要な場合は、その旨をリクエストする必要がありました。

Auth0 Actionsでは、npmレジストリ内の利用可能な100万以上にもおよぶすべてのパッケージを依存関係として追加できます。

また、Auth0 Hooksとは異なり、Auth0 Actionsではコード内でパッケージのバージョンを指定する必要はありません。たとえば、Auth0 Hooksでは次のように依存関係を宣言する必要がありました。

```JavaScript
// ユーザー登録後の拡張ポイントAuth0 Hook

module.exports = function (user, context, cb) {
  const axios = require("axios@0.22.0");

  // ... 他のコード
}
```

Auth0 Actionsでは、エディターの[モジュールマネージャー](https://auth0.com/docs/customize/actions/manage-dependencies#add-a-dependency-using-the-actions-code-editor) でパッケージのバージョンを指定します。そのためコードは次のようになります。

```JavaScript
const axios = require("axios");

exports.onExecutePostUserRegistration = async (event) => {

  // ... 他のコード
};
```

ここでは依存関係を関数の本体の外側でNode.jsのスタイルでインポートしていることに注意してください。

### Auth0 Hooksコールバックの変換

Client Credentials ExchangeとPre User Registrationでは、`cb`パラメーターを使用して処理の結果を返します。たとえば、コードがそのステップを完了すると、制御をランタイム環境に渡す必要があります。また、その後にランタイム環境が続けて次のAuth0 Hookを実行する可能性があります。このような場合、`cb()`関数を呼び出し、処理結果または処理が失敗した場合のエラーインスタンスを渡します。

Auth0 Actionsを使用すると実装がシンプルになります。制御をランタイム環境へ渡すためにコールバック関数を呼び出す必要はありません。代わりに`return`を使用します。

また、Actionトリガーに渡される`api`引数を通じて、ランタイム環境と対話ができます。たとえば、M2M/Client-CredentialsおよびPre User Registration Actionトリガーは、2番目のパラメーターとして`api`オブジェクトを持ちます。これらのActionトリガーでは、`api.access.deny()`メソッドを呼び出しユーザー登録を中止できます。

次のセクションでこのガイドラインの実際の適用方法について確認できます。

### シークレットの変換

Auth0 Hooksと同様に、Actionエディターの*Add Secrets*ボタンを使用しシークレットとしてキーと値を定義できます。

![Auth0 Actionsのシークレットを定義](https://images.ctfassets.net/23aumh6u8s0i/7GqBspWIfMBLPLxfz2qfWm/fd53857838092bfcafebb0a31f621536/configure-auth0-action-secret.png)

Auth0 Action関数内におけるシークレットへのアクセス方法は、Auth0 Hooksでのアクセス方法と異なります。

Auth0 Hook関数では、次の例のようにシークレットにアクセスします。

```JavaScript
module.exports = function (user, context, cb) {
  const mySecret = context.webtask.secrets.MY_SECRET;

  // ... 他のコード
}
```

Auth0 Actionトリガー関数では、次のようにシークレットを取得します。

```JavaScript
exports.onExecutePostChangePassword = async (event) => {
  const mySecret = event.secrets.MY_SECRET;
  
  // ... 他のコード
};
```

Auth0 Actionエディターで定義されたシークレットは、`event.secrets`オブジェクトのプロパティとして利用できます。

## 変換例

これまでのAuth0 HooksのコードをAuth0 Actionsに変換するための一般的なガイドラインをもとにいくつかの例を見てみましょう。

### 新しいユーザーにメタデータを追加する

次のPre User Registration Hookにおける実装を変換します。

```JavaScript
module.exports = function (user, context, cb) {
  const response = {};

  if (user.phoneNumber) {
    response.user = {
     user_metadata: { favorite_color: "green" }
    };

    cb(null, response);    
  } else {
    return cb(new Error("電話番号は必須項目です"));
  }
};
```

このコードは、ユーザーが電話番号を提供した場合にのみ、ユーザーのメタデータにユーザーの好きな色として緑を割り当てます。電話番号を提供しない場合エラーが発生し、登録が行われません。

対応するPre User Registration Actionトリガーは次のような実装になります。

```JavaScript
exports.onExecutePreUserRegistration = async (event, api) => {
  if (user.phoneNumber) {
    api.user.setUserMetadata("favorite_color", "green");
  } else {
    return api.access.deny("エラー: 電話番号がありません; お気に入りの色が設定されていません",
                           "電話番号は必須項目です");
  }
};
```

新しく作成されたメタデータをランタイム環境に戻すためには、`cb()`コールバック関数を呼び出す代わりに、`api.user.setUserMetadata()`メソッドを使用します。ここでも、`cb()`関数の代わりに`api`オブジェクトを使用して、ユーザーが登録できないようにします。Pre User Registrationトリガーの場合、APIオブジェクトの`deny`メソッドは内部で使用される`reason`とUIエラーを表示するために使用できる`userMessage`の2つを受け取ります。

### カスタムクレームの追加

Client Credentials Exchange Hookでは、次に示すように、アクセストークンにカスタムクレームを追加できます。

```JavaScript
module.exports = function(client, scope, audience, context, cb) {
  const access_token = {};
  const namespace = "https://myapp.example.com";
  
  access_token.scope = scope;

  access_token[`${namespace}/favorite_color`] = "green";
  cb(null, access_token);
};
```

この実装を次のようにM2M/Client-Credentials Actionトリガーに変換できます。

```JavaScript
exports.onExecuteCredentialsExchange = async (event, api) => {
  const namespace = "https://myapp.example.com";
  
  api.accessToken.setCustomClaim(`${namespace}/favorite_color`, "green");  
};
```

コールバック関数を呼び出す必要はありません。`api.accessToken.setCustomClaim()`メソッドを使用し、新しく作成したカスタムクレームに値を割り当てます。

### 通知メールの送信

次にPost-Change Passwordについて検討します。下記のコードは[SendGrid](https://sendgrid.kke.co.jp/) を使用し、パスワード変更時にユーザーへ電子メールを送信します。

```JavaScript
module.exports = function (user, context, cb) {
  const request = require("request");
  const sendgridApiKey = context.webtask.secrets.SENDGRID_API_KEY;

  request.post({
    url: "https://api.sendgrid.com/v3/mail/send",
    headers: {
      "Authorization": "Bearer " + sendgridApiKey
    },
    json: {
      personalizations: [{
        to: [{
          email: user.email
        }]
      }],
      from: {
        email: "admin@example.com"
      },
      subject: "パスワードが変更されました",
      content: [{
        type: 'text/plain',
        value: `${context.connection.name} アカウント ${user.email} のパスワードが最近変更されました。`
      }]
    }
  }, function (err, resp, body) {
    if (err || resp.statusCode !== 202) {
      return cb(err || new Error(body.errors[0].message));
    }

    cb();
  });
};
```

このAuth0 Hookは、Post Change Password Actionトリガーに変換できます。

```JavaScript
exports.onExecutePostChangePassword = async (event) => {
  const request = require("request");
  //👇 コード変更箇所
  const sendgridApiKey = event.secrets.SENDGRID_API_KEY;
  
  request.post({
    url: "https://api.sendgrid.com/v3/mail/send",
    headers: {
      "Authorization": "Bearer " + sendgridApiKey
    },
    json: {
      personalizations: [{
        to: [{
          email: user.email
        }]
      }],
      from: {
        email: "admin@example.com"
      },
      subject: "パスワードが変更されました",
      content: [{
        type: "text/plain",
        //👇 コード変更箇所
        value: `${event.connection.name} アカウント ${event.user.email} のパスワードが最近変更されました。`
      }]
    }
  }, function (err, resp, body) {
    if (err || resp.statusCode !== 202) {
      //👇 コード変更箇所
      throw (err || new Error(body.errors[0].message));
    }

    //👇 コード変更箇所
    //cb();
  });
};
```

ご覧のとおり、Hook関数からの変更はごくわずかです。変更箇所は以下の通りです。

- SendGrid APIのシークレットを取得する方法、
- connectionとユーザーデータを取得する方法、
- 実行失敗時にAuth0 Actionから抜ける方法。

また、`cb()`コールバック呼び出しに関連する最後のコメント行もご覧ください。Auth0 Actionsではこの呼び出しは不要です。

## 移行戦略を計画する

この記事ではAuth0 HooksとAuth0 Actionsで実装するコードの主な違いを説明しました。Auth0 HooksをAuth0 Actionsへと移行する場合、コードの変換以外にも考慮すべき点が存在します。そのため本番環境において問題が発生しないような移行戦略を計画する必要があります。

この点に関しては移行後のAuth0 Actionsをテストする[ステージング環境](https://auth0.com/docs/get-started/auth0-overview/create-tenants/set-up-multiple-environments)を構築することをお勧めします。このステージング環境では本番環境への移行前にAuth0 Hooksから移行したAuth0 Actionsが期待どおりに実行することを確認できます。

さらに、冒頭でも言及していますが、テナント内にAuth0 HooksとAuth0 Actionsの両方を含められることを考慮してください。両方がアクティブな場合、Auth0 ActionsはAuth0 Hooksの後に実行されます。そのためそれぞれのAuth0 Actionsをアクティブにしてから移行元となるAuth0 Hooksを非アクティブにすることで、1つずつAuth0 Hooksを移行できます。いくつかまだ注意するべき点はありますが、この方法を用いると運用環境が破壊されるリスクを最小限に抑えることができます。

より詳しいAuth0 HooksからAuth0 Actionsへの移行戦略については、[ドキュメント](https://auth0.com/docs/customize/actions/migrate/migrate-from-hooks-to-actions#plan-your-migration)をご覧ください。

## まとめ

この記事では、Auth0 Actionsが認証フローをカスタマイズするための新しい統合方法であること、さらにAuth0 Actionsを利用し、開発エクスペリエンスを強化できることを説明しました。また、この記事では既存のAuth0 Hooksを新しいAuth0 Actionsに変換するためのガイドラインについて説明し、代表的な変換例を説明しました。

Auth0 HooksからAuth0 Actionsへの移行の際は、[Auth0 HooksからAuth0 Actionsへの移行プロセスの詳細](https://auth0.com/docs/customize/actions/migrate/migrate-from-hooks-to-actions)ドキュメントを確認し、移行計画を事前に策定することを強くお勧めします。

*このブログはこちらの[英語ブログ](https://auth0.com/blog/migrating-auth0-hooks-to-auth0-actions/)からの翻訳、[池原 大然](https://auth0.com/blog/authors/daizen-ikehara)によるレビューです。*