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

# ユーザープロファイルのメタデータを管理する方法

> Auth0 Dashboard、Management API、または `post-login` アクションを使用して、ユーザープロファイルのユーザーメタデータとアプリメタデータを参照・設定します。

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

ユーザープロファイルの`user_metadata`と`app_metadata`には、ユースケースに応じてさまざまなメソッドでアクセスし、値を設定できます。

<Tabs>
  <Tab title="Management API">
    [Management APIのユーザー作成エンドポイント](/docs/ja-jp/api/management/v2/users/post-users) (`POST /users`) で新しいユーザーを作成する際は、ボディパラメーターの`user_metadata`と`app_metadata`を指定することで、そのユーザーのメタデータを設定できます。

    <Accordion title="例：メタデータ付きの新規ユーザーを作成">
      次のプロフィール情報でユーザーを作成するには：

      ```json theme={null}
      {
          "email": "jane.doe@example.com",
          "user_metadata": {
              "hobby": "surfing"
          },
          "app_metadata": {
              "plan": "full"
          }
      }
      ```

      <Tooltip tip="Management API：顧客が管理タスクを実行できるようにする製品です。" cta="用語集を表示" href="/docs/ja-jp/glossary?term=Management+API">Management API</Tooltip>の[`/post_users`](https://auth0.com/docs/api/management/v2#!/Users/post_users)エンドポイントに対して次の`POST`呼び出しを行い、ユーザーを作成してプロパティ値を設定します：

      <Callout icon="file-lines" color="#0EA5E9" iconType="regular">Auth0 CLIをご利用ですか？まだの場合は、このコマンドを実行する前に[CLIセッションのセットアップと認証](/docs/ja-jp/deploy-monitor/auth0-cli)を行ってください。</Callout>

      <AuthCodeGroup>
        ```bash Auth0 CLI theme={null}
        auth0 api post "users" \
          --data '{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}'
        ```

        ```bash cURL theme={null}
        curl --request POST \
          --url 'https://{yourDomain}/api/v2/users' \
          --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
          --header 'content-type: application/json' \
          --data '{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}'
        ```

        ```csharp C# theme={null}
        var client = new RestClient("https://{yourDomain}/api/v2/users");
        var request = new RestRequest(Method.POST);
        request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
        request.AddHeader("content-type", "application/json");
        request.AddParameter("application/json", "{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);
        ```

        ```go Go theme={null}
        package main

        import (
            "fmt"
            "strings"
            "net/http"
            "io/ioutil"
        )

        func main() {

            url := "https://{yourDomain}/api/v2/users"

            payload := strings.NewReader("{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}")

            req, _ := http.NewRequest("POST", url, payload)

            req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
            req.Header.Add("content-type", "application/json")

            res, _ := http.DefaultClient.Do(req)

            defer res.Body.Close()
            body, _ := ioutil.ReadAll(res.Body)

            fmt.Println(res)
            fmt.Println(string(body))

        }
        ```

        ```java Java theme={null}
        HttpResponse<String> response = Unirest.post("https://{yourDomain}/api/v2/users")
          .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
          .header("content-type", "application/json")
          .body("{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}")
          .asString();
        ```

        ```javascript Node.JS theme={null}
        var axios = require("axios").default;

        var options = {
          method: 'POST',
          url: 'https://{yourDomain}/api/v2/users',
          headers: {
            authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
            'content-type': 'application/json'
          },
          data: {
            email: 'jane.doe@example.com',
            user_metadata: {hobby: 'surfing'},
            app_metadata: {plan: 'full'}
          }
        };

        axios.request(options).then(function (response) {
          console.log(response.data);
        }).catch(function (error) {
          console.error(error);
        });
        ```

        ```php PHP theme={null}
        $curl = curl_init();

        curl_setopt_array($curl, [
          CURLOPT_URL => "https://{yourDomain}/api/v2/users",
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "POST",
          CURLOPT_POSTFIELDS => "{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}",
          CURLOPT_HTTPHEADER => [
            "authorization: Bearer MGMT_API_ACCESS_TOKEN",
            "content-type: application/json"
          ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
          echo "cURL Error #:" . $err;
        } else {
          echo $response;
        }
        ```

        ```python Python theme={null}
        import http.client

        conn = http.client.HTTPSConnection("")

        payload = "{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}"

        headers = {
            'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
            'content-type': "application/json"
            }

        conn.request("POST", "/{yourDomain}/api/v2/users", payload, headers)

        res = conn.getresponse()
        data = res.read()

        print(data.decode("utf-8"))
        ```

        ```ruby Ruby theme={null}
        require 'uri'
        require 'net/http'
        require 'openssl'

        url = URI("https://{yourDomain}/api/v2/users")

        http = Net::HTTP.new(url.host, url.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_PEER

        request = Net::HTTP::Post.new(url)
        request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
        request["content-type"] = 'application/json'
        request.body = "{"email": "jane.doe@example.com", "user_metadata": {"hobby": "surfing"}, "app_metadata": {"plan": "full"}}"

        response = http.request(request)
        puts response.read_body
        ```
      </AuthCodeGroup>
    </Accordion>

    既存ユーザーのメタデータを設定または更新するには、[Update a Userエンドポイント](/docs/ja-jp/api/management/v2/users/patch-users-by-id) (`PATCH /users/{id}`) を使用し、同様に`user_metadata`と`app_metadta`のボディパラメーターを指定します。

    <Accordion title="例：既存ユーザーのメタデータを更新">
      たとえば、次のメタデータ値を持つユーザーを作成したとします。

      ```json theme={null}
      {
          "email": "jane.doe@example.com",
          "user_metadata": {
              "hobby": "surfing"
          },
          "app_metadata": {
              "plan": "full"
          }
      }
      ```

      `user_metadata` を更新して、ユーザーの自宅住所を第2階層のプロパティとして追加するには、次のようにします。

      ```json theme={null}
      {
          "addresses": {
              "home": "123 Main Street, Anytown, ST 12345"
          }
      }
      ```

      次のように `PATCH` 呼び出しを行います。

      <AuthCodeGroup>
        ```bash Auth0 CLI theme={null}
        auth0 api patch "users/user_id" \
          --data '{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}'
        ```

        ```bash cURL theme={null}
        curl --request PATCH \
          --url 'https://{yourDomain}/api/v2/users/user_id' \
          --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
          --header 'content-type: application/json' \
          --data '{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}'
        ```

        ```csharp C# theme={null}
        var client = new RestClient("https://{yourDomain}/api/v2/users/user_id");
        var request = new RestRequest(Method.PATCH);
        request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
        request.AddHeader("content-type", "application/json");
        request.AddParameter("application/json", "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);
        ```

        ```go Go theme={null}
        package main

        import (
            "fmt"
            "strings"
            "net/http"
            "io/ioutil"
        )

        func main() {

            url := "https://{yourDomain}/api/v2/users/user_id"

            payload := strings.NewReader("{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}")

            req, _ := http.NewRequest("PATCH", url, payload)

            req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
            req.Header.Add("content-type", "application/json")

            res, _ := http.DefaultClient.Do(req)

            defer res.Body.Close()
            body, _ := ioutil.ReadAll(res.Body)

            fmt.Println(res)
            fmt.Println(string(body))

        }
        ```

        ```java Java theme={null}
        HttpResponse<String> response = Unirest.patch("https://{yourDomain}/api/v2/users/user_id")
          .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
          .header("content-type", "application/json")
          .body("{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}")
          .asString();
        ```

        ```javascript Node.JS theme={null}
        var axios = require("axios").default;

        var options = {
          method: 'PATCH',
          url: 'https://{yourDomain}/api/v2/users/user_id',
          headers: {
            authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
            'content-type': 'application/json'
          },
          data: {user_metadata: {addresses: {home: '123 Main Street, Anytown, ST 12345'}}}
        };

        axios.request(options).then(function (response) {
          console.log(response.data);
        }).catch(function (error) {
          console.error(error);
        });
        ```

        ```php PHP theme={null}
        $curl = curl_init();

        curl_setopt_array($curl, [
          CURLOPT_URL => "https://{yourDomain}/api/v2/users/user_id",
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "PATCH",
          CURLOPT_POSTFIELDS => "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}",
          CURLOPT_HTTPHEADER => [
            "authorization: Bearer MGMT_API_ACCESS_TOKEN",
            "content-type: application/json"
          ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
          echo "cURL Error #:" . $err;
        } else {
          echo $response;
        }
        ```

        ```python Python theme={null}
        import http.client

        conn = http.client.HTTPSConnection("")

        payload = "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}"

        headers = {
            'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
            'content-type': "application/json"
            }

        conn.request("PATCH", "/{yourDomain}/api/v2/users/user_id", payload, headers)

        res = conn.getresponse()
        data = res.read()

        print(data.decode("utf-8"))
        ```

        ```ruby Ruby theme={null}
        require 'uri'
        require 'net/http'
        require 'openssl'

        url = URI("https://{yourDomain}/api/v2/users/user_id")

        http = Net::HTTP.new(url.host, url.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_PEER

        request = Net::HTTP::Patch.new(url)
        request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
        request["content-type"] = 'application/json'
        request.body = "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345"}}}"

        response = http.request(request)
        puts response.read_body
        ```
      </AuthCodeGroup>

      ユーザーのプロフィールは次のように表示されるようになります。

      ```json theme={null}
      {
          "email": "jane.doe@example.com",
          "user_metadata": {
              "hobby": "surfing",
              "addresses": {
                  "home": "123 Main Street, Anytown, ST 12345"
              }
          },
          "app_metadata": {
              "plan": "full"
          }
      }
      ```
    </Accordion>

    既存ユーザーのメタデータを更新する場合、オブジェクトにマージされるのはルートレベルのプロパティのみです。それより下位のプロパティはすべて置き換えられます。

    <Accordion title="例：メタデータのサブプロパティを更新する">
      たとえば、ユーザーの勤務先住所を内部プロパティとして新たに追加するには、`addresses` プロパティの内容をすべて含める必要があります。`addresses` オブジェクトはルートレベルのプロパティなので、ユーザーを表す最終的な JSON オブジェクトにマージされますが、そのサブプロパティはマージされません。

      ```json theme={null}
      {
        "user_metadata": {
          "addresses": {
            "home": "123 Main Street, Anytown, ST 12345",
            "work": "100 Industrial Way, Anytown, ST 12345"
          }
        }
      }
      ```

      したがって、これに対応する API への `PATCH` 呼び出しは次のようになります。

      <AuthCodeGroup>
        ```bash Auth0 CLI theme={null}
        auth0 api patch "users/user_id" \
          --data '{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}'
        ```

        ```bash cURL theme={null}
        curl --request PATCH \
          --url 'https://{yourDomain}/api/v2/users/user_id' \
          --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
          --header 'content-type: application/json' \
          --data '{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}'
        ```

        ```csharp C# theme={null}
        var client = new RestClient("https://{yourDomain}/api/v2/users/user_id");
        var request = new RestRequest(Method.PATCH);
        request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
        request.AddHeader("content-type", "application/json");
        request.AddParameter("application/json", "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);
        ```

        ```go Go theme={null}
        package main

        import (
            "fmt"
            "strings"
            "net/http"
            "io/ioutil"
        )

        func main() {

            url := "https://{yourDomain}/api/v2/users/user_id"

            payload := strings.NewReader("{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}")

            req, _ := http.NewRequest("PATCH", url, payload)

            req.Header.Add("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
            req.Header.Add("content-type", "application/json")

            res, _ := http.DefaultClient.Do(req)

            defer res.Body.Close()
            body, _ := ioutil.ReadAll(res.Body)

            fmt.Println(res)
            fmt.Println(string(body))

        }
        ```

        ```java Java theme={null}
        HttpResponse<String> response = Unirest.patch("https://{yourDomain}/api/v2/users/user_id")
          .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
          .header("content-type", "application/json")
          .body("{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}")
          .asString();
        ```

        ```javascript Node.JS theme={null}
        var axios = require("axios").default;

        var options = {
          method: 'PATCH',
          url: 'https://{yourDomain}/api/v2/users/user_id',
          headers: {
            authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
            'content-type': 'application/json'
          },
          data: {
            user_metadata: {
              addresses: {
                home: '123 Main Street, Anytown, ST 12345',
                work: '100 Industrial Way, Anytown, ST 12345'
              }
            }
          }
        };

        axios.request(options).then(function (response) {
          console.log(response.data);
        }).catch(function (error) {
          console.error(error);
        });
        ```

        ```php PHP theme={null}
        $curl = curl_init();

        curl_setopt_array($curl, [
          CURLOPT_URL => "https://{yourDomain}/api/v2/users/user_id",
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_ENCODING => "",
          CURLOPT_MAXREDIRS => 10,
          CURLOPT_TIMEOUT => 30,
          CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
          CURLOPT_CUSTOMREQUEST => "PATCH",
          CURLOPT_POSTFIELDS => "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}",
          CURLOPT_HTTPHEADER => [
            "authorization: Bearer MGMT_API_ACCESS_TOKEN",
            "content-type: application/json"
          ],
        ]);

        $response = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
          echo "cURL Error #:" . $err;
        } else {
          echo $response;
        }
        ```

        ```python Python theme={null}
        import http.client

        conn = http.client.HTTPSConnection("")

        payload = "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}"

        headers = {
            'authorization': "Bearer MGMT_API_ACCESS_TOKEN",
            'content-type': "application/json"
            }

        conn.request("PATCH", "/{yourDomain}/api/v2/users/user_id", payload, headers)

        res = conn.getresponse()
        data = res.read()

        print(data.decode("utf-8"))
        ```

        ```ruby Ruby theme={null}
        require 'uri'
        require 'net/http'
        require 'openssl'

        url = URI("https://{yourDomain}/api/v2/users/user_id")

        http = Net::HTTP.new(url.host, url.port)
        http.use_ssl = true
        http.verify_mode = OpenSSL::SSL::VERIFY_PEER

        request = Net::HTTP::Patch.new(url)
        request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
        request["content-type"] = 'application/json'
        request.body = "{"user_metadata": {"addresses": {"home": "123 Main Street, Anytown, ST 12345", "work": "100 Industrial Way, Anytown, ST 12345"}}}"

        response = http.request(request)
        puts response.read_body
        ```
      </AuthCodeGroup>
    </Accordion>

    メタデータキーを削除するには、`PATCH` 呼び出しを実行し、対象のメタデータキーの値を `null` に設定します (例：`{ "user_metadata": {"color": null}}`) 。

    ユーザーまたはアプリのメタデータを完全に削除するには、`PATCH` 呼び出しを実行し、メタデータそのものを空のオブジェクトに設定します (例：`{ "user_metadata": {} }`) 。
  </Tab>

  <Tab title="`post-login` アクション">
    `post-login`トリガーを構成すると、ユーザーのログインフローの一部として`user_metadata`と`app_metadata`を変更できます。

    ログイン後トリガーは、アプリケーション固有のデータをユーザープロファイルに保存する、ユーザーのオペレーションログを記録する、<Tooltip tip="Security Assertion Markup Language（SAML）：2者間でパスワードを使わずに認証情報を交換できるようにする標準化されたプロトコル。" cta="用語集を表示" href="/docs/ja-jp/glossary?term=SAML">SAML</Tooltip>属性をメタデータフィールドにマッピングする、負荷の高いオペレーションの結果をユーザープロファイルにキャッシュして以降のログインで再利用する、といったタスクに便利です。

    `post-login`の`api`オブジェクトには、このトリガーで実行できる一般的なオペレーションが用意されています。ユーザーメタデータを管理するには、`api.user.setAppMetadata`メソッドと`api.user.setUserMetadata`メソッドを使用します。たとえば、特定のユーザーに対してある動作が複数回実行されないようにするには、次のようなアクションを使用できます。

    ```js theme={null}
    exports.onExecutePostLogin = async (event, api) => {
      if (event.user.app_metadata.didAnExpensiveTask) {
        console.log(`Skipping the expensive task because it already occurred for ${event.user.email}.`);

        return;
      }
      // 負荷の高いタスクを実行する
      api.user.setAppMetadata("didAnExpensiveTask", true);
    };
    ```

    ここでは、アクションの冒頭に、このユーザーに対して負荷の高い処理をすでに実行済みかどうかを確認するチェックを追加しています。メタデータフィールドが存在する場合は、関数から戻ります。

    アクションの最後では、`api.user.setAppMetadata`を呼び出して、ユーザーオブジェクトにメタデータを保存することを指示します。アクションは、各トリガーの実行終了時にユーザープロファイルを単一のオペレーションとして更新します。`setUserMetadata`が複数回呼び出された場合、それらが同じフロー内の別々のアクションで呼び出されたものであっても、アクションがユーザープロファイルを更新するのはトリガーの実行終了時の1回だけです。

    <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
      `setUserMetadata`や`setAppMetadata`の複数の呼び出しは、別々のアクションから行われたものであっても、トリガーの実行終了時に1回のユーザープロファイル更新としてまとめて処理されます。
    </Callout>

    [`api.redirect.sendUserTo()`によるリダイレクト](/docs/ja-jp/customize/actions/redirect-with-actions)が発生した場合、保留中のユーザーメタデータやアプリメタデータの更新は、ユーザーが外部サイトにリダイレクトされる前にユーザープロファイルへ適用されます。
  </Tab>

  <Tab title="ロック">
    [Lockライブラリ](/docs/ja-jp/libraries/lock)を使用すると、`user_metadata.`の定義、追加、読み取り、更新を行えます。ユーザーの`user_metadata`プロパティは、ほかのユーザープロファイルプロパティと同じ方法で読み取ることができます。たとえば、次のコードスニペットは`user_metadata.hobby`に関連付けられた値を取得し、ページ上の要素に割り当てます。

    ```javascript theme={null}
    // 認証時に取得したaccessTokenを使ってgetUserInfoを呼び出します
    lock.getUserInfo(accessToken, function(error, profile) {
      if (!error) {
        document.getElementById('hobby').textContent = profile.user_metadata.hobby;
      }
    });
    ```

    `additionalSignUpFields`を使用すると、ユーザーのサインアップフォームにカスタムフィールドを追加できます。ユーザーがカスタムフィールドにデータを入力すると、Auth0は入力された値をそのユーザーの`user_metadata`に保存します。サインアップ時に`user_metadata`を追加する方法の詳細については、「[追加のサインアップフィールド](/docs/ja-jp/libraries/lock/lock-configuration#additionalsignupfields-array-)」をお読みください。
  </Tab>

  <Tab title="ルール">
    <Warning>
      ルールとHooksの提供終了 (EOL) 日は**2026年11月18日**です。また、**2023年10月16日**以降に作成された新しいテナントでは、これらの機能は利用できません。有効なHooksがある既存のテナントでは、提供終了日まで引き続きHooksを利用できます。

      Auth0を拡張する際は、アクションの使用を強くお勧めします。アクションでは、豊富な型情報やインラインドキュメント、公開されている`npm`パッケージを利用できるほか、外部の統合機能と連携して、拡張性をさらに高めることができます。アクションで利用できる機能の詳細については、「[Auth0 Actionsの仕組みを理解する](/docs/ja-jp/customize/actions/actions-overview)」をお読みください。

      移行に役立つガイドとして、[ルールからアクションへの移行](/docs/ja-jp/customize/actions/migrate/migrate-from-rules-to-actions)と[Hooksからアクションへの移行](/docs/ja-jp/customize/actions/migrate/migrate-from-hooks-to-actions)をご用意しています。また、専用の[アクションへの移行](https://auth0.com/extensibility/movetoactions)ページでは、機能の比較や[アクションのデモ](https://www.youtube.com/watch?v=UesFSY1klrI)など、移行に役立つさまざまなリソースを紹介しています。

      ルールとHooksの非推奨化の詳細については、ブログ記事「[Preparing for Rules and Hooks End of Life](https://auth0.com/blog/preparing-for-rules-and-hooks-end-of-life/)」をお読みください。
    </Warning>

    [Auth0ルール](/docs/ja-jp/customize/rules)を使用すると、メタデータの読み取り、更新、削除を行えます。以下のセクションでは、ユーザーとその情報を次のJSONスニペットで表した例をもとに説明します。

    ```json theme={null}
    {
      "user_id": "jdoe",
      "email": "john.doe@example.com",
      "app_metadata": {
        "roles": [ "writer" ]
      },
      "user_metadata": {
        "preferences": {
          "color": "blue"
        }
      }
    }
    ```

    <h2 id="read-metadata">
      メタデータの読み取り
    </h2>

    <Tooltip tip="Management API：顧客が管理タスクを実行するための製品です。" cta="用語集を表示" href="/docs/ja-jp/glossary?term=Management+API">Management API</Tooltip>を使用すると、ルールでメタデータを読み取ることができます。また、`user_metadata`では、次のようなプロファイル関連の情報を検索することもできます。

    * `name`
    * `nickname`
    * `given_name`
    * `family_name`

    例として、メールアドレスが `jane.doe@example.com` のユーザーに次のメタデータが保存されているとします:

    ```json theme={null}
    {
        "email": "jane.doe@example.com",
        "user_metadata": {
            "hobby": "surfing"
        },
        "app_metadata": {
            "plan": "full"
        }
    }
    ```

    上記のメタデータの例を使うと、[Auth0ルール](/docs/ja-jp/customize/rules)内や[Management API](/docs/ja-jp/manage-users/user-accounts/metadata)の呼び出しで、データセット内の特定の項目を次のように参照できます。

    ```js theme={null}
    console.log(user.email); // "jane.doe@example.com"
    console.log(user.user_metadata.hobby); // "surfing"
    console.log(user.app_metadata.plan); // "full"
    ```

    有効なJSONスニペットであれば、どれでもメタデータとして使用できます。`user.app_metadata` はデフォルトで `Undefined` です。

    <Accordion title="例：メタデータに基づく条件付き処理">
      ユーザーのロールに応じて判断できます。

      ```javascript theme={null}
      function(user, context, callback){
        user.app_metadata = user.app_metadata || {};
        if (user.app_metadata.roles.indexOf('writer')){
          // 実行するコード
        }
      }
      ```

      色の好みなど、特定の好みに基づいて判断することができます：

      ```javascript theme={null}
      function(user, context, callback){
        user.user_metadata = user.user_metadata || {};
        if (user.user_metadata.preferences.color === 'black'){
          // 実行するコード
        }
        ...
      }
      ```
    </Accordion>

    <h3 id="read-application-metadata-clientmetadata">
      アプリケーションメタデータの読み取り (clientMetadata)
    </h3>

    アプリケーションメタデータ (`clientMetadata`) は、`context` オブジェクトのトップレベルにある任意のプロパティです。既存のアプリケーションでは、このプロパティに値は設定されていません。

    ```javascript theme={null}
    function(user, context, callback){
      context.clientMetadata = context.clientMetadata || {};
      if (context.clientMetadata.usersuppliedkey1 === 'black'){
        // このコードはユーザーに対して実行されません
      }
      ...
    }
    ```

    <h2 id="update-metadata">
      メタデータの更新
    </h2>

    ルールを使用すると、Auth0がIdPから受け取ったSAML属性を`user_metadata`または`app_metadata`にマッピングできます。

    <h3 id="update-app-metadata">
      アプリのメタデータの更新
    </h3>

    ユーザーに管理者ロールを追加するには：

    ```javascript theme={null}
    function(user, context, callback){
      user.app_metadata = user.app_metadata || {};
      // レスポンスに含まれる app_metadata を更新する
      user.app_metadata.roles = user.app_metadata.roles || [];
      user.app_metadata.roles.push('administrator');

      // app_metadata の更新を永続化する
      auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
        .then(function(){
          callback(null, user, context);
        })
        .catch(function(err){
          callback(err);
        });
    }
    ```

    その結果、ユーザープロファイルの詳細は次のような JSON で表されます：

    ```json theme={null}
    {
      "user_id": "jdoe",
      "email": "john.doe@example.com",
      "app_metadata": {
        "roles": [ "writer", "administrator" ]
      },
      "user_metadata": {
        "preferences": {
          "color": "blue"
        }
      }
    }
    ```

    <h3 id="update-user-metadata">
      ユーザーメタデータを更新する
    </h3>

    ユーザーの `fontSize` 設定をユーザープロファイルに追加するには、次の手順を実行します。

    ```javascript theme={null}
    function(user, context, callback){
      user.user_metadata = user.user_metadata || {};
      // レスポンスに含まれる user_metadata を更新する
      user.user_metadata.preferences = user.user_metadata.preferences || {};
      user.user_metadata.preferences.fontSize = 12;

      // user_metadata の更新内容を保存する
      auth0.users.updateUserMetadata(user.user_id, user.user_metadata)
        .then(function(){
          callback(null, user, context);
        })
        .catch(function(err){
          callback(err);
        });
    }
    ```

    これにより、ユーザープロファイルの詳細は次のような JSON で表されます。

    ```json theme={null}
    {
      "user_id": "jdoe",
      "email": "john.doe@example.com",
      "app_metadata": {
        "roles": [ "writer" ]
      },
      "user_metadata": {
        "preferences": {
          "color": "blue",
          "fontSize": 12
        }
      }
    }
    ```

    <h3 id="update-app-and-user-metadata-simultaneously">
      アプリとユーザーのメタデータを同時に更新する
    </h3>

    ルールの処理時間を短縮するには、同じルール内で `app_metadata` と `user_metadata` の両方を更新します。

    ```javascript expandable theme={null}
    function(user, context, callback){

      var q = require('q');

      user.app_metadata = user.app_metadata || {};
      user.user_metadata = user.user_metadata || {};
      // レスポンスに含まれる user_metadata を更新する
      user.user_metadata.preferences = user.user_metadata.preferences || {};
      user.user_metadata.preferences.fontSize = 12;

      // レスポンスに含まれる app_metadata を更新する
      user.app_metadata.roles = user.app_metadata.roles || [];
      user.app_metadata.roles.push('admin');

      // app_metadata の更新を永続化する
      var appMetadataPromise  = auth0.users.updateAppMetadata(user.user_id, user.app_metadata);

      // user_metadata の更新を永続化する
      var userMetadataPromise = auth0.users.updateUserMetadata(user.user_id, user.user_metadata);

      // q ライブラリを使用してすべての Promise の完了を待機する
      q.all([userMetadataPromise, appMetadataPromise])
        .then(function(){
          callback(null, user, context);
        })
        .catch(function(err){
          callback(err);
        });
    }
    ```

    これにより、ユーザープロファイルの詳細は次のような JSON で表現されます。

    ```json theme={null}
    {
      "user_id": "jdoe",
      "email": "john.doe@example.com",
      "app_metadata": {
        "roles": [ "writer", "admin" ]
      },
      "user_metadata": {
        "preferences": {
          "color": "blue",
          "fontSize": 12
        }
      }
    }
    ```

    <h2 id="delete-metadata">
      メタデータを削除
    </h2>

    <h3 id="delete-app-metadata-properties-and-values">
      アプリメタデータのプロパティと値を削除する
    </h3>

    プロパティを削除するには、そのプロパティの値を `null` に設定します。

    <h4 id="delete-users-roles-example">
      ユーザーのロール削除の例
    </h4>

    ユーザーのロールを削除するには、次のサンプルRuleを使用します：

    ```javascript theme={null}
    function(user, context, callback){
      user.app_metadata = user.app_metadata || {};
      // レスポンスに含まれる app_metadata を更新する
      user.app_metadata.roles = null;

      // app_metadata の更新を永続化する
      auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
        .then(function(){
          callback(null, user, context);
        })
        .catch(function(err){
          callback(err);
        });
    }
    ```

    その結果、ユーザープロファイルの JSON 表現は次のようになります。

    ```json theme={null}
    {
      "user_id": "jdoe",
      "email": "john.doe@example.com",
      "app_metadata": { },
      "user_metadata": {
        "preferences": {
          "color": "blue"
        }
      }
    }
    ```

    <h4 id="delete-single-property-value-example">
      単一のプロパティ値を削除する例
    </h4>

    プロパティの値を1つだけ削除するには、その値を指定して削除します。たとえば、ユーザープロファイルから `writer` ロールを削除するには、次のようにします。

    ```javascript theme={null}
    function(user, context, callback){
      user.app_metadata = user.app_metadata || {};
      user.app_metadata.roles = user.app_metadata.roles || [];

      var index = user.app_metadata.roles.indexOf('writer');

      if (index !== -1){
        // レスポンスに含まれるapp_metadataを更新します
        user.app_metadata.roles.splice(index, 1);
      }

      // app_metadataの更新内容を保存します
      auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
        .then(function(){
          callback(null, user, context);
        })
        .catch(function(err){
          callback(err);
        });
    }
    ```

    その結果、ユーザープロファイルは次のような JSON で表現されます：

    ```json theme={null}
    {
      "user_id": "google-oauth2|1234",
      "email": "john.doe@gmail.com",
      "app_metadata": {
        "roles": [ ]
      },
      "user_metadata": {
        "preferences": {
          "color": "blue"
        }
      }
    }
    ```

    `roles` プロパティは残っていますが、値は入っていません。

    <h3 id="delete-user-metadata-properties-and-values">
      ユーザーメタデータのプロパティと値を削除する
    </h3>

    ユーザーの色設定を削除するには：

    ```javascript theme={null}
    function(user, context, callback){
      user.user_metadata = user.user_metadata || {};
      // レスポンスに含まれる user_metadata を更新する
      user.user_metadata.preferences = user.user_metadata.preferences || {};
      delete user.user_metadata.preferences.color;

      // user_metadata の更新を永続化する
      auth0.users.updateUserMetadata(user.user_id, user.user_metadata)
        .then(function(){
          callback(null, user, context);
        })
        .catch(function(err){
          callback(err);
      });
    }
    ```

    これにより、ユーザープロファイルの詳細は次のような JSON で表されます：

    ```json theme={null}
    {
      "user_id": "jdoe",
      "email": "john.doe@example.com",
      "app_metadata": {
        "roles": [ "writer" ]
      },
      "user_metadata": {
        "preferences": { }
      }
    }
    ```
  </Tab>
</Tabs>
