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

# パスワードレスAPIを使用する

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

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

パスワードレスAPIは次の2つのシナリオで使用できます。

* ユニバーサルログインを実装し、Auth0とインタラクションするためにauth0.jsを使用してログインページをカスタマイズする場合。
* アプリケーションにログインフローを埋め込む場合。

ログインを埋め込む場合、[セキュリティ上の影響を必ず理解](/docs/ja-jp/authenticate/login/universal-vs-embedded-login)してください。

さまざまなシナリオでユニバーサルログインと埋め込みログインにパスワードレスを実装する方法の詳細については、「[ユニバーサルログインを使用したパスワードレス認証](/docs/ja-jp/authenticate/passwordless/implement-login/universal-login)」または「[埋め込みログインを使用したパスワードレス認証](/docs/ja-jp/authenticate/passwordless/implement-login/embedded-login)」をお読みください。

## パスワードレスエンドポイント

### POST /passwordless/start

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  [［Auth0 Dashboard］>［Applications（アプリケーション）］>［Applications（アプリケーション）］](https://manage.auth0.com/#/applications)に移動して、アプリケーション設定の **［Advanced Settings（高度な設定］** にある **［Grant Types（付与タイプ）］** で **［Passwordless OTP（パスワードレスOTP）］** の付与を有効にしなければなりません。
</Callout>

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

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

* メールまたはSMSメッセージによる1回限りのコード
* メールによる1回限りのリンク

API 呼び出しは次の構造を持つ必要があります。

export const codeExample1 = `POST https://{yourDomain}/passwordless/start
Content-Type: application/json
{
  "client_id": "{yourClientID}",
  "client_secret": "{yourClientSecret}", // For Regular Web Applications
  "connection": "email|sms",
  "email": "{email}", //set for connection=email
  "phone_number": "{phoneNumber}", //set for connection=sms
  "send": "link|code", //if left null defaults to link
  "authParams": { // any authentication parameters that you would like to add
    "scope": "openid",     // used when asking for a magic link
    "state": "{yourState}"  // used when asking for a magic link, or from the custom login page
  }
}`;

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

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

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

### POST /oauth/token

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

これを実現するには、まず、アプリケーションの設定の **［Advanced Settings（詳細設定）］** > **［Grant Types（付与タイプ）］** にある[［Auth0 Dashboard（Auth0ダッシュボード）］>［Applications（アプリケーション）］>［Applications（アプリケーション）］](https://manage.auth0.com/#/applications)で、アプリケーションの **［<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=passwordless" tip="パスワードレス: 最初の要素としてパスワードに依存しない認証の形式。" cta="用語集の表示">Passwordless</Tooltip> OTP（パスワードレスOTP）］** 付与を有効にする必要があります。

ユーザーはOTPコードを受け取り、ネイティブアプリケーションまたはWebアプリケーションがユーザーにOTPコードの入力を求めます。ユーザーがコードを入力すると、次のパラメーターを使用して`/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}", // only for web apps, native apps don’t have a client secret
  "username":"<email address>", // or "<phone number>"
  "otp": "CODE",
  "realm": "email", // or "sms" 
  "audience" : "your-api-audience", // in case you need an access token for a specific API
  "scope": "openid profile email" // whatever scopes you need
}`;

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

その後、IDトークンをデコードしてユーザーに関する情報を取得したり、アクセストークンを使用して通常どおりAPIを呼び出したりすることができます。

## Auth0.jsを使用する

シングルページアプリケーションまたはカスタマイズされたユニバーサルログインページでパスワードレス認証を実装する場合は、[Auth0.jsとそれに含まれるpasswordlessLoginメソッドを使用する](/docs/ja-jp/libraries/auth0js)必要があります。実装は複雑なので、APIを直接呼び出すのではなく、ライブラリーを使用することをお勧めします。

## パスワードレスエンドポイントでのレート制限

Auth0のレート制限と攻撃保護機能は、API呼び出しを行っているマシンのIPのみを考慮します。API呼び出しがバックエンドサーバーから行われる場合、通常、Auth0ではサーバーのIPではなく、エンドユーザーのIPを考慮する必要があります。

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

* 機密アプリケーションに対してAPI呼び出しが行われる。
* API 呼び出しにはクライアントシークレットが含まれている。
* **［Trust <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-1" href="/docs/ja-jp/glossary?term=token-endpoint" tip="トークンエンドポイント: プログラムに従ってトークンを要求するために使用される認可サーバー上のエンドポイント。" cta="用語集の表示">Token Endpoint</Tooltip> IP Header（信頼トークンエンドポイントIPヘッダー）］** トグルがオンになっている。

完全な説明については、「[リソース所有者のパスワードフローと攻撃防御のよくある不具合を回避する](/docs/ja-jp/get-started/authentication-and-authorization-flow/resource-owner-password-flow/avoid-common-issues-with-resource-owner-password-flow-and-attack-protection)」をお読みください。
