adding google sign-in to your webapp - using the js library
Tags: authentication, webdev
Published: 2019-07-23 22:16:37

---
title: adding google sign-in to your webapp - using the js library
published: true
description: how to use the `gapi` library to configure Sign-In and then actually sign-in the user, as well as a few snippets for handling some common user scenarios.
tags: authentication, webdev
canonical_url: https://www.intricatecloud.io/2019/07/adding-google-sign-in-to-your-webapp-doing-it-in-js/
series: adding google sign-in to your webapp
cover_image: https://s3.amazonaws.com/intricatecloud-content/wp-content/uploads/2019/07/23045337/using-the-js-library.png
---

In the first part of the series, we decided to use the [Google Sign-In for websites library](https://developers.google.com/identity/sign-in/web/) to allow you to show some info about the user using javascript. We used the default Google Sign-In workflow with their default button.

In this part, we'll be going over how to use the `gapi` library to configure Sign-In and then actually sign-in the user, as well as a few snippets for handling some common user scenarios.

## create your own sign in button

1. Load the api.js library instead of platform.js :shrug: (not sure why they're different)

Change `https://apis.google.com/js/platform.js` to `https://apis.google.com/js/api.js?onload=onLibraryLoaded`

Here, we configure our Sign-In client once the library has loaded using the `?onload=onLibraryLoaded` callback that you can provide via the URL. `api.js` will add a global variable called `gapi`.

2. Add a button to your index.html with a button click handler

`<button onclick="onSignInClicked()">Sign in with button onClick</button>`

2. Add the following to your script tag in index.html to handle the button click

```
function onLibraryLoaded() {
    gapi.load('auth2', function() {
        gapi.auth2.init({
            client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com',
            scope: 'profile'
        })
    })
}

function onSignInClicked() {
    gapi.load('auth2', function() {
        gapi.auth2.signIn().then(function(googleUser) {
          console.log('user signed in')
        }, function(error) {
            console.log('user failed to sign in')
        })
    })
}
```
We can then access the `gapi.auth2` library and initialize it using our `client_id` from the Developer Console.

## how to handle some common user scenarios
- listening for when the user has signs in
- checking if the user is logged in
- getting the users info
- only allow users from a particular domain to log in
- only allow certain users to log in
- hide content until after a user logs in
- sending your ID token to a backend (if you have one)

### listening for when user signs in

In the above example, we can only run some code after we initialize and sign in the user. But what if you have different parts of the page in different files, each showing something different depending on the user? (this might be the case if you're using components) 

```
class UserAvatarComponent extends React.Component {
    ...
    componentDidMount() {
        gapi.load('auth2', function() {
            gapi.auth2.isSignedIn.listen(function(isSignedIn) {
                console.log('user signed in ', isSignedIn)
                this.setState({status: isSignedIn})
            })
        })
    }    
}
```

### checking if the user is signed in
```
function isUserSignedIn() {
  gapi.load('auth2', function() {
      var isSignedIn = auth2.isSignedIn.get();
      console.log('is signed in? ', isSigned In)
  })
}
```

A few things to note about using this function:

- The Sign-In library will, by default, sign you in automatically if you've already signed in.
- If you refresh the page, even after the user has signed in, then on first laod, you'll get  `auth2.isSignedIn.get() === false`
- After the user is signed in automatically (usually takes a sec), then `auth2.isSignedIn.get() === true`
- Depending on how you handle your login UI, your user might see that they are not logged in for a hot second. It's helpful to use the `isSignedIn.listen()` callback if you want to know the precise moment this happens.

### getting the users info
```
function showCurrentUserInfo() {
  gapi.load('auth2', function() {
      var googleUser = auth2.currentUser.get()
      console.log('users info ', googleUser)
  })
}
```

### only allowing users from a particular domain to login

This is a little bit of a hack and is probably easy to circumvent, but you can use the `getHostedDomain()` method to get the G-Suite domain the user comes from. If the user does not have a G-Suite domain, then it'll be blank.

```
function onSignIn(googleUser) {
    if(googleUser.getHostedDomain() !== 'mysite.com') {
        // show a Not Authorized message
    } else {
        // show the users dashboard
    }
}
```

### only allowing certain users to login

This is even more of a hack, but seems to be the only you can do it from within javascript. You really shouldn't. Don't know why I'm including it. The brute method.

```
function onSignIn(googleUser) {
    var profile = googleUser.getBasicProfile()
    if(profile.getEmail() === 'admin@example.com' ||
       profile.getEmail() === 'client@example.com') {
           // show the user dashboard
    } else {
        // show a Not Authorized message
    }
}
```

### hiding content until after the user logs in

This is also a hack. This is easy to workaround if you fidget with the CSS in your browser, but can work if it fits your use case. The reason this is a bad idea is that in a static website, all of the information thats available in your HTML is available to the user. DO NOT USE THIS if you have actual sensitive information to hide. It is a good candidate for showing your favorite cat pictures.

```
<body>
...
  <div id="greeting">
    You are not authorized to view this content
  </div>
  <div id="dashboard">
    ...
  </div>
  <script>
    // hide initially
    $('#dashboard').hide()
    
    function onSignIn(googleUser) {
      setTimeout(function() {
        // show the content
        $('#greeting').hide()
        $('#dashboard').show()
      }, 1000);
    }
  </script>
</body>
```

### send the token to identify the user (not their ID)

If you're making a backend request, you'll want to send the users ID token to your backend as an Authorization header. On your backend, you'd then be able to validate and decode the ID token ([see here for examples](https://developers.google.com/identity/sign-in/web/backend-auth)).

The benefit of the approach is that this ID token (a type of JWT token) is signed by Google, so you know the information hasn't been tampered with.

```
$.ajax({
  url: 'myapi/example',
  headers: {'Authorization': googleUser.getAuthResponse().id_token)},
})
```

## Conclusion

In this post, we've seen how you can configure the Google Sign-In library via javascript, and use it to do things like get the users info and check if they're signed in (theres some nuances to be aware of with the login flow). 

Demo code is available on [Github intricatecloud/google-sign-in-demo](https://github.com/intricatecloud/google-sign-in-demo/blob/master/gapi-demo.html). Replace `YOUR_CLIENT_ID` with your client ID, and you'll be able to see the sign in buttons in action.

For the last part of this series, we'll look at some examples of how you might use google sign-in in a React and Angular application. [Check it out here](https://www.intricatecloud.io/2019/08/adding-google-sign-in-to-your-webapp-a-react-example/).

---

Originally published on [www.intricatecloud.io](https://www.intricatecloud.io/2019/07/adding-google-sign-in-to-your-webapp-using-the-js-library/)