🧠 Overview: How reCAPTCHA v3 Works
Unlike v2 (which uses a checkbox), reCAPTCHA v3 is invisible and works by:
- Running JavaScript on the frontend to assess user behavior.
- Returning a score (0.0 to 1.0) representing how likely the user is a bot.
- Backend (Spring Boot REST API) verifies the token with Google and takes action based on score.
🧱 Architecture Components
- 🔹 Frontend (Browser)
- Loads Google reCAPTCHA v3 script
- Gets site key from HTML/meta
- Calls
grecaptcha.execute()
to get a token
- Sends the token to the Spring Boot backend
- 🔹 Spring Boot Backend
- Exposes REST API
/validate-recaptcha
- Uses secret key to verify token with Google server
- Receives response:
{ success, score, action, challenge_ts, hostname }
- Takes action (allow, block, log, or flag)
- Validates the token
- Sends score (0.0 = likely bot, 1.0 = human)
🧩 reCAPTCHA v3 Integration Flow Diagram
💻 Sample Spring Boot Integration
✅ Backend Config
application.properties
recaptcha.secret.key=YOUR_SECRET_KEY
recaptcha.verify.url=https://www.google.com/recaptcha/api/siteverify
recaptcha.threshold=0.5
🧩 REST Controller
@RestController
public class RecaptchaController {
@Autowired
private RecaptchaService recaptchaService;
@PostMapping("/validate-recaptcha")
public ResponseEntity<String> validate(@RequestBody RecaptchaRequest request) {
boolean isHuman = recaptchaService.verify(request.getToken(), request.getAction());
if (isHuman) {
return ResponseEntity.ok("User is human");
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Bot detected");
}
}
}
🛠 Service Layer
@Service
public class RecaptchaService {
@Value("${recaptcha.secret.key}")
private String secretKey;
@Value("${recaptcha.verify.url}")
private String verifyUrl;
@Value("${recaptcha.threshold}")
private double threshold;
public boolean verify(String token, String expectedAction) {
RestTemplate restTemplate = new RestTemplate();
String body = "secret=" + secretKey + "&response=" + token;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<String> request = new HttpEntity<>(body, headers);
ResponseEntity<RecaptchaResponse> response = restTemplate
.postForEntity(verifyUrl, request, RecaptchaResponse.class);
RecaptchaResponse recaptcha = response.getBody();
return recaptcha != null && recaptcha.isSuccess()
&& expectedAction.equals(recaptcha.getAction())
&& recaptcha.getScore() >= threshold;
}
}
🔍 RecaptchaResponse
DTO
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class RecaptchaResponse {
private boolean success;
private double score;
private String action;
private String challenge_ts;
private String hostname;
private List<String> errorCodes;
}
⚙️ Internals of reCAPTCHA Score Calculation
- 🎯 What reCAPTCHA Looks At:
- Mouse movement, click/touch behavior
- Time taken to interact
- Cookies/session context
- Known patterns of bot behavior
- Google assigns a risk score (0.0–1.0):
>= 0.7
: likely human
0.3 – 0.7
: suspicious (grey area)
< 0.3
: likely bot
✅ Best Practices
Area |
Best Practice |
Frontend |
Use meaningful action names (e.g., login , signup ) |
Backend |
Always validate token server-side |
Security |
Don’t trust score blindly; combine with login throttling or IP checks |
Monitoring |
Log low-score cases for auditing and improvement |
Quota |
Monitor API usage via Google Cloud Console |
📊 Real-world Decisioning Based on Score
Score |
Action |
≥ 0.7 |
Allow user through |
0.4 – 0.7 |
Show CAPTCHA challenge or OTP |
< 0.4 |
Block or flag as bot |
🧾 Summary
- reCAPTCHA v3 provides risk scores instead of challenges.
- Your frontend generates a token, backend verifies with Google, and makes decisions based on score.
- Integration with Spring Boot is simple using a REST controller and service.
- Monitor score trends and API quota to handle traffic intelligently.
Related