Current section: OAuth 6 exercises

Intro to Oauth

Loading lesson


00:00 For many applications, authenticating with a third-party service of some kind is pretty much a requirement, whether it be social logins with GitHub, or x.com, or Google, or whatever, or in addition, single sign-on with an enterprise that has their own single sign-on implementation.

00:18 Many of these are built with OpenIDC, OIDC, so OpenConnect, or they have their own implementation of something that you have to integrate with. And these OAuth 2.0-based flows are a little bit complicated.

00:37 You can look into it pretty deeply if you take a look at this blog post, an introduction to OAuth 2.0. It's definitely an introduction. There's a lot to it, so feel free to peruse that to get an idea. But luckily, all of this stuff is kind of baked in with RemixAuth.

00:54 RemixAuth has a couple of Passport JS-inspired strategies for handling these types of flows. So let me show you a graph of what that flow actually looks like, and then we can talk about some of the code examples here really quick. And then I'll set you off on this exercise. So the user is going to say, I want to log in with the provider.

01:13 So we've got that right here, login with GitHub. So they click on that, and our server is going to respond to that. They're not going straight to the provider. They're going to talk to our server first. And our server is going to say, hey, you need to go through the provider to authenticate. And we're going to set a cookie that's

01:30 going to maintain some state to keep track of the user as we're going through this flow. So we'll set that cookie on our site and then send the user over to this provider. That user is going to authenticate with that provider, and then the provider is going to send a redirect back to the user's browser, which will send it right over to our server.

01:50 And so that redirect is going to include a special code that our server can then swap out for what's called an access code. So we can start accessing things on behalf of the user. It's also going to include the state that we initialized in this cookie,

02:08 so we can validate or check the flow and make sure that everything is copacetic. And so we're going to resolve this code into an access token. So we're going to talk to the provider and say, hey, here, I've got this code. Can you give me an access token so I can access this user information?

02:27 The provider's like, oh, yeah, I just barely made that thing. Yeah, here you go. And so from there, we can get an existing connection based on the user's data. So we're going to get that user's data, find out, OK, here's your email, here's your other information, and use that to determine whether we already

02:46 have a connection for the user in our database. And if we don't, then we create a new one. And then we redirect the user back with a cookie that includes, like, if we're going to onboard them, then we're going to include the pre-filled information about the user email and their username

03:03 and maybe their image, stuff like that, all the stuff that came from the provider. And otherwise, if a connection already exists, then we'll just log them in. And that cookie will just be part of our session and all of that. And then the user can proceed from there. So it kind of depends on the situation.

03:20 And we're not actually going to get into this last portion in this exercise, because there are a number of different scenarios that we'll want to deal with. So for us, we're just going to be dealing with this part. Now, underneath all of this stuff is the complex stuff that we're talking about in here,

03:38 and OAuth 2 and everything that goes into that. But yeah, super grateful for RemixAuth that makes all of this pretty straightforward and simple for us. OK, so as far as the way that works, RemixAuth needs a cookie to manage. And so we create our own session storage.

03:56 We're making a special one for RemixAuth just for this so that it doesn't mess with our own authentication session. Now, RemixAuth can actually be used to manage all of your authentication. And you definitely can do that. It even has an authentication strategy for username and password.

04:15 But I find that it's actually easier just to manage that authentication session yourself and then use RemixAuth for doing these complicated flows. So that's why we're making a separate session object for RemixAuth. Then we have in our auth server a authenticator

04:33 that we're going to create with RemixAuth. And we say, hey, RemixAuth, this is what I'm going to stick in your session. This is the type of that thing. And so RemixAuth says, OK, well, every single one of your strategies has to return or somehow resolve down to a user or an object that matches this type, which is quite nice.

04:52 So we get some type safety there. Here we're saying, hey, I want to use this strategy. It's called GitHub. And here is an implementation of authentication with GitHub using OAuth2. And we want to provide our client ID and client secret so that we can talk securely with GitHub APIs and all that.

05:12 And this is where I want you to send the user once they've successfully authenticated. And here is where we take the user's profile from that provider and turn it into the thing that we want that user to look like on our system for whatever it is that we're trying to do.

05:29 So that is creating and initializing our authenticator with the GitHub strategy. And then to authenticate, we have the route that manages this Login button. When you click on that, it's going to come into here and it's going to say, OK, I want to authenticate. And the authenticator is going to say, oh, OK,

05:48 so this request, it doesn't have a code or a state or whatever. So we need to send the user over to GitHub so that we can get that access code. We're also going to set a cookie so that we can track that state as the user's coming off of our site and then needs to come back. We need to have a persistent place to put that. So we manage that in a cookie. All of that happens behind the scenes.

06:07 And this is literally the only line that you have to worry about writing for this part. And then when GitHub sends the user back, we're going to say, hey, authenticator, I want you to authenticate with GitHub. And here's the request. And authenticator is going to look at that request and be like, oh, sweet.

06:24 OK, so now I've got the code in the search params and I've got the state in the search params. So let me validate that as correct. And then we also specify throw on error here so that we tell RemixAuth that we're going to be managing any errors that happen here.

06:42 And we'll take care of that actually in the next exercise. So once that has all been resolved, as a part of what's going on here is we're now talking to the GitHub APIs and saying, here's my code. GitHub says, here's your token. And we say, OK, tell me about the user. And GitHub says, here's information about the user. And we get whatever else we need.

07:00 And before we even proceed past this line, we actually end up calling this to resolve from the profile that we got from the GitHub API down to the specific shape of an object that we need. So the shape of this object, this data, will be what we return from this. And it will be type safe and it will be awesome.

07:19 So that is what you're going to be working on in this exercise. You're also going to be doing stuff with the data model because we need to persist the provider name and the provider ID and associate that to a user, to a connection. A user can have multiple connections, various things like that. So this is going to be a really fun one.

07:39 By the end of it, we're also going to be mocking out this whole flow so that we don't even need an internet connection to be able to do this successfully, which is pretty slick. Makes our tests run faster and all that stuff too. So yeah, we're going to be setting up the RemixAuth library. We're going to complete the entire user flow.

07:59 And you're welcome to create a temporary GitHub auth token and all that, or a client secret and client ID so you can actually test the full flow if you want to. And then we'll mock it out and then we'll make something in the database so that we can start making those types of interactions.

08:17 And yeah, we'll proceed from there. So there's quite a bit for all of this to work. But once you have it working, you can apply it to whatever. So we're using GitHub just because I know that all of you probably have a GitHub. But there are many services that follow this standardization.

08:33 And on top of that, by using RemixAuth and the structure that we have, we can use any of the different RemixAuth strategies, of which there are many. And so you just plug in whichever ones that matter to you, which is, I think, pretty slick. So I think that's everything. Have a really good time with this,

08:52 and we'll see you when you're done.