Playing Next Lesson In
Transcript
-
Now with all of these set up out of the way, let's go ahead and start by implementing our access tokens within our web application, getting the ability to create them first.
-
So we'll dig into our organization settings, and this is where we're going to end up housing it in a new card at the bottom of this page.
-
We're gonna save the view portion of this for last though, in case you're not interested in that whatsoever, you can just skip it and continue on to the next lesson. And we'll start with the AdonisJS side of everything.
-
So let's go ahead and dig into our terminal here because we're going to want to create a new action. So node ace make action, this is a custom ACLI command that we have a package installed for
-
that will create a new action class for us. We're gonna want this to be within our settings action directory,
-
and we'll call it store API access token. We're gonna enter to create that, and let's dig in now to our text editor.
-
We'll start by jumping into our app validators in our settings validator, and we can go ahead and export const API access token
-
validator, set that equal to vine compile. And let's go ahead and plop a vine object within there to house our actual fields. And we're gonna need two of those.
-
We'll call one our name, the name is just going to be a unique name that we can assign to the access token itself. So maybe we're creating an access token for a specific application
-
that's going to interface using our API. We could call the access token via that application's name, for example. So this will be a vine string,
-
and we'll set a max length of that to 100 characters as defined by the databases column. In addition to the name, we're also going to want to accept an array of permissions.
-
So we can set this to a vine array, and we'll want to limit these permissions to those that we defined in the last lesson as our token actions. We define that as an enum,
-
so we can do vine dot enum, and provide that enum directly into there. And that will only allow these permissions to house a value defined within this particular enum,
-
which if we command click into it, is read, create, update, and delete. Okay, so we can give that a save. We're now done with our validator, and let's go and jump into that action that we created next.
-
Those are housed within actions, and we plop that within settings and call it store API access token. If you're unfamiliar with actions, they're similar to services,
-
except they're a little bit more pointed in that they are for one specific operation within that service. So for example, you might have an access token service
-
that would then have a store method inside of it, but here we have a single class specifically for this. And then the handle method is what's going to execute the operation.
-
So it just provides a little bit of a different approach to organizing our operational logic. This action is going to need to accept in the organization of type organization model,
-
as well as that validated data that we just defined. So we can infer that from the type of, and we call that our API access token validator.
-
We can extract both of those out of our handle methods object as organization and data. Then to actually create the access token,
-
we're going to want to use the access tokens property that we added during the configuration step directly on our organization model.
-
So we can return, import our organization model, and reach for that access token database provider property, which provides us a couple of options. We can get all of the access tokens,
-
which we will use here in a bit to actually query all of our organization's access tokens. We can create an access token, which is what we want. You can also see that we can delete, find a specific one,
-
invalidate an access token, and verify the validity of an access token. We're after create here for this particular action. And the first argument to this is going to be our organization.
-
So we can pass the organization directly into there. And you'll see that the second one is going to be our abilities array. So we can pass as our second argument,
-
our data dot permissions to satisfy that. Lastly, we need to specify our name from our validator into this create a token as well.
-
That's where the third option set comes in, where we can specify a name as a string, and when that token expires, which we've discussed previously.
-
You can set this either per token during creation, as we see in the options here, or we can set this on the access tokens database provider directly on our organization model
-
when omitted from both places, which is the approach that we're going to take here, the token will never expire, which for us is going to give our users the ability to manually expire their token
-
anytime that they no longer want it to be applicable. So all we wanna do here is specify the name, and we can reach for our data name to provide that into the created token.
-
And that's all that we need there. All right, let's put it all together now by digging into our settings controller for our organization. So that's going to be within our controllers settings, and then we'll have one
-
called an organization controller within there. Now, as a heads up, we do have two organization controllers. We have one within the settings directory and one outside of the settings directory. The one within the settings directory
-
is for operations specific to the settings section for our organization. And then the one outside is for everything else for the organization,
-
giving us a way to separate those concerns a little bit. So we want the one within the settings folder, and we'll just scroll on down here to the bottom of this controller and add a new method in.
-
So this will be async, and we'll call it store access token. From our HTTP context, we're going to want our request, response, the organization, which we're providing ourselves
-
via that organization middleware. And that middleware is also providing us a can object as well, which describes the ability of the currently authenticated user
-
within the specific organization they're in. That too is populated by the organization middleware. So we'll want all of those from our HTTP context.
-
Our first step is to validate our data. So we'll await, request, validate using, and plop our API access token validator into there.
-
Then we want to create our token. So we'll await, call our store API access token action, and its handle method,
-
passing the organization and that validated data into it. Now, although this is an inertia application and inertia requires a valid inertia response
-
in order for it to be used, we're actually going to submit this using Axios instead of going through the inertia flow. So rather than redirecting back after we're done in this controller method,
-
we'll instead go ahead and just directly return a JSON response. We can either return that directly or we can specify it manually by reaching through a response and there's a JSON method within there.
-
We want to add our access token as a property on there. And we can cast that to the DTO that we created in the last lesson as access token DTO,
-
and then plop our token within there. Now, the last thing for this controller method is that we want to perform some form of authorization check to make sure that the authenticated user
-
can create an access token, which for this, we're going to limit to our administrators within the organization. We haven't done any prep work for this yet,
-
so we don't have it directly available on our can yet, but we're going to want to follow something similar like we have up here for our remove users and add it onto our organization property as an operation.
-
So within our actions, we have our abilities. We have our get abilities, which is the can response as a whole, this object right here.
-
And then it has our organization property on it, which calls our get organization abilities action. This get abilities is here for expandability. If we needed some additional operations to check for
-
in addition to our organization, we could add those as a new resource item in a similar approach to how we have our organizations here, giving this room to expand as needed.
-
And then within our get organization actions, we have each of these different abilities, which we're just checking against the role to see whether or not we want to allow it. So we're going to want a new one to add a static method on here,
-
can manage access tokens, accept the user's role ID for the organization in as the argument. And then as stated, we're going to limit this to our administrator.
-
So we'll just check and see whether or not the role for the user is an administrator. So we've added this on as a specific method off of our get organization abilities that's directly callable,
-
but we'll also want to add it into the handle methods return, which is what our can object reads from. So we'll do manage access tokens there,
-
and just call our can manage access tokens and pass that role ID in. We're getting a red squiggly because we have this implementing
-
our organization abilities type. So we also need to add it into this type. So manage access tokens, and that is a Boolean property. Okay, all good there.
-
And that will directly cascade to our can via our get abilities now. So we can go ahead and close our abilities folder out, jump back into our organization settings controller,
-
and we can make use of this as the first check within this controller method by doing if not can organization manage access tokens.
-
And then if the user cannot manage the access tokens, we can go ahead and throw a new forbidden exception saying something like you are not authorized
-
to create access tokens. And that's all that we need for this controller method. So let's next jump into our routes, and this will be within our web routes.
-
We want to scroll on down to our settings section for our organization, and let's add in a new line there
-
with router.post/settings/organization/access-tokens.
-
We'll have this read from our settings, organization controller,
-
and its store access token method. We can also give it a name as settings organization access-tokens.store.
-
As another heads up, the way that I have these routes, you could very well group these up in additional groupings. For example, all of these settings organization ones
-
start with settings organization. This could very well be a group. My personal preference is to have them all on a flat list. I feel that makes it easier to scan. So do feel free to organize those to your liking.
-
All right, so that's it for the AdonisJS side of creating our access tokens. The next portion here, we're going to go into the inertia view application and create the actual card and form.
-
So if you're not interested in that at all, and you're just here for the API stuff, feel free to skip it. I will put the actual code that we're going to add to this project in that lessons body.
-
So feel free to just copy the code snippets, apply it to your application, and continue on your merry way.
Creating Access Tokens Part 1: AdonisJS
We'll add a route to the settings portion of our application allowing the user to create an opaque access token (OAT), with the desired permissions, for the active organization.

- Created by
- @tomgobich
- Published
Join the Discussion 0 comments
Be the first to comment!