# Social Authentication

# Introduction

Along with the standard JWT authentication, ExpressWebJs also helps you implement social authentication with OAuth providers like Facebook, Google, Twitter, LinkedIn, and Microsoft out of the box.

# Configuration

To get started with social authentication, move over to social authentication configuration which is located at Config/Socials.ts file to configure your preferred driver.

import { env } from "expresswebcorets/lib/Env";

export default {
  /*
    |--------------------------------------------------------------------------
    | Social Connection Drivers
    |--------------------------------------------------------------------------
    |
    | ExpressWebJs social API supports so many authentication services,
    | giving you the flexibility to use single sign-on using an OAuth provider such as
    | Facebook,Twitter,LinkedIn,Slack,Google, Microsoft, Github, and GitLab.
    | 
    | You can set up social connection drivers like so:
    | social_connections: ["google","facebook","twitter","linkedIn"]
    |
    */

  social_connections: ["google"], // ["facebook","twitter","linkedIn"]

  /*
    |--------------------------------------------------------------------------
    | Social connections
    |--------------------------------------------------------------------------
    |
    | Here you can configure your social connection information 
    | for any of the drivers you choose.
    |
    */

  connections: {
    facebook: {
      driver: "facebook",
      clientID: env("FACEBOOK_CLIENT_ID"),
      clientSecret: env("FACEBOOK_CLIENT_SECRET"),
      callbackURL: "http://localhost:5000/api/facebook/secrets",
    },
    google: {
      driver: "google",
      clientID: env("GOOGLE_CLIENT_ID"),
      clientSecret: env("GOOGLE_CLIENT_SECRET"),
      callbackURL: "http://localhost:5000/api/auth/google/callback",
    },
    twitter: {
      driver: "twitter",
      consumerKey: env("TWITTER_CONSUMER_KEY"),
      consumerSecret: env("TWITTER_CONSUMER_SECRET"),
      callbackURL: "http://localhost:5000/api/auth/twitter/callback",
    },
    linkedin: {
      driver: "linkedin",
      clientID: env("LINKEDIN_CLIENT_ID"),
      clientSecret: env("LINKEDIN_CLIENT_SECRET"),
      callbackURL: "http://localhost:5000/api/auth/linkedin/callback",
      scope: ["r_emailaddress", "r_liteprofile"],
    },
    microsoft: {
      driver: "microsoft",
      clientID: env("MICROSOFT_CLIENT_ID"),
      clientSecret: env("MICROSOFT_CLIENT_SECRET"),
      callbackURL: "http://localhost:5000/api/auth/microsoft/callback",
      scope: ["user.read"],
    },
  },
};
Copied!

# Drivers

Name of the driver to use. It must always be one of the following available drivers.

  • facebook
  • twitter
  • google
  • linkedin
  • microsoft

# clientID

The OAuth provider's client id. This must be securely kept inside the environment variables.

# clientSecret

The OAuth provider's client secret. This must be securely kept inside the environment variables.

# callbackURL

The callback URL to handle the post redirect response from the OAuth provider. You must register the same URL with the OAuth provider as well.

# Authenticate requests

After the setup process, you can now access your Social object inside your route handlers using the Social.use() method and specifying your driver e.g: facebook, twitter etc which redirects the user to the OAuth provider website.

import Route from "Elucidate/Route/manager";
import { Request, Response, NextFunction } from "Elucidate/HttpContext";
import Social from "Elucidate/Social";

Route.get("/auth/google", Social.use("google", { scope: ["email", "profile"] }));
Copied!

# Handling the callback request

Once the user decides to approve or rejects the login request, the OAuth provider will redirect the user back to the callbackUrl where you can now access the user with Social.authenticate() method.

import Route from "Elucidate/Route/manager";
import { Request, Response } from "Config/Http";
import Social from "Elucidate/Social";

Route.get("/auth/google", Social.use("google", { scope: ["email", "profile"] }));

Route.get("/google/callback", function (req: Request, res: Response) {
  Social.authenticate("google", req, res)
    .then((google: { user: object }) => {
      let user = google.profile;
      // Process user data
      console.log(user);
    })
    .catch((err: any) => {
      //Handle error is any
      console.log(err);
    });

  res.redirect("/api/");
});
Copied!

You can also decide to handle it in a controller.

import Route from "Elucidate/Route/manager";
import { Request, Response } from "Config/Http";
import Social from "Elucidate/Social";

Route.get("/auth/google", Social.use("google"));

// Handle callback in GoogleController
Route.get("/google/callback", "GoogleController@googleCallback");
Copied!

GoogleController

import Social from "Elucidate/Social";
import { Request, Response } from "Config/Http";

export class GoogleController {
  public async googleCallback(req: Request, res: Response) => {
     const google: { user: object } = (await Social.authenticate("google", req, res)) as { user: object };
    console.log(google);

    res.redirect("/api/");
  };
}
Copied!