This workshop will be retired on August 9, 2021.
Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
In this video we'll integrate GitHub's Passport Strategy in to our application.
Links
Windows Environment Variables Command
SET GITHUB_CLIENT_ID=xxxx & GITHUB_CLIENT_SECRET=xxxx & node bin\www
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 1.7.0.0.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