이 페이지에서는 Android 앱에 reCAPTCHA Enterprise를 통합하는 방법을 설명합니다.
의심스러운 트래픽에 시각적 챌린지를 제공하려면 SafetyNet reCAPTCHA API를 사용하면 됩니다.
시작하기 전에
Android 앱 플랫폼의 reCAPTCHA 키를 만듭니다.
또는 다음 단계 중 하나를 수행하여 Android용 기존 reCAPTCHA 키의 ID를 복사할 수 있습니다.
Google Cloud 콘솔에서 기존 키의 ID를 복사하려면 다음을 수행합니다.
reCAPTCHA Enterprise 페이지로 이동합니다.
- reCAPTCHA 키 목록에서 복사할 키 위에 마우스 포인터를 올려놓고 를 클릭합니다.
- REST API를 사용하여 기존 키의 ID를 복사하려면 projects.keys.list 메서드를 사용합니다.
- gcloud CLI를 사용하여 기존 키의 ID를 복사하려면 gcloud recaptcha keys list 명령어를 사용합니다.
Android 환경 준비
기본 Android
최신 버전의 Android 스튜디오를 다운로드하고 설치하여 개발 환경을 준비합니다.
최소 Android SDK 값이 API 19: Android 4.4(KitKat)로 설정된 앱이 있는지 확인합니다. 앱의 최소 SDK를 API 19로 설정하거나 새 모바일 앱을 만들 수 있습니다.
새 모바일 앱을 만드는 경우 새로운 Android 스튜디오 프로젝트를 시작하여 테스트 애플리케이션을 만듭니다.
- 빈 활동을 선택합니다. 앱에서 Jetpack Compose를 사용하려면 빈 Compose 활동을 선택합니다.
- 언어를 kotlin으로 설정합니다.
- 최소 SDK 값을 API 19: Android 4.4(KitKat)로 설정합니다.
다음 스니펫과 같이 Google의 Maven 저장소
google()
이 프로젝트 수준build.gradle
파일의 저장소 목록에 있는지 확인합니다.allprojects { repositories { google() } }
자세한 내용은 Google의 Maven 저장소를 참조하세요.
reCAPTCHA Enterprise API 종속 항목을 추가하려면 앱 수준
build.gradle
파일의dependencies
섹션에 다음 빌드 규칙을 추가합니다.implementation 'com.google.android.recaptcha:recaptcha:18.5.0-beta03'
Android 앱에 종속 항목을 추가하는 방법에 대한 자세한 내용은 빌드 종속 항목 추가를 참조하세요.
애플리케이션 매니페스트에서 첫 번째
<manifest>
태그와 첫 번째<application>
태그 사이에 인터넷 권한을 추가합니다(예:AndroidManifest.xml
). reCAPTCHA Enterprise API를 사용하려면 네트워크 작업이 필요하므로 이 권한이 필요합니다.<manifest ...> <uses-permission android:name="android.permission.INTERNET" /> <application ...> ... </application> </manifest>
새 프로젝트에서
AndroidX
라이브러리를 사용하려면 SDK를 Android 9.0 이상으로 컴파일하고 다음 코드 스니펫을gradle.properties
에 추가하세요.android.useAndroidX=true android.enableJetifier=true
자세한 내용은 AndroidX로 마이그레이션을 참조하세요.
Flutter
Flutter를 통해 reCAPTCHA Enterprise를 사용하는 방법에 대한 자세한 내용은 Flutter 문서를 참조하세요.
React Native
React Native를 통해 reCAPTCHA Enterprise를 사용하는 방법에 대한 자세한 내용은 React Native 문서를 참조하세요.
Android 앱에 reCAPTCHA Enterprise 통합
Android 앱용으로 만든 reCAPTCHA 키(KEY_ID)를 사용하여 클라이언트를 인스턴스화합니다.
Kotlin
class MainActivity : AppCompatActivity() { private lateinit var recaptchaClient: RecaptchaClient override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initializeRecaptchaClient() // ... rest of onCreate code } private fun initializeRecaptchaClient() { lifecycleScope.launch { Recaptcha.getClient(application, "KEY_ID") .onSuccess { client -> recaptchaClient = client } .onFailure { exception -> // Handle communication errors ... // See "Handle communication errors" section } } } // ... rest of activity code. }
자바
public final class MainActivity extends Activity { @Nullable private RecaptchaTasksClient recaptchaTasksClient = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initializeRecaptchaClient(); // ... rest of onCreate code } private void initializeRecaptchaClient() { Recaptcha .getTasksClient(getApplication(), "KEY_ID") .addOnSuccessListener( this, new OnSuccessListener<RecaptchaTasksClient>() { @Override public void onSuccess(RecaptchaTasksClient client) { MainActivity.this.recaptchaTasksClient = client; } }) .addOnFailureListener( this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Handle communication errors ... // See "Handle communication errors" section } }); } // ... rest of activity code. }
reCAPTCHA Enterprise를 사용하여 보호되는 앱의 각 작업에 대해
execute
메서드를 호출하여 RecaptchaAction을 전달합니다. reCAPTCHA Enterprise는 기본 제공 작업 집합을 제공하며 필요한 경우 커스텀 작업을 만들 수도 있습니다.다음 코드 스니펫은
execute
를 사용하여LOGIN
작업을 보호하는 방법을 보여줍니다.Kotlin
private fun executeLoginAction() { lifecycleScope.launch { recaptchaClient .execute(RecaptchaAction.LOGIN) .onSuccess { token -> // Handle success ... // See "What's next" section for instructions // about handling tokens. } .onFailure { exception -> // Handle communication errors ... // See "Handle communication errors" section } } }
자바
private void executeLoginAction(View v) { assert recaptchaTasksClient != null; recaptchaTasksClient .executeTask(RecaptchaAction.LOGIN) .addOnSuccessListener( this, new OnSuccessListener<String>() { @Override public void onSuccess(String token) { // Handle success ... // See "What's next" section for instructions // about handling tokens. } }) .addOnFailureListener( this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Handle communication errors ... // See "Handle communication errors" section } }); }
다음 샘플 코드 스니펫은 단일 활동 앱에서 getClient()
및 execute()
메서드의 전체 통합을 보여줍니다.
Kotlin
class MainActivity : AppCompatActivity() {
private lateinit var recaptchaClient: RecaptchaClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initializeRecaptchaClient()
findViewById<View>(R.id.btn_login).setOnClickListener { executeLoginAction() }
findViewById<View>(R.id.btn_redeem).setOnClickListener { executeRedeemAction() }
}
private fun initializeRecaptchaClient() {
lifecycleScope.launch {
Recaptcha.getClient(application, "KEY_ID")
.onSuccess { client ->
recaptchaClient = client
}
.onFailure { exception ->
// Handle communication errors ...
// See "Handle communication errors" section
}
}
}
private fun executeLoginAction() {
lifecycleScope.launch {
recaptchaClient
.execute(RecaptchaAction.LOGIN)
.onSuccess { token ->
// Handle success ...
// See "What's next" section for instructions
// about handling tokens.
}
.onFailure { exception ->
// Handle communication errors ...
// See "Handle communication errors" section
}
}
}
private fun executeRedeemAction(){
lifecycleScope.launch {
recaptchaClient
.execute(RecaptchaAction.custom("redeem"))
.onSuccess { token ->
// Handle success ...
// See "What's next" section for instructions
// about handling tokens.
}
.onFailure { exception ->
// Handle communication errors ...
// See "Handle communication errors" section
}
}
}
}
자바
public final class MainActivity extends Activity {
@Nullable private RecaptchaTasksClient recaptchaTasksClient = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeRecaptchaClient();
findViewById(R.id.btn_login).setOnClickListener(this::executeLoginAction);
findViewById(R.id.btn_redeem).setOnClickListener(this::executeRedeemAction);
}
private void initializeRecaptchaClient() {
Recaptcha
.getTasksClient(getApplication(), "KEY_ID")
.addOnSuccessListener(
this,
new OnSuccessListener<RecaptchaTasksClient>() {
@Override
public void onSuccess(RecaptchaTasksClient client) {
MainActivity.this.recaptchaTasksClient = client;
}
})
.addOnFailureListener(
this,
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Handle communication errors ...
// See "Handle communication errors" section
}
});
}
private void executeLoginAction(View v) {
assert recaptchaTasksClient != null;
recaptchaTasksClient
.executeTask(RecaptchaAction.LOGIN)
.addOnSuccessListener(
this,
new OnSuccessListener<String>() {
@Override
public void onSuccess(String token) {
// Handle success ...
// See "What's next" section for instructions
// about handling tokens.
}
})
.addOnFailureListener(
this,
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Handle communication errors ...
// See "Handle communication errors" section
}
});
}
private void executeRedeemAction(View v) {
assert recaptchaTasksClient != null;
recaptchaTasksClient
.executeTask(RecaptchaAction.custom("redeem"))
.addOnSuccessListener(
this,
new OnSuccessListener<String>() {
@Override
public void onSuccess(String token) {
// Handle success ...
// See "What's next" section for instructions
// about handling tokens.
}
})
.addOnFailureListener(
this,
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// Handle communication errors ...
// See "Handle communication errors" section
}
});
}
}
API 호출 제한 시간 설정
각 API의 timeout
속성을 사용하여 getClient
및 execute
API에 대한 제한 시간 값을 지정할 수 있습니다.
getClient
에는 10초, execute
API에는 10초의 기본 제한 시간이 사용됩니다.
Kotlin
getClient
호출 시 제한 시간을 설정합니다.lifecycleScope.launch { Recaptcha.getClient(application, "KEY_ID", timeout = 20000L) .onSuccess { client -> recaptchaClient = client } .onFailure { exception -> // Handle communication errors ... // See "Handle communication errors" section } }
이 코드 스니펫은
getClient
의 제한 시간을 20초로 설정합니다.execute
호출 시 제한 시간을 설정합니다.lifecycleScope.launch { recaptchaClient .execute(RecaptchaAction.LOGIN(), timeout = 10000L) .onSuccess { token -> // Handle success ... // See "What's next" section for instructions // about handling tokens. } .onFailure { exception -> // Handle communication errors ... // See "Handle communication errors" section } }
이 코드 스니펫은
execute
의 제한 시간을 10초로 설정합니다.
자바
getClient
호출 시 제한 시간을 설정합니다.Recaptcha .getTasksClient(getApplication(), "KEY_ID", 20000L) .addOnSuccessListener( this, new OnSuccessListener<RecaptchaTasksClient>() { @Override public void onSuccess(RecaptchaTasksClient client) { MainActivity.this.recaptchaTasksClient = client; } }) .addOnFailureListener( this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Handle communication errors ... // See "Handle communication errors" section } });
이 코드 스니펫은
getClient
의 제한 시간을 20초로 설정합니다.execute
호출 시 제한 시간을 설정합니다.recaptchaTasksClient .executeTask(RecaptchaAction.custom("redeem"), 10000L) .addOnSuccessListener( this, new OnSuccessListener<String>() { @Override public void onSuccess(String token) { // Handle success ... // See "What's next" section for instructions // about handling tokens. } }) .addOnFailureListener( this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Handle communication errors ... // See "Handle communication errors" section } });
이 코드 스니펫은
execute
의 제한 시간을 10초로 설정합니다.
통신 오류 처리하기
앱이 reCAPTCHA 서비스와 성공적으로 통신할 수 없으면 API에 오류가 발생한 것일 수 있습니다. 이러한 오류를 정상적으로 처리하는 로직을 앱에 추가해야 합니다.
일반적인 API 오류의 완화에 대한 자세한 내용은 RecaptchaStatusCode를 참조하세요.
API 참조
Android용 reCAPTCHA API의 전체 참조는 com.google.android.recaptcha
를 참조하세요.
다음 단계
reCAPTCHA 응답 토큰을 평가하려면 평가를 만듭니다.