> ## 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.

> Auth0 API を使用してパスワードレス認証を実装する方法について説明します。

# パスワードレス API の使用

export const ReleaseStageNotice = ({feature, stage, plans, contact, terms}) => {
  const stageTextMap = {
    "beta": "ベータ",
    "ea": "早期アクセス"
  };
  const stageText = stageTextMap[stage] || "製品リリース段階";
  const prsLink = "/docs/troubleshoot/product-lifecycle/product-release-stages";
  const linkify = (text, url) => {
    return <a href={url} target="_blank" rel="noreferrer" class="link">{text}</a>;
  };
  const includeDetails = (plans, contact, terms) => {
    const hasDetails = terms || plans || contact;
    if (!hasDetails) return null;
    return <span data-as="p">
            {plans && <>この機能は、{linkify(`${plans}プラン`, "https://auth0.com/pricing")}で利用できます。 </>}
            {contact && "参加するには、" + contact + " までお問い合わせください。 "}
            {terms && <>この機能を使用すると、Okta の{linkify("Master Subscription Agreement", "https://www.okta.com/legal")}に定める該当する無料トライアル条件に同意したものとみなされます。</>}
        </span>;
  };
  return <Warning>
            <span data-as="p">
                <strong>{feature} 機能は現在、{linkify(stageText, prsLink)}です。</strong>
            </span>

            {includeDetails(plans, contact, terms)}
        </Warning>;
};

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) + "*****マスク済み*****";
          }
          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>;
};

<Tooltip tip="Passwordless: 第1要素としてパスワードに依存しない認証方式。" cta="用語集を見る" href="/ja/docs/glossary?term=Passwordless">Passwordless</Tooltip> API は、次の 2 つのシナリオで使用できます。

* <Tooltip tip="Universal Login: アプリケーションは、ユーザーの本人確認のために、Auth0 の認可サーバーでホストされる Universal Login にリダイレクトされます。" cta="用語集を見る" href="/ja/docs/glossary?term=Universal+Login">Universal Login</Tooltip> を実装し、Auth0 と連携するために auth0.js を使ってログインページをカスタマイズしたい場合。
* アプリケーションにログインフローを埋め込みたい場合。

各シナリオで Passwordless の Universal Login または埋め込みログインを実装する方法について詳しくは、[Passwordless Authentication with Universal Login](/ja/docs/authenticate/passwordless/implement-login/universal-login) または [Passwordless Authentication with Embedded Login](/ja/docs/authenticate/passwordless/implement-login/embedded-login) を参照してください。

<div id="passwordless-endpoints">
  ## パスワードレスエンドポイント
</div>

<div id="post-passwordlessstart">
  ### POST /passwordless/start
