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