Logo

dev-resources.site

for different kinds of informations.

Implement reCAPTCHA in htmx + expressjs

Published at
11/6/2024
Categories
htmx
express
javascript
recaptcha
Author
kasir-barati
Categories
4 categories in total
htmx
open
express
open
javascript
open
recaptcha
open
Author
12 person written this
kasir-barati
open
Implement reCAPTCHA in htmx + expressjs

Let's start with the most obvious question, why we need it? because reCAPTCHA is using advance risk analysis techniques to detect frau, thus protecting your websites or mobile app from fraudulent activities and security risks such as:

  • Spam.
  • Abuse.
  • Credential stuffing1.
  • Account takeover (ATO).
  • Automated account creation.
  • Password breach.
  • Leak detection.

Here we wana use Google's reCAPTCHA which I believe is the most popular out there:

  • It has:
    • Mobile app SDKs.
    • Multi-factor authentication (MFA).
  • It interacts with your:
    • Backend.
    • Clients (web pages or mobile applications).

UX -- User journey

So here is how our users probably use our app, well you know how things usually end:

User using our app meme

  1. Client loads the web page.
  2. Client app initializes the reCAPTCHA JS API or mobile SDK.
  3. End user triggers an action protected by reCAPTCHA (e.g. login), the reCAPTCHA JS API or the mobile SDK in the client requests a verdict2 from reCAPTCHA.
  4. Get back an encrypted reCAPTCHA token (save it somewhere since we're gonna need it).
  5. Client sends the aforementioned token to backend.
  6. Backend sends an assessment req to reCAPTCHA + encrypted token.
  7. Backend receives a verdict score from ranging 0 to 1 + a reason code based on this request made to the backend.
  8. Now you can decide to reject the req or process it.

reCAPTCHA workflow
Credits for this image goes to google doc.


In which layers we can add reCAPTCHA?

  • In our websites.
  • In mobile apps.
  • Or in the WAF layer.

How to work with Google's reCAPTCHA

Here is probably the thing that you wanted to know the most.

  1. Create a new project or use an existing one.
  2. Enable the "reCAPTCHA Enterprise API".
  3. Create a new "reCAPTCHA key" there by going to "reCAPTCHA" tab.

    1. Pick a name for the key.
    2. Choose your platform, in my case "Website".
    3. Add your domain name, no port number, or protocol is allowed.

      Tip:

      If you're like me and want to just test it you can write: localhost or 127.0.0.1, or you can add both :).

  4. Add the script tag in the key details page, "Integration" tag to your web app.

    Note:

    It is normal for your client to be able to see your reCAPTCHA key in plain text So do not worry about it. It is not supposed to be a secret ;).

  5. Call the grecaptcha.execute function on whatever action you want to protect. In my case on clicking on "Sign up!" button.

    I do not like to have bots as user :kidding:. Anyway here is a break down on what you need to do:

    1. I created my registration form. It is called register.html and made the most beautiful UI.

      Important:

      The most important part is where I added a hidden input. That's how I am sending the token I got from Google reCAPTCHA service to my backend.

    2. I wrote all the logics that I were not able to implement in htmx in what they call it hypermedia friendly in a separate JS file called register.js and linked it to my html file.

      1. There we have a function called isGoogleRecaptchaReady which is responsible to check whether the Google's lib for reCAPTCHA is loaded. I just promisified it for the sake of syntax.
      2. I realized that there are a couple of ways to modify a request before sending it:

        1. Through: hx-on:htmx:config-request attribute. But as you can see it is designed for simple scenarios and not for cases like our case where we need more room to work (learn more here).
        2. hx-sync which looked it might be able to help me in one way or another but the more I looked at it the more I realized that it was not up to the task. You can have more complex logic in it but it won't wait until it is resolved and then make the forms request (learn more in their doc). So here is what I was trying to do with it but could not.

          I added an hx-click (in fact I tried first onclick but they where not any different). And inside that handler I tried to do the logic that I've implemented in step 3.

        3. I then saw my savior, htmx:confirm event. This was what worked an was able to handle this task.
      3. I defined a listener for htmx:confirm event and inside it:

        1. Made sure that we've intercepted the right event, the one that user is trying to register -- isRegisterForm.
        2. Then made sure Google's lib is ready -- isGoogleRecaptchaReady.
        3. Called Google's API with our site key to get a token for this request: grecaptcha.enterprise.execute.
        4. Then updated our hidden input with the fetched value from Google.

          Caution:

          Here my hidden input did not have any hx-* attribute on it. Thus I did not need to tell htmx anything about me changing the DOM with JS. But if you have please note that:

          If javascript adds content to the DOM that has htmx attributes on it, you need to make sure that this content is initialized with the htmx.process() function.

          Learn more: https://htmx.org/docs/#3rd-party.

        5. Told htmx to send the req: event.detail.issueRequest.

  6. Add reCAPTCHA to your backend:

    1. I have created a utility function called createAssessment, in it we are:

      Caution:

      You need to either send your API key for authentication or can use a simpler approach called ADC which stands for Application Default Credentials. And here I decided to use API keys. But you can definitely go with what suits you're requirements most.

      On a side note, not every API can be called with API keys. But we know for sure that create assessment can be called based on what is written here. And to learn about how you can create a new API key read this doc.

      1. Creating a client -- new RecaptchaEnterpriseServiceClient().
      2. Constructing our request -- projectPath, and request variables.
      3. Sending the req to get a score for the user action -- client.createAssessment.
      4. Performing some verifications before returning the score -- isTokenValid, isTheExpectedAction, and isNumeric.
      5. Lastly we are closing the open connection we've created just a few steps ago (step #1).

        Note:

        Please read the JSDoc I wrote for the client here.

    2. Then I use it to get a score assessment from Google.

    3. And finally I do a quick interpretation of the score and decide whether the action was performed by a human or a bot -- isBot.