</div>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  アプリケーションの設定で、[Auth0 Dashboard > Applications > Applications](https://manage.auth0.com/#/applications) の **Advanced Settings** > **Grant Types** にある **Passwordless OTP** グラントを有効にする必要があります。
</Callout>

[POST /passwordless/start](https://auth0.com/docs/api/authentication#get-code-or-link) エンドポイントを呼び出すと、Classic Login と 埋め込みログイン の両方でパスワードレス認証プロセスを開始できます。

エンドポイントに指定したパラメーターに応じて、Auth0 は次のいずれかを送信してユーザーの検証プロセスを開始します。

* 単一使用の code をメールまたは SMS で送信
* 単一使用のリンクをメールで送信

API 呼び出しは、次の構造である必要があります。

export const codeExample1 = `POST https://{yourDomain}/passwordless/start
Content-Type: application/json
{
  "client_id": "{yourClientID}",
  "client_secret": "{yourClientSecret}", // 通常の Web アプリケーションの場合
  "connection": "email|sms",
  "email": "{email}", // connection=email の場合に指定
  "phone_number": "{phoneNumber}", // connection=sms の場合に指定
  "send": "link|code", // null のままにすると既定値は link
  "authParams": { // 追加する任意の認証パラメーター
    "scope": "openid",     // マジックリンクをリクエストする場合に使用
    "state": "{yourState}"  // マジックリンクをリクエストする場合、またはカスタムログインページから使用
  }
}`;

<AuthCodeBlock children={codeExample1} language="json" />

マジックリンクを使用する場合、ユーザーは Authentication API によって生成されたリンクを受け取ります。ユーザーがそのリンクをクリックすると、\{`yourAuth0Tenant}.auth0.com/passwordless/verify-redirect` が呼び出されます。Auth0 はユーザーをアプリケーションにリダイレクトし、ユーザーはログインします。

code を使用する場合、アプリケーションはその code の入力を求める必要があります。その後、`/oauth/token` エンドポイント、または Auth0.js SDK の `passwordlessLogin` メソッドを使用して、その code を認証トークンに引き換える必要があります。

<div id="post-oauthtoken">
  ### POST /oauth/token
</div>

ネイティブアプリケーションまたは通常の Web アプリケーション向けにパスワードレスを実装している場合は、`/oauth/token` を使用して OTP code を認証トークンに交換する必要があります。シングルページアプリケーションからはこのエンドポイントを使用できません。

これを行うには、まず [Auth0 Dashboard > Applications > Applications](https://manage.auth0.com/#/applications) のアプリケーション設定にある **Advanced Settings** > **Grant Types** で、アプリケーションの **Passwordless OTP** グラントを有効にする必要があります。

ユーザーは OTP code を受け取り、ネイティブアプリケーションまたは Web アプリケーションはその入力をユーザーに求めます。ユーザーが code を入力したら、次のパラメーターを指定して `/oauth/token` エンドポイントを呼び出すことで、認証フローを完了できます。

export const codeExample2 = `POST https://{yourAuth0Domain}/oauth/token
Content-Type: application/json
{
  "grant_type" : "http://auth0.com/oauth/grant-type/passwordless/otp",
  "client_id": "{yourAuth0ClientID}",
  "client_secret": "{yourClientSecret}", // Web アプリのみ。ネイティブアプリにはクライアントシークレットがありません
  "username":"<メールアドレス>", // または "<電話番号>"
  "otp": "CODE",
  "realm": "email", // または "sms" 
  "audience" : "your-api-audience", // 特定の API のアクセストークンが必要な場合
  "scope": "openid profile email" // 必要なスコープを指定
}`;

<AuthCodeBlock children={codeExample2} language="json" />

問題がなければ、Auth0 は次のようなレスポンスを返します。

```json lines theme={null}
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token":"eyJz93a...k4laUWw",
"refresh_token":"GEbRxBN...edjnXbL",
"id_token":"eyJ0XAi...4faeEoQ",
"token_type":"Bearer",
"expires_in":86400
}
```

その後、<Tooltip tip="IDトークン: リソースへのアクセス用ではなく、クライアント自体のための認証情報です。" cta="用語集を見る" href="/ja/docs/glossary?term=ID+Token">ID Token</Tooltip> をデコードしてユーザー情報を取得するか、<Tooltip tip="アクセストークン: API へのアクセスに使用される、不透明な文字列または JWT 形式の認可資格情報です。" cta="用語集を見る" href="/ja/docs/glossary?term=Access+Token">Access Token</Tooltip> を使って通常どおり API を呼び出すことができます。

<div id="using-auth0js">
  ## Auth0.js の使用
</div>

シングルページアプリケーション でパスワードレス認証を実装する場合や、Universal Login ページをカスタマイズする場合は、[Auth0.js と付属の `passwordlessLogin` メソッドを使用してください](/ja/docs/libraries/auth0js)。実装は複雑なため、API を直接呼び出すのではなく、ライブラリを使用することをお勧めします。

<div id="rate-limiting-in-passwordless-endpoints">
  ## パスワードレスエンドポイントでのレート制限
</div>

Auth0 のレート制限および <Tooltip tip="Attack Protection: Auth0 が攻撃を検出して軽減するために提供する機能で、ブルートフォース対策、不審な IP のスロットリング、漏えいパスワードの検出、ボット検出、適応型多要素認証などが含まれます。" cta="用語集を見る" href="/ja/docs/glossary?term=attack+protection">攻撃対策</Tooltip>機能では、API 呼び出しを行うマシンの IP のみが考慮されます。API 呼び出しがバックエンドサーバーから行われる場合、通常、Auth0 に考慮させたいのはサーバーの IP ではなくエンドユーザーの IP です。

Auth0 では、API 呼び出しで `auth0-forwarded-for` ヘッダーを指定できますが、これが考慮されるのは次の場合のみです。

* API 呼び出しが機密アプリケーションに対して行われる。
* API 呼び出しに <Tooltip tip="Client Secret: クライアント（アプリケーション）が認可サーバーに対して認証するために使用するシークレットです。クライアントと認可サーバーのみが知っているべきであり、推測されないよう十分にランダムである必要があります。" cta="用語集を見る" href="/ja/docs/glossary?term=client+secret">クライアントシークレット</Tooltip>が含まれている。
* **Trust <Tooltip tip="Token Endpoint: トークンをプログラムから要求するために認可サーバーで使用されるエンドポイントです。" cta="用語集を見る" href="/ja/docs/glossary?term=Token+Endpoint">Token Endpoint</Tooltip> IP Header** トグルがオンになっている。

詳しくは、[Avoid Common Issues with Resource Owner Password Flow and Attack Protection](/ja/docs/get-started/authentication-and-authorization-flow/resource-owner-password-flow/avoid-common-issues-with-resource-owner-password-flow-and-attack-protection) を参照してください。

<div id="customize-mfa">
  ## MFA をカスタマイズする
</div>

<ReleaseStageNotice feature="Resource Owner Password Grant、Embedded、またはリフレッシュトークンフローでカスタマイズ可能な MFA" stage="ea" terms="true" contact="Auth0 Support" />

パスワードレス API を使用して<Tooltip tip="多要素認証（MFA）: SMS 経由の code など、username と password に加えて別の要素を使用するユーザー認証プロセス。" cta="用語集を表示" href="/ja/docs/glossary?term=MFA">MFA</Tooltip>をカスタマイズします。アプリケーションがアクセストークンをリクエストするために `/oauth/token` エンドポイントを呼び出すと、<Tooltip tip="認可サーバー: ユーザーのアクセス範囲を定義する一元化されたサーバーです。たとえば、認可サーバーはユーザーが利用できるデータ、タスク、機能を制御できます。" cta="用語集を表示" href="/ja/docs/glossary?term=authorization+server">認可サーバー</Tooltip>は `mfa_required` エラーを返し、次の情報を提供します。

* 登録とチャレンジのために MFA API を呼び出す際に必要な `mfa_token`。

* チャレンジでアプリケーションがサポートする認証要素の `type` を示す `mfa_requirements` パラメーター。

```json lines theme={null}
{
  "error": "mfa_required",
  "error_description": "Multifactor authentication required",
  "mfa_token": "Fe26...Ha",
  "mfa_requirements": {
    "challenge": [
      { "type": "otp" },
      { "type": "push-notification" },
      { "type": "phone" },
      { "type": "recovery-code" }
    ]
  }
}
```

`mfa_token` を使用して [`mfa/authenticator`](https://auth0.com/docs/api/authentication/muti-factor-authentication/list-authenticators) エンドポイントを呼び出し、ユーザーが登録しているすべての認証要素を一覧取得し、アプリケーションでサポートしている `type` と一致するものを特定します。また、チャレンジを発行するには、対応する `authenticator_type` も取得する必要があります。

```json lines theme={null}
[
  {
    "type": "recovery-code",
    "id": "recovery-code|dev_qpOkGUOxBpw6R16t",
    "authenticator_type": "recovery-code",
    "active": true
  },
  {
    "type": "otp",
    "id": "totp|dev_6NWz8awwC8brh2dN",
    "authenticator_type": "otp",
    "active": true
  }
]
```

[`request/mfa/challenge`](https://auth0.com/docs/api/authentication/muti-factor-authentication/request-mfa-challenge) エンドポイントを呼び出して、MFA チャレンジを実行します。

Auth0 Actions を使用すると、MFA フローをさらにカスタマイズできます。詳細については、[Actions Triggers: post-challenge - API Object](/ja/docs/customize/actions/explore-triggers/password-reset-triggers/post-challenge-trigger/post-challenge-api-object) を参照してください。
