Search code examples
vue.jssymfonyvalidationrecaptchaapi-platform.com

Verify reCaptcha Token API Platform


I am hoping some of you can give me the best practice on how to verify my reCaptcha token on the server.

I have a Symfony 6 app with API Platform. I have defined some entities as API Resources, so I can POST data. On the front end I am using Vue with axios to POST to the specific end points.

I would like to verify the reCaptcha token, before the data from my form is posted, and came up with the below 3 options (Not really sure if any of these are the correct way to go about this)

  1. Create a separate end point for reCaptcha, that I post data to and depending on the response run axios post request for form or not.

  2. Create an up mapped property on the entities I want to use reCaptcha with and set a custom validator on this that validates if the response on token is success. I can then send the reCaptcha token as part of the post request.

  3. Create an event listener for PRE_POST and somehow validate there???

I'm not sure if I'm on the right track with any of the above, the documentation I have been able to find is pretty non existent.

I would really appreciate being pointed in the right direction, or perhaps an example of best practice on this with my current set up?


Solution

  • For those of you coming across this with the same issue I solved it with the following steps: (I would still like to know from someone with more knowledge, if this would be considered best practice or if there is a better way).

    1. Added an unmapped field (No #[ORM\Column annotation) to the Symfony entity I was posting data to, called reCaptchaToken. Added the set method to my denormalizationContext group.

    2. Created ReCaptchaConstraint (class extending Constraint) and set validatedBy method to ReCaptchaConstraintValidator::class

    3. Created ReCaptchaConstraintValidator (class extending ConstraintValidator), added HttpClientInterface to constructor and in validate method posted to recaptcha API (details of this end point can be found in reCaptcha documentation) to validate token and score. If validation failed or score too low, added violation.

    4. Back in Symfony entity, added #[ReCaptchaConstraint] annotation to reCaptchaToken field.

    5. Then from front end, created Vue method:

      validateCaptcha() {
            return new Promise((res) => {
              grecaptcha.ready(() => {
                grecaptcha.execute('YOUR_SITE_KEY', {action:
                      'addContact'}).then((token) => {
                  return res(token);
                })
              })
            })
          }
      

    In .then() method of validateCaptcha() add token to my JSON object and posted to API end point normally.

    Now if there is an issue with my token or score, I will get a validation violation returned from POST.

    Hope this helps someone else struggling.