adding google sign-in to your webapp - using the js library
Danny Perez
Posted on July 23, 2019
In the first part of the series, we decided to use the Google Sign-In for websites library 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
- Load the api.js library instead of platform.js 🤷 (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
.
- Add a button to your index.html with a button click handler
<button onclick="onSignInClicked()">Sign in with button onClick</button>
- 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).
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. 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.
Originally published on www.intricatecloud.io
Posted on July 23, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 26, 2024
November 20, 2024