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

# パスワードレス接続のためにカスタムSMSゲートウェイをセットアップする

> パスワードレス接続のためにカスタムSMSゲートウェイをセットアップする方法を学びます。

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

このガイドでは、１回限り使用できるコードを送信するためにカスタムSMSゲートウェイを使用する方法について説明します。

デフォルトでは、[パスワードレスSMS接続](/docs/ja-jp/authenticate/passwordless/authentication-methods/sms-otp)は、[Twilio](https://www.twilio.com)を使用して１回限り使用できるコードを送信します。ただし、カスタムSMSゲートウェイがある場合は、代わりにそれを使用するために接続を変更できます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Auth0は、基本的なSMS認証に対応していません。
</Callout>

1. SMSパスワードレス接続をセットアップします。方法については、[パスワードレス接続](/docs/ja-jp/authenticate/passwordless)の「パスワードレスの実装」セクションをご覧ください。
2. [Management APIのアクセストークンを取得](/docs/ja-jp/secure/tokens/access-tokens/management-api-access-tokens)します。これは、パスワードレス接続を更新するために、Mangement APIを呼び出すために必要です。
3. [GET接続](/docs/ja-jp/api/management/v2#!/Connections/get_connections)エンドポイントを使用して、テナントに関する接続についての情報を取得します。より具体的には、パスワードレスSMS接続のIDを取得する必要があります。そうすることで、接続自体を更新する後のAPI呼び出しでそれを使用できます。Management APIに以下の呼び出しを行う前に、`ACCESS_TOKEN`を手順1で取得したトークンに置き換えてください。

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url https://your-auth0-tenant.com/api/v2/connections \
    --header 'authorization: Bearer {yourAccessToken}'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://your-auth0-tenant.com/api/v2/connections");
  var request = new RestRequest(Method.GET);
  request.AddHeader("authorization", "Bearer {yourAccessToken}");
  IRestResponse response = client.Execute(request);
  ```

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

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

  func main() {

  	url := "https://your-auth0-tenant.com/api/v2/connections"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("authorization", "Bearer {yourAccessToken}")

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

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

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

  }
  ```

  ```java Java lines theme={null}
  HttpResponse response = Unirest.get("https://your-auth0-tenant.com/api/v2/connections")
    .header("authorization", "Bearer {yourAccessToken}")
    .asString();
  ```

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

  var options = {
    method: 'GET',
    url: 'https://your-auth0-tenant.com/api/v2/connections',
    headers: {authorization: 'Bearer {yourAccessToken}'}
  };

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

  ```objc Obj-C lines theme={null}
  #import <Foundation/Foundation.h>

  NSDictionary *headers = @{ @"authorization": @"Bearer {yourAccessToken}" };

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://your-auth0-tenant.com/api/v2/connections"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];
  [request setAllHTTPHeaderFields:headers];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                      NSLog(@"%@", error);
                                                  } else {
                                                      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                      NSLog(@"%@", httpResponse);
                                                  }
                                              }];
  [dataTask resume];
  ```

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

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://your-auth0-tenant.com/api/v2/connections",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {yourAccessToken}"
    ],
  ]);

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

  curl_close($curl);

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

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

  conn = http.client.HTTPSConnection("your-auth0-tenant.com")

  headers = { 'authorization': "Bearer {yourAccessToken}" }

  conn.request("GET", "/api/v2/connections", headers=headers)

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

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

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

  url = URI("https://your-auth0-tenant.com/api/v2/connections")

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

  request = Net::HTTP::Get.new(url)
  request["authorization"] = 'Bearer {yourAccessToken}'

  response = http.request(request)
  puts response.read_body
  ```

  ```swift Swift lines theme={null}
  import Foundation

  let headers = ["authorization": "Bearer {yourAccessToken}"]

  let request = NSMutableURLRequest(url: NSURL(string: "https://your-auth0-tenant.com/api/v2/connections")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "GET"
  request.allHTTPHeaderFields = headers

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  })

  dataTask.resume()
  ```
</AuthCodeGroup>

エンドポイントからの応答は、オブジェクトの配列です。各オブジェクトは、テナントと関係がある1つの接続を表しています。
4\. 接続IDを特定します。手順２で[GET接続エンドポイント](/docs/ja-jp/api/management/v2#!/Connections/get_connections)から返されたオブジェクトの配列を確認して、パスワードレス接続と関係があるIDを見つけることができます。パスワードレス接続のある特定のオブジェクトを見つけるには、`"name": "sms"`プロパティを検索できます。接続で、セットアッププロセス中にあなたが提供したTwilio情報が現在表示されていることに注目してください。

```json lines expandable theme={null}
[
    {
        "id": "con_UX85K7K0N86INi9U",
        "options": {
            "disable_signup": false,
            "name": "sms",
            "twilio_sid": "TWILIO_SID",
            "twilio_token": "TWILIO_AUTH_TOKEN",
            "from": "+15555555555",
            "syntax": "md_with_macros",
            "template": "Your SMS verification code is: @@password@@",
            "totp": {
                "time_step": 300,
                "length": 6
            },
            "messaging_service_sid": null,
            "brute_force_protection": true
        },
        "strategy": "sms",
        "name": "sms",
        "is_domain_connection": false,
        "realms": [
            "sms"
        ],
    }
]
```

5. 接続を更新する。[接続の更新エンドポイント](/docs/ja-jp/api/management/v2#!/Connections/patch_connections_by_id)に対してPATCH呼び出しを行うことで、これを実行できます。より具体的には、SMS Gatewayに関する情報を提供するために、接続`options`オブジェクトを更新します。

   <Warning>
     呼び出しのたびに`options`オブジェクト全体を送信しなければなりません。そうしないと、後続の呼び出しに含まれない既存のデータが上書きされます。
   </Warning>

   以下の項目を変更します。

   * `twilio_sid`および`twilio_token`の両方のパラメーターを削除します。
   * `provider`パラメーターを追加し、`sms_gateway`に設定します。
   * `gateway_url`パラメーターを追加し、SMSゲートウェイのURLに設定します。Auth0は、ゲートウェイを使用してあなたに代わってメッセージを送信するために、このURLに到達できなければなりません。

   ペイロードはこのようになっているはずです。

   ```json lines theme={null}
   {
       "options": {
         "strategy": "sms",
         "provider": "sms_gateway",
         "gateway_url": "{urlOfYourGateway}",
         "from": "+1 234 567",
         "template": "Your verification code is: @@password@@",
         "brute_force_protection": true,
         "forward_req_info": "true",
         "disable_signup": false,
         "name": "sms",
         "syntax": "md_with_macros",
         "totp": {
           "time_step": 300,
           "length": 6
         }
       },
       "is_domain_connection": false,
   }
   ```

## 認証済み要求

SMSゲートウェイが、トークンベースの認証済み要求を受け入れたら、`options`オブジェクトに以下を追加できます。

```json lines theme={null}
"gateway_authentication": {
    "method": "bearer",
    "subject": "urn:Auth0",
    "audience": "urn:MySmsGateway",
    "secret": "MySecretToSignTheToken",
    "secret_base64_encoded": false
}
```

`options`オブジェクトに`gateway_authentication`を含めた場合、Auth0は、SMSゲートウェイに要求を送信するときはいつでも、`認証`ヘッダーに[JSON Web Token](/docs/ja-jp/secure/tokens/json-web-tokens)を追加します。トークンは、`gateway_authentication.subject`および`gateway_authentication.audience`値を含み、`gateway_authentication.secret`で署名されます。

シークレットがBase64URLエンコードされている場合は、`secret_base64_encoded`を`true`に設定します。

接続を更新したら、Auth0は、ユーザーがパスワードレス接続にサインアップまたはログインするたびに、以下をSMSに送信します。

```json lines theme={null}
{
  "recipient": "+1 399 999",
  "body": "Your verification code is: 12345",
  "sender": "+1 234 567"
}
```

`options`オブジェクトの`forward_req_info`プロパティを`true`に設定した場合、ゲートウェイは、パスワードレスプロセスを開始するHTTP要求からも情報を受け取ります。これには、`/passwordless/start`およびユーザーエージェントを呼び出すクライアントのIPアドレスが含まれます。

```json lines theme={null}
{
  "recipient": "+1 399 999",
  "body": "Your verification code is: 12345",
  "sender": "+1 234 567",
  "req" : { 
      "ip" : "167.56.227.117",
      "user-agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"
       }
}
```

## エラー処理

Auth0は、SMSゲートウェイから返されたHTTPコードのみを考慮し、他の応答を無視します（たとえば、応答本文や応答タイプ）。

SMSゲートウェイが200以外のHTTPコードを返した場合、`/passwordless/start`エンドポイントは、HTTP 400コードと以下のような応答を返します。

```json lines theme={null}
{
 "error":"sms_provider_error",
 "error_description":"Unexpected response while calling the SMS gateway: <HTTP Code Returned by the SMS Gateway>"}
}
```

SMSゲートウェイがHTTP 401を返した場合、`error_description`は、 **SMSゲートウェイ呼び出し中に認証に失敗しました：401** になります。（エラーの説明の言葉遣いは、いつでも変更される可能性がありますのでご注意ください）

Auth0では、カスタムSMSゲートウェイに対するHTTPの呼び出しについて、30秒のタイムアウトを強制できます。SMSゲートウェイがこの時間枠内に応答しなかった場合も、`/passwordless/start`エンドポイントはHTTP 400コードを返します。応答は、上記のフォーマットで行われ、`error_description`フィールドは、 **SMSゲートウェイ呼び出し中にタイムアウト：`<Timeout Code>`** となります。（繰り返しになりますが、エラーの説明の言い回しは、いつでも変更される可能性があります）
