Configuring PassportFinally! Our application is now set up and ready for us to configure passport (Which we did in the last post, Setting up for Passport). All of the configuration for passport will be done in the config/passport.js file.
Passport with a New User
Because a user needs to signup with you app before they can login, we will start with how to handle authenticating a new user with passport.
First we need to create a LocalStragety, passport uses strategies to authenticate data. On our config/passport.js file we want to load the things we will use on this js file. We will load the passport LocalStrategy and we will also load the model of our user which we created in app/models/user.js.
For right now we can ignore the section for passport sessions. I will cover this a little later and passport does most of the leg work here.
Once we've loaded the files we need, we can configure a new LocalStrategy. Strategies are created by using the passport.use() function.
So we call passport.use() and name this new LocalStrategy 'local signup'. Passport by default uses a username and password we will override this the user name to be the user's email.
Then using the User.findOne() function I want to check through my database to see if this email has been previously saved there (we are checking if this user's email already exists in the database! If it does we want to notify the user).
Passport is able to check the credentials by using a verify callback. The verify callback parses the credentials in the request (the email and password), and then uses them as arguments to check if they are valid.
*Note: As we can see in the function above, there are three return done(). Two of them have null passed through it and one of them does not.
return done(null, false)
return done(null, user)
return done(err) we know that the issue is with the server and not with the authentication process.
The verify callback invokes the done function to let passport know that it has completed the verification process.
If the user is found in the database, then it return:
return done(null, false, req.flash());
The false, indicates to passport that there was a failure in redicretion and sends the user back to the signup page with a message to let them know what the issue was. The req.flash() is the message that you want to send to your user to inform them that they have failed to log in and why. So in this case, they failed to log in because the email they tried to login in is already in the database, meaning they are a returning user, not a new one. So we could pass them a message like: "This email is not available" or "This email is already taken", just something so that the user knows what is going on and doesn't get frustrated.
If the user is not found in the database we want to save their credentials, their email and password as a new User and then send them along to their profile. Thus:
return done(null, newUser)
The newUser, indicates to passport that the authentication was successful and it should redirect to /profile, the secure profile page.
Review of the Passport ProcessSo let's do a quick review of what is happening when we use passport to authenticate.
Steps to the passport process:
- The user inputs their credential (email, password) and tries to sign in this data sets off the POST request which triggers the passport.authenticate() function.
- We send the passport object to get authenticated at config/passport.js through a Passport Strategy which check to see if they are correct.
- The strategy either returns a true (the user is verified) or a false (the user is unverified) and sends this information back to the POST request in the app/routes.js file.
- If the POST request recieves successful(true), the user will be routed to their profile, and if the post request recieves failure(false), the user will be rerouted back to the signin page with a failure message.