Created
December 8, 2025 19:55
-
-
Save CerealKiller97/ffece8f256f60192cd1feac471268333 to your computer and use it in GitHub Desktop.
RecaptchaService Go Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package recaptcha | |
| var ErrResponseEmpty = errors.New("response is an empty string") | |
| const siteVerifyURL = "https://www.google.com/recaptcha/api/siteverify" | |
| type ( | |
| V3Response struct { | |
| ChallengeTS time.Time `json:"challenge_ts"` | |
| Hostname string `json:"hostname"` | |
| ErrorCodes []string `json:"error-codes"` | |
| Success bool `json:"success"` | |
| } | |
| Interface interface { | |
| Verify(ctx context.Context, response string, remoteIP string) (V3Response, error) | |
| } | |
| Service struct { | |
| logger zerolog.Logger | |
| client *http.Client | |
| secret string | |
| } | |
| ) | |
| func New(secret string, logger zerolog.Logger) *Service { | |
| return &Service{ | |
| logger: logger, | |
| secret: secret, | |
| client: &http.Client{}, | |
| } | |
| } | |
| var _ Interface = &Service{} | |
| func (s Service) Verify(ctx context.Context, response string, remoteIP string) (V3Response, error) { | |
| if response == "" { | |
| return V3Response{}, ErrResponseEmpty | |
| } | |
| form := url.Values{ | |
| "secret": {s.secret}, | |
| "response": {response}, | |
| } | |
| if len(remoteIP) > 0 { | |
| form.Set("remoteip", remoteIP) | |
| } | |
| req, err := http.NewRequestWithContext(ctx, http.MethodPost, siteVerifyURL, strings.NewReader(form.Encode())) | |
| if err != nil { | |
| return V3Response{}, fmt.Errorf("failed to create reCAPTCHA V3 request: %w", err) | |
| } | |
| req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |
| resp, err := s.client.Do(req) //nolint:bodyclose | |
| if err != nil { | |
| return V3Response{}, fmt.Errorf("failed to perform reCAPTCHA V3 request: %w", err) | |
| } | |
| defer func(Body io.ReadCloser) { | |
| if err = Body.Close(); err != nil { | |
| s.logger.Err(err).Msg("Error while closing response") | |
| } | |
| }(resp.Body) | |
| var r V3Response | |
| if err = json.NewDecoder(resp.Body).Decode(&r); err != nil { | |
| return V3Response{}, err | |
| } | |
| return r, nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment