基于Matt's Script Archive FormMail.cgi的reCAPTCHA V2验证失败求助
Fixing reCAPTCHA V2 Verification in Perl CGI Script
Let's dig into why your reCAPTCHA V2 verification keeps failing. The biggest issue with your current code is that you're using a regex to match the JSON response—and JSON doesn't guarantee consistent whitespace or key order. For example, "success": true might show up as "success":true or come after other keys in the response, breaking your regex check entirely.
Here's how to fix this properly using reliable JSON parsing:
Step 1: Use a JSON Parser
Perl includes core modules like JSON::PP (no extra installation needed for Perl 5.14+) that let you safely parse API responses instead of relying on flaky regex matches.
Step 2: Updated Verification Code
Replace your check_captcha subroutine with this version:
sub check_captcha { my $ua = LWP::UserAgent->new(); # Ensure HTTPS requests work (install LWP::Protocol::https if you get connection errors) $ua->ssl_opts( verify_hostname => 1 ); my $result = $ua->post( 'https://www.google.com/recaptcha/api/siteverify', { secret => 'MyPrivateKey', # Confirm this is your reCAPTCHA V2 secret key (not V1!) remoteip => $ENV{'REMOTE_ADDR'}, response => $Form{'g-recaptcha-response'} } ); # First handle HTTP request failures (e.g., network issues) if (!$result->is_success) { &error('captcha_connection_failed'); return; } # Parse the JSON response safely my $json = JSON::PP->new(); my $response_data; eval { $response_data = $json->decode($result->content); }; if ($@) { &error('captcha_invalid_response'); return; } # Check the success flag the right way if ($response_data->{success}) { return; # Verification passed } else { # Optional: Log error codes for debugging (e.g., invalid secret, missing response) my $error_codes = join(', ', @{$response_data->{'error-codes'} || []}); warn "reCAPTCHA failed with errors: $error_codes"; &error('captcha_failed'); } }
Additional Troubleshooting Tips
- Double-check your secret key: Make sure you're using the reCAPTCHA V2 secret key (not the old V1 private key, and not the public site key).
- Verify the
g-recaptcha-responsevalue: Add a debug line likewarn "Captcha response: " . $Form{'g-recaptcha-response'};to confirm the frontend is sending this parameter correctly to your CGI script. - HTTPS support: If you get errors connecting to the siteverify URL, install the
LWP::Protocol::httpsmodule via CPAN to enable HTTPS for LWP. - Use error codes: The API returns specific error codes when verification fails (like
invalid-input-secretormissing-input-response). The code above logs these, which will help you pinpoint exactly what's going wrong.
内容的提问来源于stack exchange,提问作者Lee Mac
相关产品推荐
相关产品推荐

