Hey everyone, this is Sebastian, Product Manager here at 8base. Today, we're going to be walking through how you can use AWS Cognito as an authentication provider when working with a backend workspace. Let's jump right into it.
To kick off this tutorial, there are a few prerequisites that you're going to need. One is a 8base workspace, backend workspace, that is at least on the developer plan. That will give you the ability to integrate third-party auth providers. The second is an AWS account. There's a lot of documentation online to set up both of those resources. However, I will put some links in the video description so that you can jump to it. You can reference those yourself.
To kick things off, I am going to go into my AWS management console and then go find Cognito in there in the console. Once I go to Cognito, what I'm going to have to do is create a new user pool. I'm going to Manage User Pools, Create Pool, and give it a name. I am just going to call this "8base Cognito Auth Provider." You can call it whatever you want. Then we're going to click on Review the defaults. When it comes to the defaults, pretty much everything is good to go. Yeah. We can just go through that and click Create Pool.
With the user pool created, we're going to scroll down in its general settings to the App Clients section and click Add an App Client. Once there, click Add App Client. Now, we're going to give it a name. I'm just going to use the name "Supertasks Backend," because that's the name of the 8base workspace that I'll be utilizing, so "Supertasks Backend."
Then, I'm going to go down and also check off the "Enable username password based authentication flow." Super important. We'll enable that as well. That's all we need to do. Now we can create the app client. Cool. Now we have the app client ID, which we are going to need in a little bit.
However, first we're going to go to our domain. We are going to set up a domain. So let's go to Domain Name, and it's going to give us an input here that we can set up our domain on. You can use custom domains if you want to. Hopefully, we'll cover that in a future tutorial. Right now though, we're just going to allow... And we are going to use a Amazon Cognito domain. I'm just going to say this is "supertasks-auth." I'm going to check the availability. It's available. Perfect. Then I'm going to save that change. Cool. That's set up. Awesome.
Now, we get over to your App Client Settings, and there's a few things that we're going to want to specify. First off, we're going to say that we're using a Cognito user pool, and we're going to specify the callback URL as https://localhost:3000. Whatever callback you're going to want your authentication flow to use, you're going to have to use that one. However, if you're in development, this is likely a local host port that you could be using. However, make sure that you change it per your setup [inaudible 00:03:15]. And if you wanted to, you could also specify a sign out URL. However, we're not going to do that in this tutorial.
Now, what we are going to do is check "Implicit grant," and then make sure that our Auth Scopes or OAuth Scopes include email, OpenID, as well as the AWS Cognito sign in user admin. Once all those are set up, we can save those changes. And believe it or not, most of the work is done at this point. We're just going to go through and do some testing of it.
What we're going to do now is pop back over to 8base, where we're going to configure the auth profile on the 8base side. However, there are a few details that we need from here first. The first one is that if we go to our general settings, we can get our pool ID. I'm going to grab that pool ID right here, and I am just going to go into my Supertasks Backend, and go into my App Services, Authentication, and add a new auth profile. I'm just going to paste it in here. Don't save anything. I'm literally using this as a notepad right now.
The second thing that we're going to want is the region in which we created the resource. So this is "us-east-1." So I'm just going to type that in here as well. Actually, it's kind of in there in the ID, so I'm just going to copy it. The next thing that we are going to need is to create a link or provide the OpenID URL. What I'm going to do is, I have the anatomy of that URL in here. I'll also paste it in the video description. However, it's "cognito-idp." You put in the region. I'm just going to snag that region that we had copied in here right there. Cool. And then the pool ID. I'm going to drop that in right there.
Now I'm going to copy that whole thing, switch over to here—OpenID, because we're using the OpenID provider—and drop in that provider URL. I'm going to name this "Cognito Auth Provider." Call it whatever you'd like. I'm going to say it's open to all so anyone can sign up for our application. If you wanted to not enable that, you could use other options. We're not going to worry about any roles for right now. Or you know what, let's just say that they would get a user role. Perfect, so we can see that it works. And add profile. Cool.
Now, we actually have everything set up both on the AWS side or the Cognito side as well as the 8base side. Now what we're going to do is, call it a dry run of making sure that everything works together, and we're going to do it in a clever way. Here, we are back in our AWS console, and we can scroll down, or we can go to our app client settings, scroll down, and you see it says here "Launch Hosted UI". This is actually going to launch the login page that is provided from our auth provider, which is Cognito. This is completely separate from 8base.
I'm going to sign up, and I'm going to say my username is sebscholl, my email is firstname.lastname@example.org. Now you guys know how to contact me. And then I'm going to say that my password is something I'm not going to tell you. Cool. I run all those, I click Sign Up. Now it's asking me to verify my account. Let me go get my verification code from my device, one second. And boom. It is 103... I'm not telling the rest. Confirm my account.
It looks like it broke, but it actually didn't. What just happened there after successfully verifying my email address or authenticating is it actually did a callback back to our callback URL. You can see that it redirected us back to localhost:3000. And then as a fragment inside of the URL, it actually gave us the ID token and all the other auth information. I'm going to copy this, and I'm actually going to drag it over here to my GraphQL client, because we're going to now interface with the 8base, our workspace API. What I'm going to do is I'm going to paste this in here and parse out from it the ID token, which would probably... I'm sure there's a better way to do this, but I'm just going to take the long way to school this morning. Cool. Access token there. Awesome. It is this string. Perfect.
We have our ID token. And remember that that's a bearer token on our API. I am just going to get a notes... Actually, rich text. Let me just pull up a rich text document, which is... There we go. New Document, and pop that in there. Cool. Now I'm going to go grab the workspace API. If I go into my settings, I can find that endpoint URL right here, and I'm going to drop the endpoint into there. Awesome. It's successfully loaded our API, or our schema.
I'm going to go into the headers here. And remember that authentication or authorization happens through bearer tokens with the 8base API, so we're going to say "Authorization," "Bearer." I'm going to go and grab that bearer token once again. Save that. Awesome.
Now what we're going to do... We were able to create that user in Cognito, so now that user has a saved password and email address in the Cognito system. However, now we need to actually create the user record in 8base so that we have that user in the application database. And the way we're going to do that is with a mutation called SignUpWithToken. UserSignUpWithToken, I believe that's the name of it. I'm going to do a mutation here, and we're going to pass through that mutation a authentication profile ID. I'm going to say AID, which is an ID type, and it's mandatory, as well as we're going to pass in the email of the user, which is going to be a string, which is mandatory.
And here, what we're going to do is... Let me see really quickly. I'm going to have some notes here off-screen that I am going to pull in. Awesome. Yeah, it's a userSignUpWithToken, so "userSignUpWithToken." Inside there, there we're going to give it a "authProfileId." Yeah, ID, cool. Then we can drop in the variable, as well as then the user whose... We're going to give it the email address of "email." Awesome. Then in response, we're just going to ask for the email back.
I don't know why there's no schema available. However, we're going to run this and see if it works. Essentially, what it's doing is that we're passing it that token, it's going to verify that token. Once it sees that that token is valid, it's going to create the user and then return our response, and it's going to sign them up via the auth profile ID, which we need to supply.
I'm going to go grab... We need to set our variables. I'm going to go now to App Services, Authentication. Here's my authentication profiles. I have the ID right here. I'm going to put that in as a variable "aid," and I'm going to put it in parentheses for the string. Then email, which I do know off the top of my head, which is sebscholl... I always forget to put the parentheses, email@example.com. Cool. All right, let's run it and see what happens.
"This token is not from your user pool." Interesting. Maybe I copied something weird in that. I've done that before. Let's look here really quickly. It was actually a weird error. Essentially what it was is I have a CICD set up in this workspace, and I was in this specific environment here called multitenant. So when I copied my API endpoint, I actually got the wrong API endpoint. I wanted to come to my home page and use the API endpoint here, which actually has multitenant appended to it, so it is a different URL. I think we're going to probably make an update in the product, so that's clear for future reference.
However, I do need to write out this mutation one more time. It's going to be easier though, because I can actually use introspection. So the ID, the email, which is a string. Then we open those brackets into the User Sign Up With Token. Awesome. In there, I'm just going to open that up, and it's auth profile ID which takes the AID, and it is the user which has an email. Of course, if you're doing this programmatically, you can pass any other information to the user object, like their first name, last name, birthday, whatever you want to do. It can all be in there.
In response, we want the email back as well, as well as actually, let's say that we want the roles back, because we want to make sure that they actually got the user role. And so items, and we want the name of the role. Awesome. Cool. Now we're going to paste that. We're going to have to go get the auth profile ID one more time. Not a problem. Grab that. In here, we're going to say AID equals that value. Cool. And the email is firstname.lastname@example.org. All right. 3, 2, 1, boom.
I don't have permission? Let's see why not. Oh, no wonder. The user doesn't have permission to read the roles. So we're going to drop that. As you can see, we can see it in the path here. All right. This is going smooth. So there we don't go again. A user already exists with that email. I already used it.
We are going to do this one last way. As you can see, we are so close. We are going to go and delete this user from 8base. Awesome. We're going to run it again.
We have successfully, by hook or by crook, signed up the user. However, the important parts of this tutorial are obviously the establishing the settings all in Cognito of making it work, and then setting up the auth profile. All these little steps were afterwards, we're actually just testing it out to make sure everything runs. However, you'll be handling this programmatically, so for comic relief, I'm just going to leave all this in the video anyway.
All right, I hope that you found this helpful in figuring out how to set up Cognito with 8base. Just as like a little reiteration of what some of the documentation says, 8base is not an authentication provider in the sense that we don't store passwords in our database. We do have 8base authentication, which is actually Cognito under the hood.
However, if you're going to be building a production application, really encourage you to go set up your own auth provider such as Cognito, Auth0, Okta. There's a lot of them out there, but any that are OpenID compliant will work with 8base. The reason for this is because then you won't be metered on the number of users that you have. A user will just be treated as a database record. So if you have a plan that has a million records or 10 million records for your database in 8base... You can have that many users if you have no other records, but you get how it works. Meanwhile, then you have full flexibility for establishing any type of authentication flow that you want with the auth provider that you choose.
Happy developing, and see you in future videos.