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

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

デフォルトでは、パスワードレスSMS接続は、Twilioを使用して1回限り使用できるコードを送信します。ただし、カスタムSMSゲートウェイがある場合は、代わりにそれを使用するために接続を変更できます。

  1. SMSパスワードレス接続をセットアップします。方法については、パスワードレス接続の「パスワードレスの実装」セクションをご覧ください。

  2. Management APIのアクセストークンを取得します。これは、パスワードレス接続を更新するために、Mangement APIを呼び出すために必要です。

  3. GET接続エンドポイントを使用して、テナントに関する接続についての情報を取得します。より具体的には、パスワードレスSMS接続のIDを取得する必要があります。そうすることで、接続自体を更新する後のAPI呼び出しでそれを使用できます。Management APIに以下の呼び出しを行う前に、ACCESS_TOKENを手順1で取得したトークンに置き換えてください。

    
    
    curl --request GET \
      --url https://your-auth0-tenant.com/api/v2/connections \
      --header 'authorization: Bearer {yourAccessToken}'

    Was this helpful?

    /
    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);

    Was this helpful?

    /
    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))
    
    }

    Was this helpful?

    /
    HttpResponse<String> response = Unirest.get("https://your-auth0-tenant.com/api/v2/connections")
      .header("authorization", "Bearer {yourAccessToken}")
      .asString();

    Was this helpful?

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

    Was this helpful?

    /
    #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];

    Was this helpful?

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

    Was this helpful?

    /
    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"))

    Was this helpful?

    /
    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

    Was this helpful?

    /
    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()

    Was this helpful?

    /
    エンドポイントからの応答は、オブジェクトの配列です。各オブジェクトは、テナントと関係がある1つの接続を表しています。

  4. 接続IDを特定します。手順2でGET接続エンドポイントから返されたオブジェクトの配列を確認して、パスワードレス接続と関係があるIDを見つけることができます。パスワードレス接続のある特定のオブジェクトを見つけるには、"name": "sms"プロパティを検索できます。接続で、セットアッププロセス中にあなたが提供したTwilio情報が現在表示されていることに注目してください。

    [
        {
            "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"
            ],
            "enabled_clients": []
        }
    ]

    Was this helpful?

    /

  5. 接続を更新する。接続の更新エンドポイントに対してPATCH呼び出しを行うことで、これを実行できます。より具体的には、SMS Gatewayに関する情報を提供するために、接続optionsオブジェクトを更新します。

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

    • twilio_sidおよびtwilio_tokenの両方のパラメーターを削除します。

    • providerパラメーターを追加し、sms_gatewayに設定します。

    • gateway_urlパラメーターを追加し、SMSゲートウェイのURLに設定します。Auth0は、ゲートウェイを使用してあなたに代わってメッセージを送信するために、このURLに到達できなければなりません。

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

    {
        "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,
        "enabled_clients": []
    }

    Was this helpful?

    /

認証済み要求

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

"gateway_authentication": {
    "method": "bearer",
    "subject": "urn:Auth0",
    "audience": "urn:MySmsGateway",
    "secret": "MySecretToSignTheToken",
    "secret_base64_encoded": false
}

Was this helpful?

/

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

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

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

{
  "recipient": "+1 399 999",
  "body": "Your verification code is: 12345",
  "sender": "+1 234 567"
}

Was this helpful?

/

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

{
  "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"
       }
}

Was this helpful?

/

エラー処理

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

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

{
 "error":"sms_provider_error",
 "error_description":"Unexpected response while calling the SMS gateway: <HTTP Code Returned by the SMS Gateway>"}
}

Was this helpful?

/

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

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