GitHub Authentication16:18 with Andrew Chalkley
In this video we'll integrate GitHub's Passport Strategy in to our application.
You can think of a strategy as a middleware for Passport. 0:00 There's a general process you need to go through when setting it up. 0:04 First, you need to install the Strategy through NPM. 0:08 Second, register your application with the provider. 0:12 In our case, it's Get Up and Facebook. 0:16 This is where you'll get your ID in secret, 0:18 in other words, your application username and password. 0:21 Third, configure your Passport Strategy or 0:25 Passport Middleware with the ideal key and secret. 0:27 Finally, set up the routes for the provider. 0:32 First, let's install the Passport Strategy for GitHub with the NPM Save Flag. 0:36 Once Passport GitHub is installed, we need to head over to GitHub. 0:47 Go to your Account Settings. 0:53 And, on the left-hand side, there's OAuth applications. 0:57 Here you'll see all the applications that use OAuth that you've ever authorized. 1:02 Notice how you can revoke an application's access to your information at 1:08 any time without involving a third party. 1:12 At the top of the page, there is Developer applications. 1:16 Here is where you register your application. 1:20 Enter in the application name here and the URL for the application. 1:24 Generally, you would have multiple OAuth apps, one for development, 1:35 one for staging, and one for production. 1:39 Since this is for development, 1:42 I'm going to add my development URL of localhost3000 here. 1:44 This is generally the homepage of the site. 1:49 Then, the call back URL is the route where your application will handle the return 1:52 call from the OAuth provider containing the profile information. 1:57 Let's use our development URL /auth/github/return, 2:02 submit the form, and 2:11 you find yourself presented with the client ID and client secret. 2:15 We'll use this in a moment, keep your browser window open here. 2:20 Let's go back to our app.js file, and 2:25 just after we require everything we can include passport use. 2:30 Like Express, passport has a use method to use passport specific 2:39 middleware called strategies. 2:44 Just under where we require passport, let's require the GitHub strategy. 2:48 We're using the variable name GitHubStrategy because 3:12 we're using another strategy later on, and we don't want our variables to clash. 3:16 We need to configure our GitHubStrategy. 3:23 In the passport.use method, let's initialize the GitHubStrategy. 3:30 The passport strategy takes two arguments, set of options and a callback. 3:38 The options required are client's ID which is a string, 3:47 a clientSecret, which is a string also, 3:53 and then the callback URL. 3:58 This is the same one from earlier 4:06 Be sure that your URLs are the same one we used when 4:15 setting up our application GitHub. 4:20 For example, if you use 18.104.22.168.1 rather than local host, you'll get an error. 4:24 I've left the clientID and clientSecret blank on purpose. 4:33 You don't want to actually put these values in here for security and 4:38 maintenance reasons. 4:42 Firstly, you don't want to submit sensitive information like this 4:43 into version control. 4:47 You could end up uploading your credentials to a repository, potentially 4:49 exposing the information to others, who could use them to spoof your application. 4:52 Secondly, you don't want your development credentials deployed to staging 4:58 and production. 5:01 You don't want to mix up your development and 5:03 staging uses with your actual user base. 5:05 Also if the developer leaves the company you work for 5:08 even favorably, you want to be able to revoke that development environment 5:11 without affecting your production uses. 5:16 It's just good practice to separate IDs and secrets for all environments. 5:18 iI's save potential future headaches. 5:23 To get around this will use environmental variables. 5:26 We'll use GitHub clients 5:36 ID And 5:40 GITHUB_CLIENT_SECRET, For the secret. 5:46 We can pass them in as arguments or set them before we run the node application. 5:55 I'll show you how to do that shortly. 6:00 The callback function takes an accessToken, a refreshToken, 6:04 a profile JSON object, and a callback, done. 6:14 This is an ideal place to find or create a user document in the database. 6:22 Mongoose has a method called FindOneAndUpdate, 6:27 which takes a filter criteria And updates object. 6:33 Some options, and a call back. 6:42 The mongoose model finds a single entry based on search criteria. 6:47 The search criteria in our case, is the user's email address. 6:56 We can access the email from a list of emails returned by the profile 7:04 object from the OAuth callback. 7:09 We may use different providers OAuth functionality, GitHub and 7:17 Facebook and Twitter for example Is always good when setting up a new 7:22 provider to inspect the profile object. 7:27 So that you're sure that you're getting all the information you expect and 7:30 it's in the correct format. 7:34 If we find the object we should update it with the latest information from 7:39 the social network. 7:43 The display name property on the profile object is the user's name. 7:52 Then the email address and The photo. 8:02 We can get the first image from a set of photos. 8:08 [SOUND] The display name may not be 8:11 available from the OLF provider. 8:15 We can set to be the providers username instead 8:20 You may be asking what if this is the first time the user is using the site 8:30 there is no use a model to find an update. 8:34 What can we do? 8:37 We can use the opt set option that will insert the model if it doesn't exist or 8:39 if it does. 8:44 [SOUND] When it's called on at some point to hand 8:45 control back to passport and eventually back to express so 8:50 it can execute the next piece of middleware Like before, 8:57 when we found a user, we can pass done to the FindOneAndUpdate method. 9:03 If there's an error from the upset process, 9:16 that method will pass in an error to done as the first document. 9:19 If a document is found, it'll be passed as the second argument. 9:24 The second argument passed to the 'didn't call back' by the find one and 9:29 update method, is the user model 9:34 that is added to the request object which will be available for all routes. 9:38 Now depending on an individual's user privacy settings, 9:44 their e-mail addresses may not be available. 9:47 If it's not available. 10:07 We need to pass an error to the done callback. 10:10 Let's create an error saying your 10:18 email privacy settings prevent 10:24 you from Signing into Bookworm. 10:29 Then we can pass this error into the done callback. 10:40 And nothing as the second parameter. 10:47 We'll create our authorization routes in a separate file, 10:56 auth.JS in the routes' directory, in just a minute. 11:00 But before we do that, let's wire up the routes in the app JS file. 11:05 Underneath the index.JS file containing all the get routes for the app, 11:09 let's create an auth route. 11:14 Then we can use this auth route down here next to the other get routes. 11:27 Awesome! 11:40 Now let's create the auth.js file in the routes folder. 11:42 Let's also require express and express.Router at the top of the file. 11:50 Let's also include passport. 11:58 Now we can create our first login route. 12:04 Instead of creating our own rout handler. 12:23 We'll use Passport's authentication handler instead. 12:27 We need to include which strategy we use too, github. 12:36 Then we need to implement the call back URL return. 12:49 But this time we need to include an options object. 13:03 With the failure redirect key. 13:10 This is the path you want to send users if they don't authorize your application or 13:19 there was some other failure. 13:24 Maybe a stand alone login page would present an error to them. 13:27 In this case, we're just sending them back to the home page. 13:32 Finally, we write our own handler with a request and response. 13:39 You can do anything here for example. 13:49 You could log the time the user logs in for analytics and security reasons. 13:52 We can just simply redirect to the profile page. 14:03 Now we have the logging complete. 14:16 We need a walking out route, 14:19 The Passport middleware not only adds the user property to the request objects, 14:38 it also adds a logout method. 14:43 When you call it, it logs the user out. 14:46 Then we can redirect the user to the homepage. 14:53 Don't forget to export the router. 15:06 Before we start our application before to start the MongoDB server. 15:16 Now to start the application with environment variables on a Mac and 15:21 Linux, you can include environment variables immediately proceeding 15:26 the application start command Check the teachers notes on how to do it in Windows. 15:31 Now that the application is running, let's visit it in our web browser. 15:58 Click on Log In. 16:06 With GitHub. 16:08 Authorize the application, and bam, we're signed in 16:10
You need to sign up for Treehouse in order to download course files.Sign up