Playing Next Lesson In
seconds

Transcript

  1. Now it's pretty typical for login forms to have a little checkbox right down here that says something like remember me,

  2. that informs the application whenever you have that checked that you want it to remember your logged in session for a long duration. Sessions within AdonisJS have a default lifespan

  3. of about two hours. We can verify that within our application by jumping into our config folder and into our session file. If we scroll down a little bit here, we'll see age is set to two hours.

  4. So from our last point of activity with an application, it will expire the session two hours after that point in time. So it's two hours of straight inactivity,

  5. then it will expire out the session. And that's for sessions as a whole, not just your authenticated user. So if you're storing information within a session, it will apply to that as well. The remember me feature allows us

  6. to expand authentication state beyond this two hours. And to enable it, if we jump back into our browser and dive into the session guard authentication,

  7. documentation, we're gonna need to create a new migration. So we can give this here a copy directly from the documentation, jump into our terminal, give our server a stop, clear that out and paste this migration,

  8. create call for ACLI into our terminal and give it a run. Let's go ahead and boot our server back up while we're here, close that out. And now we need to define these columns

  9. as the columns for this remember me tokens table. So we'll give that a copy, tie our browser back away, dive into our database folder, migrations,

  10. and into our new create remember me tokens table migration. Give everything inside of the create table here a highlight and paste in what we've copied directly from the documentation.

  11. To give a quick overview of what we have, we have our default increments ID column right here, which will serve as a primary key for this table. Then we have a tokenable ID that's unsigned,

  12. meaning that it can't be negative. And it's going to reference the user's ID. So if you placed your users anywhere else besides a user's table and you have their primary key column called anything other than ID,

  13. you'll wanna swap that out accordingly. And this will cascade on delete. So if we were to delete that user, these remember me tokens would automatically clear out for them as well. Then we have a hash.

  14. This is used to verify that this remember me token is valid for the current user that we're working with. And then we have the created at and updated at timestamps, as well as an expires at timestamp

  15. that contains what time and day the actual remember me token expires. So let's give that a save. We should have our down right here as well. That will just drop the table, which is a okay.

  16. So actually let's dive back into our terminal one more time, give our server one more stop and let's run our migration. Although we have that defined. So node ace migration run. Okay, cool.

  17. So we'll clear that out and we can run npm run dev to boot our server back. Slide that back away. And now we're done with our migrations and our database folder as well. So we'll clear that out and we're done with our set. And the next thing that we need to do

  18. is scroll up to our user model. Within this user model, we're going to want to define a static property. So static called remember me tokens.

  19. And we're gonna want to set the value of this to db remember me tokens provider. And we can import that from AdonisJS auth. From this, we're gonna wanna call a method

  20. called for model and provide in our user model. This gives AdonisJS's auth package the ability to create remember me tokens for us

  21. on our behalf with our user model. Okay, next we need to configure our remember me behavior. So we'll dive down into our config and into our auth file here.

  22. So within our web session guard, you'll see that we have used remember me token set to false. Well, we're now enabling that. So we're gonna wanna switch that to true. And we're also gonna wanna define

  23. how long we want to remember me token to last. So how long we want it to keep a user authenticated. So we can do that with remember me tokens age. And let's say maybe two years for that.

  24. The values for these dates are pretty forgiving. So you could do two Y for years, or you could do two years spelling it out and it will understand it accordingly. Okay, so with that, we should now have

  25. our remember me behavior fully configured and set up and ready to go. So now we just need to add it into our login form and account for it accordingly within our login method. So let's hide our config away,

  26. scroll back down to our login form and right above our login button, let's go ahead and add in a label class flex item center, maybe a gap of two.

  27. We'll have our input type equals checkbox name is remember me. And then we'll do a span here for our actual remember me label text.

  28. Okay, let's give that a save. Next, we're gonna need to account for this new body property within our auth validator for our login. So let's dive back to our validators auth and specifically for our login validator.

  29. Let's add in our is remember me field. And there's a form helper specific type called accepted,

  30. specifically meant to receive in checkbox based values directly from form inputs. So we can call that and then we can make it optional

  31. so that it can be checked or unchecked and still be valid. And so this accepted here, we'll just normalize the various input values

  32. that checkboxes can send up with like on, yes, one, true, so on and so forth. Okay, so now let's scroll up to our login controller because now we have an additional field

  33. for is remember me being passed in. And if we take a look at our login validator, we'll see exactly what that's being provided as. So it's either true or it's undefined, which is a falsy value.

  34. So we can take this and provide it directly into our login method, which accepts in a remember flag as the second argument. So let's put is remember me right there.

  35. And now if this is true, it will create a remember me token and assign that to the user's cookies. It will then use that cookie to track the user's login state across multiple sessions.

  36. As AdonisJS cycles through our expired sessions and that recreates a new one for us, it will take that remember me token and just kind of use it to persist the authenticated state

  37. across those various sessions that it creates, allowing us to have a long lived authenticated session despite an actual sessions lifetime being two hours of inactivity.

  38. So let's give that a save. And if we did everything correctly, we should now be able to jump back into our browser. There is our remember me checkbox. Let's do [email protected]. Put in the accurate password here,

  39. check out remember me box and log in. Well, it looks like this errored out. So let's see, you cannot use user model for verifying remember me tokens. Make sure to assign token provider to the model.

  40. So this portion right here makes me think we might've gotten something wrong when we added that token provider into our user model. So let's drive back into our text editor,

  41. go into our user model, static remember me tokens, DB remember me tokens provider for user model, remember me tokens, there we go. Give that a save. And let's give that one more try.

  42. So let's go back to our login, [email protected], enter in their valid password, check remember me, log in. Okay, cool. So now it did actually work.

  43. Now that we have everything spelled correctly. Furthermore, we can dive into PG admin. Let's scroll up to our Adonis 6 database and let's give it a refresh. Scroll back down.

  44. And we should now have this remember me tokens table. Let's give that a right click, view edit data. We can just do all rows 'cause it should just be one value here. And there we go. So there is a remember me token

  45. for our user with an ID of seven, which is our [email protected] user. Here's the hash that we're using to match a particular session to a user, created at, updated at, and here's when that token will expire.

  46. So we are authenticated until 2026, unless we were to come into here and lock out. So while we're logged out, let's go ahead and make sure that it works okay without that being checked.

  47. So [email protected], password, leave remember me unchecked here, hit log in, and cool. We're still A-okay there as well.

