Ready to get started?

Join Adocasts Plus for $8/mo, or sign into an existing Adocasts Plus account, to get access to all of our lessons.

robot mascot smiling

Restricting Login Attempts with Rate Limiting

In This Lesson

We'll add AdonisJS' Rate Limiter to our web login action to restrict the number of times a user can attempt to login to our application with invalid credentials.

Created by
@tomgobich
Published

Join the Discussion 6 comments

Create a free account to join in on the discussion
  1. @aaron-ford

    I am getting an error from the SettingsShell.vue, I am guessing it is from changing the tailwind config. I have gone back over the last lesson and this one, and I haven't found any differences in the change I made vs what you made.

    [postcss]

    /plotmycourse/inertia/components/SettingsShell.vue?vue&type=style&index=0&scoped=9c23e674&lang.css:3:5: The text-primary class does not exist. If text-primary is a custom class, make sure it is defined within a @layer directive.

    1
    1. Responding to aaron-ford
      @tomgobich

      Hi Aaron! I had run into this as well while preparing for the Web API series, but my thinking at the time was that it was something that had changed during the package updates when updating to Inertia 2. Perhaps not though, if you're seeing it here. Terribly sorry about that! I'll have to circle back and add a note in lesson 12.3.

      If you go into your inertia/css/app.css file and add the below, does that resolve this issue for you? My understanding was that TailwindCSS should be able to discern the default config when omitted, but it appears @apply might not work so well with that.

      @config "../../tailwind.config.js";
      Copied!
      0
      1. Responding to tomgobich
        @aaron-ford

        That fixed it, thanks!

        1
        1. Responding to aaron-ford
          @tomgobich

          Great to hear, and thanks for confirming Aaron! I'll get that note added into lesson 12.3! Again, terribly sorry about that!

          0
  2. @himito
    // handler.ts
    
      async handle(error: unknown, ctx: HttpContext) {
        if (error instanceof errors.E_TOO_MANY_REQUESTS) {
          ctx.session.flashAll()
          ctx.session.flashErrors({
            E_TOO_MANY_REQUESTS: 'Too many login attempts. Please try again later.',
          })
          return ctx.response.redirect().back()
        }
    
        return super.handle(error, ctx)
      }
    Copied!
    // auth.ts
    
    router.post('/login', [LoginController, 'store']).use(throttle).as('login.store')
    Copied!

    Hi,

    Only for curiosity, what would be the advantages of your approach wrt to the above ? It's for resetting per user ?


    Thank you in advance !

    Cheers,
    Jaime

    1
    1. Responding to himito
      @tomgobich

      Hi Jaime! Not quite sure which repository this code comes from, but the exception handler there is merely changing how the E_TOO_MANY_REQUESTS exception is returned and displayed to the user. It won't change anything with the rate limiting behavior itself.

      The traditional web rate limit exception would print a blank page to the user with the exception message. This intercepts that behavior to instead display the exception message via a flash message.

      async handle(error: unknown, ctx: HttpContext) {
        // if the exception thrown is E_TOO_MANY_REQUESTS (rate limit)
        if (error instanceof errors.E_TOO_MANY_REQUESTS) {
          // flash form input data so it can be repopulated into any forms
          ctx.session.flashAll()
      
          // flash the rate limit exception so the user knows what happened
          ctx.session.flashErrors({
            E_TOO_MANY_REQUESTS: 'Too many login attempts. Please try again later.',
          })
      
          // redirect the user back to where they were
          return ctx.response.redirect().back()
        }
      
        // if the exception thrown wasn't E_TOO_MANY_REQUESTS, 
        // proceed as usual with the standard exception handling.
        return super.handle(error, ctx)
      }
      Copied!
      • app
      • exceptions
      • handler.ts

      Hope this helps!!

      0