Authentication , or authentication of user information, is one of the most fundamental features of most Web applications. In this article, I would like to share the method of using passportjs to build Authentication feature for an API server written on NestJS – A fairly popular NodeJS Framework today.
I will build a project from scratch, then I will build two basic user authentication features, with email / password authentication and user authentication with json web token .
I. Project installation
First, assuming a Nodejs environment is available, we instantiate an application called demo-app using the nest-cli tool.
# cai dat cli
npm install -g @nestjs/cli
# khoi tao project
nest new demo-app
Next, we will install the necessary libraries with the following command:
npm install --save @nestjs/passport passport passport-local passport-jwt
npm install --save-dev @types/passport-local @types/passport-jwt
- Passport : The general library in use, which is the foundation of the passport ‘s activity flow.
- passport-local, passport-jwt : Two libraries that serve the two authentication methods we mentioned above. In the passport , each authentication method will be a strategy .
- @nestjs / passport : The nestjs passport utility.
- @types / passport-jwt, @types / passport-local : By default, the 2 strategy libraries of the passport we installed above do not support typescript , these 2 libraries will help fix that.
OK, so the installation is complete, we continue to initialize the auth module, this module will take care of the authentication functions in the application, we continue to use nest-cli :
nest g module auth
nest g controller auth --no-spec
nest g service auth --no-spec
I have created the controller and service that comes with the auth module , for simplicity I have the option of not generating a spec file, and will not build database related functions in this section.
II. Build authentication function with passport-local
1. Definition of functions
The first function we want to build for our application is the Sign in function with email and password , which is extremely basic. We begin by defining “database” and api, we have a list that contains the user information (user) and a Post API – This API will receive a Body of two values are email and password are sent to From the Client , the main logical part will be to check the value that the user sends to the database and return the user information an exception if the information submitted is incorrect (This is the logical part we will use the passport ).
For the sake of simplicity, we will define the list of users as static data:
Next we define the Dto and Sign In API :
2. Build authentication feature with passport-local strategy
OK, after defining the “database” and the API , we write logic to validate the data that the user submits with the passport , as I said above, the passport provides an important flow of authentication logic , for each Authentication features, passport build for us a separate strategy , this makes it easy to manage and extend the application, assuming the application needs to build more authentication methods, we just need to expand by More strategy .
In this problem, we will create a strategy like this:
After adding some lines of code, I will re-explain a little bit of the working steps of the authentication feature through the diagram as follows:
- The local strategy reads the request body and checks the data in it, by default it will check the username and password fields, here because we conduct the authentication with two fields, email / password, so I reset the settings in the function. Constructor of strategy .
- If the format of the submitted data does not matter, then check the authenticity of the data with the database , logic will be done in the validate method (note the correct method name when declaring strategy ). , the detailed logic we will have to write by ourselves, here we have used the validateUserAndPassword method in AuthService , this function we will add to the auth.service.ts created above.
- After the test results are available, the information returned in the validate method will be added to the request ‘s information, from which we can read the user’s credentials by calling request.user , this will done automatically by passport-local .
- If the submitted data is not in the correct format or the result returned from the validate function does not exist, the client will get an exception .
According to the workflow above, we just need to write the method to validate the information signed in with the existing data into the AuthService , like so
3. Add AuthGuard to API Sign In
After we have written the authentication logic , we assemble them into the auth module , we first need to add the Passport Module and LocalStrategy to the AuthModule setup. Next, we specify the implementation of the authentication logic with the API inside the controller . NestJS provides the concept of Guards ( https://docs.nestjs.com/guards ) – translated as protection – with the role of allowing us to build logic to decide when a request should be executed – If you have worked with expressjs , the concept is almost identical to middleware . The @nestjs / passport library we installed initially has built-in, allowing us to use the passport strategy as a Guard of the API . All you need to do is add a little bit of code inside auth.controller.ts
I explain a little bit, AuthGuard is a NestJS Guard pre-written by the @nestjs / passport library allowing integration of passport strategy into the API . By default, AuthGuard will call the LocalStrategy we defined and added to the AuthModule earlier.
Done, we have built the email / password authentication method. However, if using only one authentication method as above in the application, then there is a problem like this, for each subsequent API of the application, if authentication is needed, the client always remembers to send email and password , and must be the Post method. So this authentication method should be used only for an API that is when the user signs in . As for the other APIs , we need to use a more flexible authentication method, such as using jsonwebtoken , we will continue to build this authentication method by passport in part 2 of this article. write.