Remembering A User's Authenticated Session

@tomgobich
Published by
@tomgobich
In This Lesson

We'll learn how we can use AdonisJS' Remember Me Tokens feature to allow a user to specify they'd like their authentication state to be remembered for a long time across sessions.

You can use the below command to create your remember me tokens migration.

node ace make:migration remember_me_tokens
Copied!

Then, use the below to define your migration

import { BaseSchema } from '@adonisjs/lucid/schema'

export default class extends BaseSchema {
  protected tableName = 'remember_me_tokens'

  async up() {
    this.schema.createTable(this.tableName, (table) => {
      table.increments()
      table
        .integer('tokenable_id')
        .notNullable()
        .unsigned()
        .references('id')
        .inTable('users')
        .onDelete('CASCADE')

      table.string('hash').notNullable().unique()
      table.timestamp('created_at').notNullable()
      table.timestamp('updated_at').notNullable()
      table.timestamp('expires_at').notNullable()
    })
  }

  async down() {
    this.schema.dropTable(this.tableName)
  }
}
Copied!

You can also grab this from the documentation as well.

Join the Discussion 2 comments

Create a free account to join in on the discussion
  1. This episode is such a mind blow.

    I have rolled out custom JWT with refresh and access tokens for an Express backend, and it took me 2 weeks (+ so many corrections through its lifetime) to do something that you have done in Adonis in less than 7 minutes.

    Absolutely insane

    1
    1. Responding to vladimir-laskin
      @tomgobich

      Happy to hear you enjoyed, Vladimir!! JWT & refresh tokens can definitely be complicated to implement, for sure! 😊

      0