バックエンド実装
この章では、サンプルコードを使用して、加盟店アプリのバックエンドへの実装方法について説明します。
Note
サンプルコードに目を通し、実装してから、次に進んでください。
バックエンドには3DSリクエスターを実装する必要があります。次の図は、3DSリクエスターに含まれる主なファイルを示します。これらはサンプルコードの/final
ディレクトリの中にあります。必要に応じディレクトリ構想を確認してください。
AuthController
は3DS認証用のリクエストを処理するコントローラークラスで、ステップ.2、ステップ.3のように3DS-web-adapterからのリクエストを処理してActiveServerに転送します。
処理 1: 認証の初期化
認証を初期化するためには、3DSリクエスターが以下のように動作する必要があります。
- 3DS-web-adapterからの
認証の初期化
リクエストを処理する(ステップ.2、およびステップ.3)。 - 応答メッセージを受信して3DS-web-adapterに返送する(ステップ.4、およびステップ.5)。
AuthController
で、3DSリクエスターは、@PostMapping("/auth/init")
を使用してinitAuth
ハンドラーメソッドを実行し認証の初期化
リクエストを処理します。フロンドエンドがこのリクエストをどうやって送信しているかの説明は、ここを参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class AuthController { @PostMapping("/auth/init") public InitAuthResponseBRW initAuth(@RequestBody InitAuthRequestBRW request) { String initBrwUrl = THREE_DS_SERVER_URL + "/api/v1/auth/brw/init/pa"; // 認証の初期化を/brw/init/{messageCategory} (ステップ. 3)にPOST要求する RequestEntity<InitAuthRequestBRW> req = new RequestEntity<>(request, HttpMethod.POST, URI.create(initBrwUrl)); try { ResponseEntity<InitAuthResponseBRW> resp = restTemplate.exchange(req, InitAuthResponseBRW.class); InitAuthResponseBRW initRespBody = resp.getBody(); logger.info("initAuthResponseBRW {}", initRespBody); // set InitAuthResponseBRW for future use transactionInfo.setInitAuthResponseBRW(initRespBody); return initRespBody; } catch (HttpClientErrorException | HttpServerErrorException ex) { logger.error("initAuthReq failed, {}, {}", ex.getStatusCode(), ex.getResponseBodyAsString()); throw ex; } } } |
initAuth
ハンドラーメソッドは、まずURL initBrwUrl = THREE_DS_SERVER_URL + ../brw/init/{messageCategory}
を初期化します(行5)。リクエストは、このURLにPOST送信されます(ステップ.3)。
Note
次に、行11と12でinitAuth
コントローラーはリクエストをPOST送信して応答を待ちます。リクエストと応答のデータ構造はそれぞれInitAuthRequestBRW
、InitAuthResponseBRW
です。
InitAuthRequestBRW
-/brw/init/{messageCategory}
へのAPI呼び出しを行うのに必要なすべての情報を保持しています(ステップ.3)。InitAuthResponseBRW
-/brw/init/{messageCategory}
へのAPI呼び出しに対する応答に関する情報を保持しています(ステップ.4)。
InitAuthRequestBRW
とInitAuthResponseBRW
のデータ構造については、API Documentを参照してください。
Note
3DSリクエスターを実装する際には、次の2つの事項が重要です。
Tip
3DSリクエスターはSSLを使用してActiveServerに接続します。API呼び出しを行うには、RESTTemplate
にクライアント証明書を添付する必要があります。
/resources/certs
ディレクトリ内のクライアント証明書(.p12
ファイル)とcacerts.jks
トラストストアファイルを確認してください。.p12
ファイルの取得についてはIntroductionを参照してください。- SSL設定は
RestClientConfig
クラスに実装されています。このクラスはrequestor/config
ディレクトリにあります。
Tip
次の例のコードでは、3DSリクエスターはInitAuthRequestBRW
リクエストを挿入してから3DSサーバーに送信しています。
1 2 3 4 5 6 | //AuthController.java public InitAuthResponseBRW initAuth(@RequestBody InitAuthRequestBRW request) { ... fillInitAuthRequestBRW(request, THREE_DS_REQUESTOR_URL + "/3ds-notify"); ... } |
AuthController.java
の中にあるfillInitAuthRequestBRW
メソッドについて説明します。このメソッドではInitAuthRequestBRW
にデモ用のデフォルトデータを挿入していますが、実際の状況では、データベースからのデータ、あるいはフロンドエンドから送信されたカード会員情報をロードするように、このメソッドの部分を入れ替えることができます。処理 2: 認証の実行
認証を実行するためには、3DSリクエスターが以下のように動作する必要があります。
ステップ.7の後にActiveServerからの
/3ds-notify
メッセージを処理する。
ブラウザー情報収集(ステップ.7)が完了したら、ActiveServerは、THREE_DS_REQUESTOR_URL/3ds-notify
に設定されているeventCallBackUrl
にiframe
を通して通知します。3DSリクエスターは、MainController.java
にてこの通知を処理します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // MainController.java @PostMapping("/3ds-notify") public String notifyResult( @RequestParam("requestorTransId") String transId, @RequestParam("event") String callbackType, @RequestParam(name = "param", required = false) String param, Model model) { String callbackName; // check the callbackType and initialise callbackName if ("3DSMethodFinished".equals(callbackType)) { callbackName = "_on3DSMethodFinished"; } else if ("3DSMethodSkipped".equals(callbackType)) { callbackName = "_on3DSMethodSkipped"; } else { throw new IllegalArgumentException("invalid callback type"); } //オブジェクトの情報をnotify_3ds_eventsに送る。 model.addAttribute("transId", transId); model.addAttribute("callbackName", callbackName); model.addAttribute("callbackParam", param); return "notify_3ds_events"; } |
このハンドラーメソッドは、パラメーターtransId
とcallbackType
、およびオプションのparam
を取り込みます。callbackType
は、3DSMethodFinished
または3DSMethodSkipped
のいずれかです。ハンドラーメソッドは文字列notify_3ds_events
を返します。これは、名前がnotify_3ds_events.html
であるHTMLページを返すことを意味します。フロンドエンドでのnotify_3ds_events.html
の実装については、ここを参照してください。
AuthController
で、3DSリクエスターは、@PostMapping("/auth")
を使用してauth
ハンドラーメソッドを実行し認証の実行
リクエストを処理します(ステップ.9)。このメソッドは、threeDSRequestorTransID
とthreeDSServerTransID
を使用して/brw
へのPOST APIリクエストを行います(ステップ.10)。ActiveServerは、AReq
を初期化して送信することで3DS処理を開始し(ステップ.11)、ARes
を受信します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //AuthController.java @PostMapping("/auth") public AuthResponseBRW auth(@RequestParam("id") String transId) { MerchantTransaction transaction = transMgr.findTransaction(transId); //create authentication request. AuthRequestBRW authRequest = new AuthRequestBRW(); authRequest.setThreeDSRequestorTransID(transaction.getId()); authRequest.setThreeDSServerTransID(transaction.getInitAuthResponseBRW().getThreeDSServerTransID()); String brwUrl = THREE_DS_SERVER_URL + "/api/v1/auth/brw"; AuthResponseBRW response = restTemplate.postForObject(brwUrl, authRequest, AuthResponseBRW.class); logger.info("authResponseBRW {}", response); return response; } |
auth
ハンドラーメソッドはフロンドエンドに応答
します。応答
に含まれているtransStatus
の値はY
, N
, U
,R
, A
またはC
であり、この応答結果に応じて以後のフローを加盟店が決定できます。ステップ毎の実装ガイドにおいては主にY
とC
それぞれフリクションレス、チャレンジのフローについて解説しています。フロンドエンドでのtransStatus
の処理については、ここを参照してください。また、AuthRequestBRW
とAuthResponseBRW
のデータ構造については、API documentを参照してください。
処理 3: 認証結果の取得
認証結果を取得するためには、3DSリクエスターが以下のように動作する必要があります。
- 3DS-web-adapterからの
認証結果取得
リクエストを処理する(ステップ.15(F)、またはステップ.20(C))。 - ActiveServerにリクエストを送信して結果を取得し、フロンドエンドに結果を返す(ステップ.16(F)、ステップ.17(F)、またはステップ.21(C)、ステップ.22(C))。
認証結果の準備ができると、ActiveServerはeventCallBackUrl
を使用して通知を送信します。3DSリクエスターは_onAuthResult
メッセージをnotify_3ds_events.html
に返して通知を処理します。フロンドエンドでの_onAuthResult
メッセージの実装については、ここを参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 | //MainController.java @PostMapping("/3ds-notify") public String notifyResult( ... if ("3DSMethodFinished".equals(callbackType)) { callbackName = "_on3DSMethodFinished"; } else if ("3DSMethodSkipped".equals(callbackType)) { callbackName = "_on3DSMethodSkipped"; } else if ("AuthResultReady".equals(callbackType)) { callbackName = "_onAuthResult"; } ... |
3DSリクエスターは、@GetMapping("/auth/result")
を使用してresult
ハンドラーメソッドを実行し認証結果を取得
します。このハンドラーメソッドは、/brw/result
を呼び出してActiveServerに認証結果を要求し、フロンドエンドにresult
を返します。フロンドエンドはresult.html
ページを使用して結果を表示します。フロンドエンドでの実装については、ここを参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 | @GetMapping("/auth/result") public String result( @RequestParam("txid") String transId, Model model) { MerchantTransaction transaction = transMgr.findTransaction(transId); String resultUrl = AuthController.THREE_DS_SERVER_URL + "/api/v1/auth/brw/result?threeDSServerTransID=" + transaction.getInitAuthResponseBRW().getThreeDSServerTransID(); AuthResponseBRW response = restTemplate.getForObject(resultUrl, AuthResponseBRW.class); model.addAttribute("result", response); return "result"; } |
Success
お疲れ様でした。これでバックエンドの導入は完了です。
次のチャプター
「次へ」ボタンを選択し、ステップ毎の実装ガイドに従って加盟店のウェブサイトに3DSリクエスターを統合してください。