28/03/2023
Google reCAPTCHA: Forståelse og Implementering i Android-apps
I den digitale tidsalder er beskyttelse mod ondsindede bots og automatiserede angreb afgørende for enhver applikation. Google reCAPTCHA er en af de mest effektive og udbredte løsninger til at verificere, om en bruger er et menneske eller en bot. Denne artikel dykker ned i, hvordan Google reCAPTCHA fungerer, og hvordan du kan implementere det i dine egne Android-applikationer ved hjælp af Java. Vi vil guide dig gennem processen trin for trin, fra opsætning af API-nøgler til den faktiske kodning.

Hvad er Google reCAPTCHA?
Google reCAPTCHA er en gratis tjeneste, der beskytter websites og mobilapps mod spam og misbrug ved at lade brugere gennemgå en test, der adskiller mennesker fra bots. reCAPTCHA tilbyder flere versioner, hvoraf den mest almindelige er den, der præsenterer en udfordring (f.eks. at identificere billeder eller indtaste tekst), og den nyere version, reCAPTCHA v3, der kører i baggrunden og tildeler en score baseret på brugerens interaktion med appen uden at kræve en synlig udfordring.
Formålet med reCAPTCHA er at skelne mellem ægte brugere og automatiserede programmer (bots), som kan bruges til skadelige formål som f.eks. at oprette falske konti, foretage uautoriserede transaktioner eller sprede spam.
Hvordan virker Google reCAPTCHA i Android?
Implementeringen af reCAPTCHA i Android involverer typisk en tovejskommunikation mellem din Android-app, Google's SafetyNet-servere og din egen backend-server. Processen kan groft opdeles i følgende trin:
- Initiation: Når en bruger skal verificeres, sender din Android-app en anmodning til Google's SafetyNet API ved hjælp af en site key (offentlig nøgle), der er knyttet til din applikation.
- Brugerinteraktion: Google's reCAPTCHA-tjeneste præsenterer en udfordring for brugeren (hvis relevant for den valgte reCAPTCHA-version) eller analyserer brugerens adfærd.
- Token Generering: Efter en succesfuld verifikation genererer reCAPTCHA en unik token, der bekræfter, at brugeren er et menneske.
- Callback til App: Denne token returneres til din Android-app.
- Backend Verifikation: Din Android-app sender derefter denne token til din backend-server. Din server kommunikerer med Google's reCAPTCHA-server ved hjælp af en secret key (privat nøgle) og den modtagne token for at validere tokenen.
- Endelig Bekræftelse: Google's server bekræfter tokenens gyldighed og sender et succes- eller fejlsvar tilbage til din server, som derefter informerer din Android-app.
Denne proces sikrer, at selvom site key er synlig i appen, er det den hemmelige secret key på serveren, der giver den endelige validering, hvilket giver et ekstra lag af sikkerhed.
Trin-for-Trin Implementering i Android (Java)
Lad os nu se på den praktiske implementering. Følgende trin vil guide dig gennem oprettelsen af en simpel Android-app med en knap, der udløser reCAPTCHA-verifikationen.
Trin 1: Opret et Nyt Android-projekt
Start Android Studio og opret et nyt projekt. Vælg en tom aktivitet og sørg for at vælge Java som programmeringssprog.
Trin 2: Tilføj Nødvendige Dependencies
Du skal bruge Volley til netværksanmodninger og Google Play Services SafetyNet til at interagere med reCAPTCHA. Åbn din build.gradle (app) fil og tilføj følgende dependencies:
constraintlayout compileSdkPreview implementation 'com.android.volley:volley:1.1.1' implementation 'com.google.android.gms:play-services-safetynet:15.0.1' Efter at have tilføjet dependencies, synkroniser dit projekt med Gradle-filer ved at klikke på "Sync Now".
Trin 3: Generer Google reCAPTCHA API-nøgler
Før du kan bruge reCAPTCHA, skal du generere dine egne API-nøgler:
- Besøg Google reCAPTCHA admin-konsollen.
- Registrer din applikation ved at angive et etiketnavn (f.eks. "Min Android App").
- Vælg reCAPTCHA-typen. For mobilapps er reCAPTCHA v3 ofte et godt valg, da det er usynligt for brugeren. Men for demonstrationens skyld og kompatibilitet med SafetyNet API'en, kan du vælge "v2 - Jeg er ikke en robot" (specifikt "App integration").
- Indtast dit Android-applikationspakkenavn (det samme som i din
build.gradlefil). - Accepter reCAPTCHA-vilkårene.
- Klik på "Submit".
Du vil nu modtage to nøgler:
- Site Key (Offentlig nøgle): Denne bruges i din Android-app.
- Secret Key (Privat nøgle): Denne skal holdes sikker på din backend-server og bruges til at validere tokens.
Vigtigt: Kopier din Site Key og gem den, da du skal indsætte den i din Java-kode. Din Secret Key bør ikke inkluderes direkte i app-koden af sikkerhedsmæssige årsager; den skal bruges på din server.
Trin 4: Tilføj Internet Tilladelse
Din app skal have adgang til internettet for at kommunikere med Google's servere. Åbn AndroidManifest.xml og tilføj følgende linje før <application> tagget:
Trin 5: Design af Brugergrænsefladen (activity_main.xml)
Vi skal bruge en simpel knap til at starte reCAPTCHA-verifikationen. Åbn res/layout/activity_main.xml og indsæt følgende kode:
Trin 6: Implementering af Logik (MainActivity.java)
Nu skal vi skrive Java-koden for at håndtere reCAPTCHA-interaktionen. Åbn MainActivity.java og indsæt følgende kode:
import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.android.volley.DefaultRetryPolicy; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.common.api.CommonStatusCodes; import com.google.android.gms.safetynet.SafetyNet; import com.google.android.gms.safetynet.SafetyNetApi; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; public class MainActivity extends AppCompatActivity { private static final String TAG = "reCAPTCHA_Demo"; // ERSTAT "DIN_SITE_KEY" MED DIN RIGTIGE SITE KEY private final String SITE_KEY = "DIN_SITE_KEY"; // DIN SECRET KEY SKAL BRUGES PÅ SERVEREN. IKKE HER. // private final String SECRET_KEY = "DIN_SECRET_KEY"; private Button btnVerifyCaptcha; private RequestQueue requestQueue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestQueue = Volley.newRequestQueue(this); btnVerifyCaptcha = findViewById(R.id.btnVerifyCaptcha); btnVerifyCaptcha.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { verifyGoogleReCAPTCHA(); } }); } private void verifyGoogleReCAPTCHA() { SafetyNet.getClient(this).verifyWithRecaptcha(SITE_KEY) .addOnSuccessListener(this, new OnSuccessListener() { @Override public void onSuccess(SafetyNetApi.RecaptchaTokenResponse response) { String userResponseToken = response.getTokenResult(); if (!userResponseToken.isEmpty()) { Log.d(TAG, "reCAPTCHA Token: " + userResponseToken); // Her skal du sende token til din backend for verifikation // I dette eksempel simulerer vi verifikation ved at sende til Google's API direkte // (Dette er IKKE anbefalet i produktion - brug din egen backend!) verifyTokenWithGoogleBackend(userResponseToken); } else { Log.d(TAG, "reCAPTCHA token er tom."); Toast.makeText(MainActivity.this, "reCAPTCHA fejlede: Tom token", Toast.LENGTH_SHORT).show(); } } }) .addOnFailureListener(this, new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { if (e instanceof ApiException) { ApiException apiException = (ApiException) e; int statusCode = apiException.getStatusCode(); Log.e(TAG, "reCAPTCHA API Exception: " + CommonStatusCodes.getStatusCodeString(statusCode), e); Toast.makeText(MainActivity.this, "reCAPTCHA fejl: " + CommonStatusCodes.getStatusCodeString(statusCode), Toast.LENGTH_LONG).show(); } else { Log.e(TAG, "Ukendt reCAPTCHA fejl: " + e.getMessage(), e); Toast.makeText(MainActivity.this, "Ukendt fejl ved reCAPTCHA: " + e.getMessage(), Toast.LENGTH_LONG).show(); } } }); } // ADVARSEL: Denne metode sender direkte til Google's API. // I en produktionsapplikation skal du sende token til DIN EGEN BACKEND, // som derefter kommunikerer med Google's API ved hjælp af DIN SECRET KEY. private void verifyTokenWithGoogleBackend(final String responseToken) { // URL til Google's reCAPTCHA siteverify API String url = "https://www.google.com/recaptcha/api/siteverify"; StringRequest stringRequest = new StringRequest(Request.Method.POST, url, response -> { try { JSONObject jsonObject = new JSONObject(response); boolean success = jsonObject.getBoolean("success"); if (success) { Log.d(TAG, "Backend Verifikation: Succes!"); Toast.makeText(MainActivity.this, "Bruger verificeret!", Toast.LENGTH_LONG).show(); // Opdater UI eller udfør yderligere handlinger her } else { Log.e(TAG, "Backend Verifikation: Fejl. Response: " + response); Toast.makeText(MainActivity.this, "Verifikation mislykkedes. Tjek din 'secret key' eller token.", Toast.LENGTH_LONG).show(); } } catch (JSONException e) { Log.e(TAG, "JSON Parsing Fejl: " + e.getMessage()); Toast.makeText(MainActivity.this, "Fejl ved behandling af svar.", Toast.LENGTH_LONG).show(); } }, error -> { Log.e(TAG, "Volley Error: " + error.getMessage()); Toast.makeText(MainActivity.this, "Netværksfejl ved verifikation.", Toast.LENGTH_LONG).show(); }) { @Override protected Map getParams() { Map params = new HashMap<>(); // VIGTIGT: SECRET_KEY skal være din hemmelige nøgle fra Google. // Denne bør hentes fra en sikker konfiguration på serveren, // ikke hardcodet her i en produktionsapp. // For demonstrationens skyld, er den ukommenteret for at vise konceptet. // params.put("secret", "DIN_SECRET_KEY"); params.put("response", responseToken); return params; } }; // Justering af retry policy for at håndtere potentielle netværksforsinkelser stringRequest.setRetryPolicy(new DefaultRetryPolicy( 50000, // Timeout i millisekunder (50 sekunder) DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); requestQueue.add(stringRequest); } } Husk: Erstat "DIN_SITE_KEY" med din faktiske reCAPTCHA Site Key. For en produktionsapplikation skal du aldrig inkludere din Secret Key i Android-koden. Den skal bruges på din backend-server til at validere tokens sikkert.

reCAPTCHA V3 og App Check
Mens SafetyNet API'en er en måde at integrere reCAPTCHA, tilbyder Google også App Check, som integrerer med Firebase og giver et robust system til at beskytte dine backend-ressourcer. App Check kan bruge reCAPTCHA v3 som en provider til at validere appens identitet.
Fordele ved reCAPTCHA v3 med App Check:
- Usynlig for brugeren: Kræver ingen interaktion fra brugeren.
- Risikoscore: Giver en score, der indikerer sandsynligheden for, at en anmodning er ondsindet.
- Beskyttelse af Firebase-ressourcer: Sikrer, at kun godkendte app-instanser kan tilgå dine Firebase-tjenester.
Vigtige overvejelser for reCAPTCHA v3:
- Implementering: Kræver opsætning i Firebase-konsollen og tilføjelse af App Check SDK'en til din app.
- TTL (Time To Live): Du kan konfigurere, hvor længe App Check-tokens er gyldige. Kortere TTL øger sikkerheden, men kan påvirke ydeevnen.
- Overvågning og Håndhævelse: Det anbefales at overvåge App Check-metrikker, før du håndhæver det fuldt ud, for at undgå at blokere legitime brugere.
Overgang til reCAPTCHA Enterprise: Google anbefaler at bruge reCAPTCHA Enterprise til nye integrationer, da det tilbyder forbedrede funktioner og bedre beskyttelse mod svindel. Det giver op til 10.000 gratis evalueringer pr. måned.
Fejlfinding og Bedste Praksis
Almindelige Fejl:
- Forkert Site Key: Dobbelttjek, at din site key er korrekt indsat i koden.
- Manglende Internet Tilladelse: Sørg for, at
<uses-permission android:name="android.permission.INTERNET" />er tilføjet iAndroidManifest.xml. - Secret Key Eksponering:Undgå at inkludere din secret key i Android-appen. Brug en backend-tjeneste.
- Netværksproblemer: Implementer korrekt fejlhåndtering og retry-mekanismer (som vist med Volley's
DefaultRetryPolicy). - API Versionering: Sørg for, at de anvendte Google Play Services-versioner er kompatible.
Bedste Praksis:
- Brug en Backend: Valider altid reCAPTCHA-tokens på din egen server for maksimal sikkerhed.
- Håndter Fejl Gracefully: Informer brugeren tydeligt, hvis verifikationen fejler, og giv dem mulighed for at prøve igen.
- Overvej reCAPTCHA v3 eller Enterprise: For en bedre brugeroplevelse, især på mobile enheder, er de usynlige versioner at foretrække.
- Test Grundigt: Test din implementering på forskellige enheder og netværksforhold.
Konklusion
Google reCAPTCHA er et kraftfuldt værktøj til at beskytte dine Android-applikationer mod bots og ondsindede aktiviteter. Ved at følge disse trin kan du succesfuldt integrere reCAPTCHA og forbedre sikkerheden og troværdigheden af din app. Husk altid at prioritere sikkerheden ved at håndtere din secret key korrekt og overveje de nyere, mere brugervenlige versioner af reCAPTCHA for en optimal oplevelse.
Ofte Stillede Spørgsmål (FAQ)
Spørgsmål: Skal jeg bruge reCAPTCHA v2 eller v3 i min Android-app?
Svar: reCAPTCHA v3 er generelt at foretrække for mobilapps, da den er usynlig for brugeren og giver en bedre brugeroplevelse. reCAPTCHA v2 kræver en synlig interaktion, som kan være mere forstyrrende.
Spørgsmål: Hvorfor skal jeg validere tokenen på min backend?
Svar: Din secret key er følsom. Hvis den blev inkluderet i appen og udgivet, kunne ondsindede aktører misbruge den. Ved at validere på backend sikrer du, at kun din server kan bekræfte tokens med den hemmelige nøgle.
Spørgsmål: Kan jeg bruge reCAPTCHA Enterprise med Android?
Svar: Ja, reCAPTCHA Enterprise er den nyeste og mest avancerede løsning fra Google og kan integreres med Android-apps, ofte via Firebase App Check, for udvidet beskyttelse.
Spørgsmål: Hvad betyder "Site Key" og "Secret Key"?
Svar:Site Key er en offentlig nøgle, der bruges i din app til at identificere din hjemmeside/app over for Google. Secret Key er en privat nøgle, der bruges på din server til at verificere tokens genereret af reCAPTCHA-tjenesten.
Hvis du vil læse andre artikler, der ligner Google reCAPTCHA: Beskyttelse mod bots i Android, kan du besøge kategorien Teknologi.