Congrats, now you have a fully functional reCAPTCHA implementation in htmx, and your backend does not really mater since their logic is what they should take care of it. But here we used the lovely ExpressJS.


YouTube

Footnotes


You can find me:


  1. Credential stuffing: when the attacker collects stolen account credentials. ↩

  2. Verdict: An opinion/decision made after judging the facts that are given. ↩

recaptcha Article's
30 articles in total
Favicon
How to Solve and Overcome reCAPTCHA Automatically with Puppeteer and Auto Captcha Integration
Favicon
Implement reCAPTCHA in htmx + expressjs
Favicon
Google reCAPTCHA for Vue.js/Nuxt.js : App & Form Spam Shield
Favicon
How to Bypass reCAPTCHA While Web Scraping
Favicon
How to Bypass reCAPTCHA While Web Scraping
Favicon
How to bypass reCAPTCHA V2/V3 using code and another way
Favicon
Add Google ReCaptcha To Laravel Project
Favicon
How to bypass reCAPTCHA
Favicon
Which reCAPTCHA Solver is Best? Best reCAPTCHA Solver 2024
Favicon
# How to Solve reCAPTCHA v2: Solve and Bypass reCAPTCHA v2 Guide
Favicon
How to solver Captcha With Python and NextCaptcha
Favicon
Crawl millions of pages every day with Python
Favicon
reCAPTCHA Auto Solver - Solve reCAPTCHAs Automatically
Favicon
What is reCAPTCHA types and how to solve it?
Favicon
reCAPTCHA v2 Solver, reCAPTCHA v2 Captcha Solving Service
Favicon
Fastest FunCaptcha Solving Service, Top CAPTCHA Solvers in 2024
Favicon
reCAPTCHA v3 Solver, Auto Recognition and Solve reCAPTCHA v3
Favicon
Best reCAPTCHA v3 Captcha Solver, auto reCAPTCHA v3 Solving Service Using API or Extension
Favicon
Captcha Solver Free, Best reCAPTCHA v2/v3, Funcaptcha, Geetest Auto Solver
Favicon
Integrating Nuxt 3 with Recaptcha v3 for Token Handling πŸ€–πŸ”
Favicon
Best reCAPTCHA v2 Captcha Solver, auto reCAPTCHA v2 Solving Service Using API or Extension
Favicon
Google reCAPTCHA Enterprise: Integrate the β€œI’m not a robot” Challenge In Vue.js
Favicon
Recaptcha Auto Solver
Favicon
Laravel 10 Google ReCaptcha V2 Validation
Favicon
EasyCaptchaJS: Simplified reCAPTCHA Integration
Favicon
How to solve google reCaptcha using a captcha solver - Capsolver.com
Favicon
reCaptcha v2 Solver : Captchas Solver
Favicon
Install Google reCaptcha in your React/Next js app.
Favicon
Sending Mail in Laravel and securing it with Google reCAPTCHA
Favicon
Integrate google reCAPTCHA in Android studio

Featured ones: