How to implement Facebook Login with NestJS

elishaking

King Elisha

Posted on August 20, 2020

How to implement Facebook Login with NestJS

NestJS is a relatively new framework that has been growing in popularity for many good reasons. It has full support for TypeScript and it combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming) to enable developers build scalable and coherent server-side applications.

Requirements

Below is a list of software required to follow along as we setup facebook login with NestJS:

  • Facebook account
  • NodeJS
  • Yarn

Project Setup

NestJS comes with a convenient CLI that can be used to scaffold a new NestJS project.

Install the CLI globally using the following command:



npm i -g @nestjs/cli


Enter fullscreen mode Exit fullscreen mode

Scaffold a new project using the command:



nest new <project-name>


Enter fullscreen mode Exit fullscreen mode

For this project,you use a descriptive name as shown below:



nest new nest-facebook-auth


Enter fullscreen mode Exit fullscreen mode

The CLI will prompt you to choose a package manager between yarn or npm.you be using yarn for this project.

After the setup is complete, you can open the project in your favorite editor and you should have a folder structure like this:

Alt Text

Dependencies

To implement facebook login, we need to add a few dependencies to the project:

  • dotenv
  • passport
  • passport-facebook
  • @nestjs/passport

The dotenv package will be used to load environment variables and passport will be used to manage authentication. Add the packages using the following command:



yarn add dotenv @nestjs/passport passport passport-facebook


Enter fullscreen mode Exit fullscreen mode

To add static typing for passport-facebook, we need to install one more dependency:



yarn add @types/passport-facebook


Enter fullscreen mode Exit fullscreen mode

Create Facebook App

Visit https://developers.facebook.com to create a Facebook app. If you don't have a developer account, click on Get Started at the top right of the screen. After setting up your account, you should see the dialog below:

Alt Text

Click on Create First App and fill in the details for your desired app name and contact info. You can give yours a different name than the one below:

Alt Text

Once your app is created, you should see a dashboard that looks similar to the one below. Click on Set Up Facebook Login.

Alt Text

Select Web and fill in your website's URL (without any paths). Since this is just for testing, our request will be coming from localhost, so enter http://localhost:3000 and click Save.

Just like this:

Alt Text

Get and Save Credentials

Alt Text

To get your app credentials, click on Settings on the left side menu and click on Basic. Copy your App ID and App Secret.

Create a new .env file in the NestJs project's root directory. Store your app credentials as environment variables for security reasons:



APP_ID=<your_app_id>
APP_SECRET=<your_app_secret>


Enter fullscreen mode Exit fullscreen mode

NOTE: make sure you add .env to your .gitignore to prevent it from being added to git. At the bottom of your .gitignore, add the following:



# Environment
.env


Enter fullscreen mode Exit fullscreen mode

Implement Facebook Login

To import the saved environment variables, add the following code to the top (and below other imports) of your main.ts file in the src folder



import * as dotenv from "dotenv";

dotenv.config();


Enter fullscreen mode Exit fullscreen mode

Since we're using passport to implement Facebook Login, we need to create a passport strategy. To do that, create a facebook.strategy.ts file in the src folder and add the code below:



import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Profile, Strategy } from "passport-facebook";

@Injectable()
export class FacebookStrategy extends PassportStrategy(Strategy, "facebook") {
  constructor() {
    super({
      clientID: process.env.APP_ID,
      clientSecret: process.env.APP_SECRET,
      callbackURL: "http://localhost:3000/facebook/redirect",
      scope: "email",
      profileFields: ["emails", "name"],
    });
  }

  async validate(
    accessToken: string,
    refreshToken: string,
    profile: Profile,
    done: (err: any, user: any, info?: any) => void
  ): Promise<any> {
    const { name, emails } = profile;
    const user = {
      email: emails[0].value,
      firstName: name.givenName,
      lastName: name.familyName,
    };
    const payload = {
      user,
      accessToken,
    };

    done(null, payload);
  }
}


Enter fullscreen mode Exit fullscreen mode

The first argument to PassportStrategy is Strategy which comes from passport-facebook. The second argument tells passport the name of the strategy which in our case is facebook.

To be able to use the newly created strategy, we need to include it as a provider in our app module. Open app.module.ts in the src folder and replace it with:



import { Module } from "@nestjs/common";

import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { FacebookStrategy } from "./facebook.strategy";

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, FacebookStrategy],
})
export class AppModule {}


Enter fullscreen mode Exit fullscreen mode

Add login route

Finally, we need to add the API endpoint/route for facebook login. In NestJS, routes are handled by controllers.you implement facebook login in app.controller.ts as follows:



import { Controller, Get, UseGuards, HttpStatus, Req } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { Request } from "express";

import { AppService } from "./app.service";

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get("/facebook")
  @UseGuards(AuthGuard("facebook"))
  async facebookLogin(): Promise<any> {
    return HttpStatus.OK;
  }

  @Get("/facebook/redirect")
  @UseGuards(AuthGuard("facebook"))
  async facebookLoginRedirect(@Req() req: Request): Promise<any> {
    return {
      statusCode: HttpStatus.OK,
      data: req.user,
    };
  }
}


Enter fullscreen mode Exit fullscreen mode

The last two routes are responsible for the entire login flow. The first one initiates facebook login. The second route is where facebook will redirect the user to after a successful login.

Test App

Run in development mode using the following command:



yarn start:dev


Enter fullscreen mode Exit fullscreen mode

Navigate to the facebook endpoint in your browser: http://localhost:3000/facebook. You'll be prompted to log in with facebook as shown below:

Alt Text

After a successful login, you'll be redirected to http://localhost:3000/facebook/redirect and you'll get the response as defined in the facebookLoginRedirect controller. See an example response below:

Alt Text

🎉🎉🎉, you have successfully implemented facebook login. The code for this project can be found on GitHub: https://github.com/elishaking/nestjs-facebook-login

If you encountered any issues, feel free to leave a comment below or reach me @ElishaChibueze.

I love making these articles, so please I'd love to know your suggestion on topics you'll like me to explore.

❤️ the article ?****?**?** I loved making it.

💖 💪 🙅 🚩
elishaking
King Elisha

Posted on August 20, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related