Creating Access Tokens Part 1: AdonisJS
In this lesson, 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.
- Author
- Tom Gobich
- Published
- Apr 25
- Duration
- 10m 19s

Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Get the Code
Download or explore the source code for this lesson on GitHub
Transcript
Creating Access Tokens Part 1: AdonisJS
-
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.
-
Introduction
-
API Authentication
-
2.0Configuring Access Token Auth on top of Session AuthLesson 2.010m 50s
-
2.1Separation of API & Web Auth Guard ConcernsLesson 2.19m 17s
-
2.2Defining Access Token Abilities & DTOLesson 2.29m 54s
-
2.3Creating Access Tokens Part 1: AdonisJSLesson 2.310m 19s
-
2.4Creating Access Tokens Part 2: Inertia/VueLesson 2.412m 44s
-
2.5Opaque Access Tokens (OAT) vs JSON Web Tokens (JWT)Lesson 2.53m 57s
-
Listing an Organization's Access TokensLesson 2.68m 3s
-
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!