/ Middleware

Setup Google Authentication on a Proxy in 5 minutes

During your application development journey, you will need to implement authentication. It's common to use sign-on providers like Google, Facebook, Slack, or Twitter; users enjoy the familiarity and you save time by not building complex authentication systems. There are a couple ways that you might use a sign-on provider:

  • Full Authentication: Managing user sign-ups and sign-ons for your application. The account provider will forward you a hash containing information like the users' name and email. You would then decode this identifying information to create a user within your application.
  • Restricted Access: If you are creating an internal tool or have portions of your application that should be gated, you can limit access. For example: We only want people belonging to our Google Apps for Work domain to access our administrative panel.

This article will look into the second facet: using an account provider to restrict site access. We'll examine the different ways that you can white-list bits of your applications using Rails, NodeJS, and plain JavaScript. After that, we'll show you how you can use a proxy to create a restrictive gate. The best part? It takes roughly 5 minutes and code alteration isn't required.

Omniauth

If you're writing your application in Rails, you may have already considered using Omniauth for authentication - for good reason! Omniauth is a library that allows you to thread many different sign-on providers into your application. There's methods for Facebook, Twitter, Slack, Google, even LDAP. With the gem installed users who want to authenticate are directed at /auth/:provider, where :provider is whichever one you've specified.

After that, it's a matter of organizing the callback. You'd typically add a line to routes.rb:

get '/auth/:provider/callback', to: 'sessions#create'

And then to your SessionController, where the hash that you've received is decoded by your omniauth.auth key and turned into details about your user:

class SessionsController < ApplicationController
  def create
    @user = User.find_or_create_from_auth_hash(auth_hash)
    self.current_user = @user
    redirect_to '/'
  end

  protected

  def auth_hash
    request.env['omniauth.auth']
  end
end

While Omniauth is useful for both cases - authentication and access restricting - you'll need to have a solid understanding of Rails in order to incorporate it securely. If you're simply looking to restrict access to an admin or analytics dashboard, that's substantial effort!

Passport

In the world of Node.JS, PassportJS fills the same niche as Omniauth... Except with many more authentication strategies. Install the package via npm, then build your function:

app.post('/login',
  passport.authenticate('google-oauth'),
  function(req, res) {
    // If this function gets called, authentication was successful.
    // `req.user` contains the authenticated user.
    res.redirect('/' + req.user.username);
  });

To activate, call passport.authenticate to your selected provider, then specify where they should be sent. Like Omniauth, you'll need to get deeper into the code, building your authentication system around Passport.

OAuth 2.0: Straight from the Provider

While both Passport and Omniauth provide robust solutions to sign-on, major providers have their own methods using OAuth 2.0. Google, for example, allows you to include their Google Platform Library.

You simply add the script:

<script src="https://apis.google.com/js/platform.js" async defer></script>

Then put your ClientID in a meta-element:

<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">

... And then create functions to handle sign in:

function onSignIn(googleUser) {
  var profile = googleUser.getBasicProfile();
  console.log('ID: ' + profile.getId()); 
  console.log('Name: ' + profile.getName());
  console.log('Image URL: ' + profile.getImageUrl());
  console.log('Email: ' + profile.getEmail()); 
}

Powerful, functional, but the same dilemma as Omniauth and Passport. Let's look at something less code-y. Or, how we can use a proxy to do this in 5 minutes.

Fly Auth

Each example we've seen so far is better suited for replacing a custom made, full-featured user authentication system. What if we simply want to restrict hostname access to those within a Google Org? Using Fly, Google Authentication is applied at the proxy before requests are sent off to whichever hostname we've chosen to secure. The major benefit is that proxy-based authentication is code agnostic; you can gate anything behind the hostname.

Configuration starts with adding a site. We're wanting to create a secured administrative panel, so we'll add a site for admin.coolapp.com. New site setup asks you to choose your backend type: Heroku, GitHub Pages, Kubernetes, Containers -- any configuration will work. Next, we need to verify that you own the admin.coolapp.com hostname.

Ye' old picture of hostnames

A hostname is verified by adding a DNS record. Once verified, head over to the Middleware tab within the site. Find Google Authentication and click Configure. We have some information to fill in!

  • Google Apps Domain: Your organizations domain: fly.io or coolapp.com-- whichever is tied to your Google Org.

  • Whitelist of Allowed Emails: If you'd like to add other Google accounts that exist outside of your organization, you can specify them here.

  • Google App Client ID & Google App Client Secret: Retrieved from the Google Developer Console.

The developer console can be found here: Google Developer Console. We'll want to head here to generate credentials.

A GDC screen. Pretty standard.

While generating, we want to specify the redirect URL that speaks through Fly to our domain: https://admin.coolapp.com/__fly/auth/google/callback. This is a standard callback URL; you'd simply swap admin.coolapp.com for the domain of your choosing. For example: https://any.example.com/__fly/auth/google/callback.

Next, click save and retrieve your ClientID and Client Secret.

Put your Google Authentication into this form. It's fairly lovely.

With credentials in tow, head back to Fly. We want to add them to their respective fields, add our domain and any additional Google emails to the whitelist, then click Enable. With Google Authentication added to our Request Flow, it may look something like this. Notice that it's on the pre-request band -- it invokes before the request arrives at the server.

A flow-chart of requests

Voila! We can see that our traffic route is now secured with Google Authentication. Any attempts to access admin.coolapp.com will require an active account from your Google Org. Unwelcome logins will be safely denied and routed into the abyss.

Google says WHO ARE YOU?

Summary

Using a major sign-on provider through a first-party library - or a tool like Omniauth or Passport - can save you time when you're constructing your initial authentication system. If you've already applied an authentication system or simply want to restrict a new portion of your application, try doing so from the proxy. With a proxy, you can secure any backend, language or framework that the domain points to -- and you don't have to muck with any code.

Fly is an Application Delivery Network. It's a smart-proxy and global a load balancer all rolled into one. It's free to sign up, as are your first 2,000,000 requests and 100GB of transfer every month.

Kellen Evan Person

@thegoodroot

Kellen Evan Person

A polite, forest-dwelling Canadian who enjoys coding and writing. He's spent near two decades building web applications and strives to keep development fun and light-hearted.

North Vancouver, Canada