キャプチャAPIの基礎
Liferay は、 SimpleCAPTCHA エンジンを使用して CAPTCHA を取得および送信するためのヘッドレス API を提供します。 API エクスプローラーの /captcha エンドポイントを使用すると、タグ ライブラリを使用せずにカスタム実装に captcha を追加できます。 エンドポイントは 2 つあります。
/GET- 検証用のBase64エンコードされたキャプチャ画像文字列とJWTトークンを取得します。/POST- 検証のためにキャプチャの回答とJWTトークンを送信します
キャプチャチャレンジを受ける
新しいLiferay DXPインスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/dxp:2025.q1.6-lts
メールアドレス test@liferay.com とパスワード testを使用して、 http://localhost:8080 で Liferay にサインインします。 プロンプトが表示されたら、パスワードを learnに変更します。
Liferayが起動したら、
-
Captcha API Basicsをダウンロードして解凍します。
curl https://resources.learn.liferay.com/examples/liferay-p6s7.zip -Ounzip liferay-p6s7.zip -
cURL スクリプトを使用して、キャプチャ画像文字列と検証トークンを取得します。 コマンドラインで、
curlフォルダに移動します。Captcha_GET_FromInstance.shスクリプトを実行します。./Captcha_GET_FromInstance.shJSON 応答には、キャプチャ画像文字列とトークンが表示されます。
{ "image" : "data:image/png;base64,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", "token" : "BnDK5SupcZFFKqlBiswtjHv0tw6ptDYoICH8Y/wccQAwmJzS+pvjBxSiPkDaEwnDcuvHCWuHb4slvrdSZVy3W5N2EDNbDRjljs9ksftAkp8s3Fa6bKYiu4hYsCCCCwJA" } -
data:image/png;base64,プレフィックスを除いた画像フィールドの値をコピーし、次のコマンドを実行します。echo <COPIED_IMAGE_STRING> | base64 -d > captcha.pngこれにより、キャプチャ画像が現在のディレクトリに
captcha.pngというファイル名で保存されます。 ファイルを開いてキャプチャを表示します。
-
前の JSON レスポンスから、
tokenフィールドの値をコピーします。 このトークンを使用して、/POSTエンドポイントを通じてキャプチャを検証します。 -
または、Javaクライアントを使用してRESTサービスを呼び出します。
javajavac -classpath .:* *.java -
Captcha_GET_FromInstanceクラスを実行します。java -classpath .:* Captcha_GET_FromInstance
cURLコマンドの検証
Captcha_GET_FromInstance.sh スクリプトは、cURL コマンドを使用して REST サービスを呼び出します。
curl \
"http://localhost:8080/o/captcha/v1.0/captcha/challenge" \
--user "test@liferay.com:learn"
ここでは、コマンドの引数を紹介します。
引数 説明
"http://localhost:8080/o/captcha/v1.0/captcha/challenge"RESTサービスのエンドポイントを指定します。
--user "test@liferay.com:learn"基本認証の認証情報を入力します。
注
ここでは、デモのために基本的な認証を使用しています。 本番環境では、 OAuth2経由でユーザーを認証する必要があります。 OAuth2 を使用したサンプル React アプリケーションについては、 OAuth2 を使用してユーザーを承認する を参照してください。
Javaクラスを調べる
Captcha_GET_FromInstance.java クラスは、 CaptchaResource サービスを呼び出して、キャプチャ文字列とトークンを取得します。
public static void main(String[] args) throws Exception {
CaptchaResource.Builder builder = CaptchaResource.builder();
CaptchaResource captchaResource = builder.authentication(
"test@liferay.com", "learn"
).build();
Captcha captcha = captchaResource.getCaptchaChallenge();
System.out.println("Token: " + captcha.getToken());
byte[] imageBytes = Base64.getDecoder(
).decode(
captcha.getImage(
).split(
","
)[1]
);
try (FileOutputStream fileOutputStream = new FileOutputStream(
"captcha.png")) {
fileOutputStream.write(imageBytes);
}
}
このクラスは、次の3行のコードのみを使用してRESTサービスを呼び出します。
行(省略形) 説明
CaptchaResource.Builder builder = ...Builder を取得して、 CaptchaResource サービス インスタンスを生成します。
CaptchaResource captchaResource = builder.authentication(...).build();基本認証を使用して、 CaptchaResource サービス インスタンスを生成します。
captchaResource.getCaptchaChallenge();captchaResource.getCaptchaChallenge メソッドを呼び出します。
応答を取得した後、トークンが表示され、 Base64 クラスを使用して画像文字列をバイトにデコードします。 これは同じディレクトリに画像として保存されます。
プロジェクトには、依存関係としてcom.liferay.captcha.rest.client.jarファイルが含まれていることに注意してください。 すべての REST アプリケーションのクライアント JAR 依存関係情報は、インストールの API エクスプローラーの /o/api (例: http://localhost:8080/o/api) で確認できます。
注
メイン メソッドのコメントは、クラスの実行を示しています。
重要
サービスの詳細については、 CaptchaResource を参照してください。
キャプチャ応答を投稿する
キャプチャ画像を取得したら、 /POST エンドポイントを使用して、cURL または Java コマンドで回答とトークンを送信できます。 abcd を答えに置き換え、 efgh をトークンに置き換えます。
Captcha_POST_ToInstance cURLコマンドを調べる
コマンド:
./Captcha_POST_ToInstance.sh abcd efgh
コード:
curl \
"http://localhost:8080/o/captcha/v1.0/captcha/response" \
--data-raw '
{
"answer": "'${1}'",
"token": "'${2}'"
}' \
--header "Content-Type: application/json" \
--request "POST" \
--user "test@liferay.com:learn" \
Captcha_POST_ToInstance.sh スクリプトは、cURL コマンドを使用して REST サービスを呼び出します。
ここでは、コマンドの引数を紹介します。
引数 説明
"http://localhost:8080/o/captcha/v1.0/captcha/response"RESTサービスのエンドポイントを指定します。
--data-raw '{ "answer": "'${1}'", "token": "'${2}'"}'投稿するデータを入力します。
--header "Content-Type: application/json"リクエストボディの形式をJSONに設定します。
--request "POST"指定されたエンドポイントで呼び出す HTTP メソッドを設定します。
--user "test@liferay.com:learn"基本認証の認証情報を入力します。
回答が有効な場合、API は 204 を返します。 JWT トークンには、 nonce があり、 /POST エンドポイントによって追跡されます。 すでに間違った回答を送信している場合は、同じトークンを再利用することはできません。
Captcha_POST_ToInstance クラスを調べる
コマンド:
java -classpath .:* -Danswer=abcd -Dtoken=efgh Captcha_POST_ToInstance
コード:
public static void main(String[] args) throws Exception {
CaptchaResource.Builder builder = CaptchaResource.builder();
CaptchaResource captchaResource = builder.authentication(
"test@liferay.com", "learn"
).build();
captchaResource.postCaptchaResponse(
new Captcha() {
{
answer = String.valueOf(System.getProperty("answer"));
token = String.valueOf(System.getProperty("token"));
}
});
}
Captcha_POST_ToInstance.java クラスは、 CaptchaResource サービスを呼び出して、キャプチャの回答とトークンを送信します。
このクラスは、わずか3行のコードでRESTサービスを呼び出します。
行(省略形) 説明
CaptchaResource.Builder builder = ...Builder を取得して、 CaptchaResource サービス インスタンスを生成します。
CaptchaResource captchaResource = builder.authentication(...).build();基本認証を使用して、 CaptchaResource サービス インスタンスを生成します。
captchaResource.postCaptchaResponse(...);captchaResource.postCaptchaResponse メソッドを呼び出します。
postCaptchaResponse() メソッドは、キャプチャの回答と JWT トークンを含む Captcha クラスのインスタンスを受け入れます。 回答が有効な場合、API は 204 を返します。 JWT トークンには、 nonce があり、 /POST エンドポイントによって追跡されます。 すでに間違った回答を送信している場合は、同じトークンを再利用することはできません。
誤ったキャプチャを送信するか、無効/期限切れのトークンを使用する
正しいトークンを使用して誤ったキャプチャ回答を送信すると、次の応答が返されます。
{
"status" : "BAD_REQUEST",
"title" : "Answer is invalid",
"type" : "CaptchaTextException"
}
すでに使用されているのと同じトークンを使用して正しい回答を送信すると、次の応答が返されます。
{
"status" : "BAD_REQUEST",
"title" : "Token: BnDK5SupcZFFKqlBiswtjHv0tw6ptDYoICH8Y/wccQAwmJzS+pvjBxSiPkDaEwnDcuvHCWuHb4slvrdSZVy3W5N2EDNbDRjljs9ksftAkp8s3Fa6bKYiu4hYsCCCCwJA",
"type" : "IllegalArgumentException"
}
期限切れのトークンを使用しようとすると、同じ応答が返されます。
API エクスプローラー には、 キャプチャ サービスとスキーマが表示され、各サービスをテストするためのインターフェースがあります。