Passport’s local strategy is a Node.js module that allows you to implement a username/password
authentication mechanism. Along with it, we need other modules as dependency as follow
Run>> npm install
Step 1: Configuring Passport
To create the Passport configuration file, we have to create config folder in the root and create a new file named passport.js and express.js. In the root folder, we have server.js or usually, we called it as app.js. Add the following code in server.js
Step 2: Register the Passport middleware
We required the Passport module and need to register the Passport middleware in your Express application and add the following code in config/express.js. The registered two middleware: the
- passport.initialize() middleware, which is responsible for bootstrapping the Passport module, and the
- passport.session() middleware, which is using the Express session to keep track of your user’s session.
The passport module is installed and configure, now we need to install at least one strategy for authentication, here we are using local strategy. For local strategy we need “passport-local” as dependency >> npm install –save passport-local
Step 3: Configure the local strategy
We need to configure the local strategy, we will keep the each strategy separately in folder strategies in the config folder. To use local strategy we need to install npm package called “passport-local”. Add the local strategy code in config/strategies/local.js
For local strategy, we need above highlight code module. We register the strategy using the passport.use() method, which uses an instance of the LocalStrategy object. Notice how the LocalStrategy constructor takes a callback function as an argument. It will later call this callback when trying to authenticate a user.
The callback function accepts three arguments—username , password , and a done callback—which will be called when the authentication process is over. Inside the callback function, you will use the User Mongoose model to find a user with that username and try to authenticate it. In the event of an error, you will pass the error object to the done callback. When the user is authenticated, you will call the done callback with the user Mongoose object.
Step 4: Passport will handle users serialization/deserialization
Now we will create passport.js in the config folder, the passport will handle users serialization. When a user is authenticated, Passport will save its _id property to the session. Later on, when the user object is needed, Passport will use the _id property to grab the user object from the database through deserializing. Add the following code config/passport.js
Here along with serialization, we are doing two important task
- Loading or including local strategy configuration file.
- Notice how we used the field options argument to make sure Mongoose doesn’t fetch the user’s password and salt properties.
Step 5: Adapting the User model
In the User Model, we have to define the UserSchema, adding some pre middleware, and adding some new instance methods. To do so, go to your app/models/user.js or user.server.model.js file, and add the following code
First, you added four fields to your UserSchema object: a salt property, which you’ll use to hash your password; a provider property, which will indicate the strategy used to register the user; a providerId property, which will indicate the user identifier for the authentication strategy; and a providerData property, which you’ll later use to store the user object retrieved from OAuth providers.
Activity done in User models
- We define user schema.
- Pre-save middleware to handle the hashing of user passwords.
- Create two instance methods: a hashPassword() instance method, which is used to hash a
password string by utilizing Node.js, crypto module; and an authenticate() instance method, which accepts a string argument, hashes it, and compares it to the current user’s hashed password.
- findUniqueUsername() static method, which is used to find an available unique
username for new users
Step 5: Add authentication views
We need to add the user signup and signin view page, add code for app/views/signup.ejs in views.
Adding code for view for signin.ejs. app/views/signin.ejs
Step 6: Modifying the Users controller
To alter the Users controller, go to your app/controllers/users.server.controller.js file, and
change its content as follows:
Here we are displaying various error message while signup and login, and also creating a new user. The signup() method uses your User model to create new users. As you can see, it first creates a user object from the HTTP request body. Then, try saving it to MongoDB. If an error occurs, the signup() method will use the getErrorMessage() method to provide the user with an appropriate error message. The getErrorMessage() method is a private method that returns a unified error message from a Mongoose error object. There are two possible errors here:
- MongoDB indexing error handled using the error code
- Mongoose validation error handled using the err.errors object.
The signout() method is also simple and uses the req.logout() method, which is provided by the Passport module to invalidate the authenticated session.
Step 7: Displaying flash error messages
When an authentication process is failing, it is common to redirect the request back to the signup or sign-in pages. This is done here when an error occurs, but how can your user tell what exactly went wrong? The problem is that when redirecting to another page, you cannot pass variables to that page. The solution is to use some sort of mechanism to pass temporary messages between requests. Fortunately, that mechanism already exists in the form of a node module named Connect-Flash .
The Connect-Flash module is a node module that allows you to store temporary messages in an area of the session object called flash . Messages stored on the flash object will be cleared once they are presented to the user. This architecture makes the Connect-Flash module perfect for transferring messages before redirecting the request to another page.
Configuring Connect-Flash module
We have to configure the express.js file to use the flash module, we have to use require a method to include flash module and app.use() to register to our application. To do so, make the following changes in your config/express.js file:
Just to show the code, as we have already added to the code in step 2 in config/express.js file.
Using Connect-Flash module
Once installed, the Connect-Flash module exposes the req.flash() method, which allows you to create and retrieve flash messages. To understand it better, let’s observe the changes you’ve made to your Users controller. To understan it better at step 6, we have code renderSignup() and renderSignin() methods, which are responsible for rendering the sign-in and signup pages:
These flash code we already added in our Step 6, Modifying the Users controller. The messages variable uses req.flash() to read the messages written to the flash. Now if you go over the signup() method, you’ll notice the following line of code:
This is how error messages are written to the flash, again using the req.flash() method. After you learned how to use the Connect-Flash module, you might have noticed that we’re lacking a signin() method. This is because Passport provides you with an authentication method, which you can use directly in your routing definition.
Step 8: Adding routing code
Once you have your model, controller, and views configured, all that is left to do is define the user’s
routes. Add the following code in app/routes/users.server.routes.js
Most of the code can be self explanatory, we have to note special on POST request made to the /signin path using the passport.authenticate() method. When the passport.authenticate() method is executed, it will try to authenticate the user request using the strategy defined by its first argument. In this case, it will try to authenticate the request using the local strategy. The second parameter this method accepts is an options object, which contains three properties:
- successRedirect: This property tells Passport where to redirect the request once it successfully authenticated the user.
- failureRedirect: This property tells Passport where to redirect the request once it failed to authenticate the user
- failureFlash: This property tells Passport whether or not to use flash messages
Add the second routing code in app/routes/index.server.routes.js
We also have to add code in app/controllers/index.server.controller.js
Step 9: Adding view code for index, app/views/index.ejs
Step 10: Add the following code of configuration, we can add this code from starting of view, routes code.
Add code in config/env/development.js