James Morris James Morris - 27 days ago 12
Javascript Question

Restrict login to specific domain using Node Passport with Google Auth

I am implementing Google Auth on an internal service at work. It is a JS client heavy application with a Node backend. I am choosing to use the Node module Passport.js with the passport-google-oauth strategy.

I have successfully got it working but one thing is still confusing me. I want to ensure my application allows only company employees to login. I understand that you can restrict the login by domain using a parameter called "hd", according to the official documentation.

Firstly, where do you send that parameter in the context of Passport.js? I just don't understand where in the code that is put. If it helps, I have been mostly following the example passport-google-oauth provides.

Secondly, in theory how does this all work? Is it on the Google side, where they reject anyone trying to access the app with a domain outside of our company. Or is it on my side, that I need to check what domain the user is logging in from?

Answer

Here's an example:

// first make sure you have access to the proper scope on your login route
app.get("/login", passport.authenticate("google", {
    scope: ["profile", "email"]
});

// set up your Google OAuth strategy elsewhere...
passport.use(new GoogleStrategy({
    clientID: "something",
    clientSecret: "something",
    callbackURL: "/something"
}, function(token, refreshToken, profile, done){
    if(profile._json.hd === "yourdomain.com"){
        // find or create user in database, etc
        User.find({ id: profile.id }).done(done);
    }else{
        // fail        
        done(new Error("Invalid host domain"));
    }
});

And for good measure here's a full variable dump of what the "profile" variable looks like.

{ 
    provider: 'google',
    id: '12345678987654321',
    displayName: 'Don Draper',
    name: { familyName: 'Whitman', givenName: 'Richard' },
    emails: [ { value: 'don@scdp.com' } ],
    _raw: 'a bunch of stringified json',
    _json: { 
        id: '123456789',
        email: 'something@something.com',
        verified_email: true,
        name: 'Don Draper',
        given_name: 'Don',
        family_name: 'Draper',
        link: 'https://plus.google.com/123456789',
        picture: 'https://lh3.googleusercontent.com/XdUIqdMkCWA/AAAAAAAAAAI/AAAAAAAAAAA/123456789/photo.jpg',
        gender: 'male',
        locale: 'en',
        hd: 'yourdomain.com' 
    } 
}

Here are some detailed tutorials that should answer your question about the theory behind all of this. You'll want some combination of the two.

  1. Local authentication and basic setup
  2. Google authentication
Comments