Creating an Authenticated User in Strapi
So, let's take a look at how to create users with an authenticated role and then how to essentially, in inverted commas, log them in and see whether they can access the endpoint that I've just enabled in the previous video for only authenticated users.
Now, I did mention that User is a built-in content type. So if I go to Content Manager, you will see that we have our own content type, but I also have the built-in user content type, which means that I can create a new user. So let's actually add the new user, which is going to be Steve, [email protected] and let's add a password. So that's going to be test1234.
And I get to change two more things: whether they are confirmed—so I'm going to confirm them—and whether they are blocked or not. And of course, I'm not going to create them as being blocked. So I'm just going to hit save. That's a very nice user management screen, by the way. And notice that it automatically added the authenticated role to Steve. So that's great.
Authenticating with the Local Provider
But now, how do I prove to Strapi that Steve logged in, and how can I then make a request as Steve and then see this particular endpoint /api/films/:id?
So Strapi allows us to do authentication, and it has quite a few options for you if you want to build authentication in Strapi. In this course, what we're going to be using is the so-called local authentication, which is 100% baked into the core of Strapi.
So how do we do that? Well, in order for us to do that, we need to grab a JSON Web Token. And the way we grab that JSON Web Token—and I'm going to talk to you about what that is in just a moment—is by querying or by accessing /api/auth/local against the Strapi instance running on localhost:1337.
Very important to notice that I am executing this as an HTTP POST method, which means that I also need to send a payload. And the payload that I'm sending is in a JSON format, and you need to pass two properties: one is an identifier and the other one is, of course, the password. Now, for the identifier, you have a little bit of flexibility. You could either pass the actual email or you could just pass the username that you have specified. Both requests will work. So let me hit send.
Receiving and Understanding the JWT
And what we get back is user information, right? So, information about the user with the local auth provider. User is confirmed, so this is great. And we also get what is called a JWT, a JSON Web Token, or a "jot". So let me copy this and let's talk about what this is.
So JSON Web Tokens are predominantly used in token-based authentication models, and it's very, very popular with modern front-end frameworks. So if you work with React or Angular or Svelte or Vue and you did some authentication, it's very likely that you've used some token-based authentication by using a jot. So let's explore what this jot token is and how it looks like.
And I'm going to go to this website called jwt.io. Now, if you're brand new to JSON Web Tokens, I highly recommend that you click this button here that says "Learn more about the JSON Web Tokens", and then you're going to be taken to a page where you can learn more about these. If you're familiar with them, well, I'm just going to paste my token in here and walk you through very briefly what this is.
Deconstructing a JSON Web Token
So a JSON Web Token is made up of three distinctive parts, each separated by a dot. So you see here it's actually color-coded. We get the red section here and then a dot. So the first section, this red section, is the so-called the Header of the JSON Web Token. And the header basically contains the algorithm that was used for creating the token and the token type, which as you can see is set to JWT. So this is the encryption algorithm, so SHA256 is a symmetric algorithm that created this JSON Web Token for us.
Then the purple section, which is the second sort of middle section between the two dots, is what we would call the Payload. That is the data that is contained in the JSON Web Token. And in this case, the only data that we have is the ID of the user, which is id: 1. And we get two more extra fields. The first one is iat, which is "issued at", and that is an epoch timestamp, but if you hover your mouse over that, you can see that I issued that a couple of minutes ago. And exp is, of course, the expiration time. So when is this token going to expire? And by default, it's set to one month.
And then the last section is a so-called verification signature, which basically takes the header, the payload, your secret, and if you have those encoded with this same symmetric algorithm that you used, you should be able to verify the signature. Now, of course, because I don't know what the secret is, it's going to have an invalid signature, but that's beside the point.
Using the JWT as a Bearer Token
So with these JSON Web Tokens, what happens is that you need to attach the token as part of your outgoing HTTP request. So in our case, we want to access a resource which we said is only for authenticated people. So what that endpoint is going to essentially expect from us is the JSON Web Token to be sent as part of the HTTP request.
When it comes to these tokens, you have to send them using the Authorization header, followed with a keyword of Bearer, followed by a space, followed by the JSON Web Token. So let's actually put this together now, and I'm going to go back to Insomnia. So let me just make sure I copied this. Go back to this endpoint. Remember, grabbing just one film is not possible because I'm not providing authentication at all. And because I've set this up in Strapi so that an authenticated role must be used to query this endpoint, I must now add authentication. Now, in Insomnia, I can click Auth, I can click Bearer Token, and just paste the token in, making sure that this header is enabled. If I now hit send, look at that, I do get the data back.
Now, if you're curious how this would work outside of Insomnia, I could generate some client-side code, maybe let's take a look at shell and curl. So you see that I'm passing in an additional header, which is the Authorization header, spelled with a Z. I then have the keyword Bearer followed by a space, followed by the actual JSON Web Token.
And because this endpoint is expecting that token, it verifies the token, and because it knows that that token is valid, it will return us the data. Changing anything in this token—so I'm just removing this 'e' from the beginning—will automatically invalidate the signature for the token, and it's just not going to work. So at all times, you need to make sure that you pass the right token or you attach the right token to the request.
Summary and Next Steps with Next.js
And basically, this is how you use token-based authentication in Strapi. Right? So you first need to log in your user using the /api/auth/local endpoint. You get a JSON Web Token, and for any subsequent requests, you need to attach that JSON Web Token in order for you to see the data.
Now, of course, we're going to replicate this in Next.js. Of course, we have a login mechanism. That login mechanism is going to return a JSON Web Token. We're going to store that JSON Web Token in a cookie, and then for every request that we make to Strapi, it will attach that token, should it exist in the browser as a cookie. If it doesn't, of course, we are not going to return any data to the user.