Svelte: Google Sign In/Out
Tags: svelte, auth, google, webdev
Published: 2020-01-19 23:18:39

You got your awesome Svelte app and it is time to integrate some authentication flows. Sign in with Google is one way to support many users to log into your app.

Google makes it simple to plug in their ready made Google Sign In button for any web project.

Let's get started.

## Google Prerequisite
A client ID from Google is necessary to integrate sign in. Configure a project here: https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin

Once you navigated the Google API dashboards and have a client ID, add a meta tag to your root HTML file. If you generated your Svelte app with the default configuration, it should be in `public/index.html`.

```html
<!doctype html>
<html>
<head>
  <meta name="google-signin-client_id" content="CLIENT_ID.apps.googleusercontent.com">
</head>
...
</html>
```

## Set up the Google Sign In Button
Let us create a new component `GoogleSignInButton.svelte` to handle the UI and sign in.

Let start off with the component, we need to add the Google Platform and display the button.
```html
<svelte:head>
  <script src="https://apis.google.com/js/platform.js" async defer></script>
</svelte:head>

<div class="g-signin2" data-longtitle="true" data-onsuccess="onSignIn" />
```

Success! ✅ You should see your button.
![Google Sign In Button on a web page.](https://thepracticaldev.s3.amazonaws.com/i/8a2t7ev30jms4fvogklj.png)

The div takes a property `data-onsuccess="onSignIn"`. It looks for the function `window.onSignIn` and uses that as the on sign in callback.

```html
<script>
  window.onSignIn = (googleUser) => {
     const profile = googleUser.getBasicProfile();
     console.log('ID: ' + profile.getId());
     console.log('Name: ' + profile.getName());
     console.log('Image URL: ' + profile.getImageUrl());
     console.log('Email: ' + profile.getEmail());
  };
</script>

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

<div class="g-signin2" data-longtitle="true" data-onsuccess="onSignIn" />
```
Now you have access to the public information of the user. You can use the attributes to create a unique user so they can continue to log into your app.

## Logging out
To logout we need to use Google API AuthInstance to call sign out, we included this API in our root HTML file.

Let's create a `Logout.svelte` component.
```html
<script>
  window.signOut = () => {
    const auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(() => {
      // User is now signed out
    });
  }
</script>

<a onclick="signOut">Sign out</a>
```

We are using the `onclick` attribute to reference our `signOut` logic. Now we have signing out! ✅🎉

## Persisting Session
It would be a pain if the user had to sign in every time they want to access your site. So let's make sure the session is persisted.

We need to know when the Google API has loaded before we try to access it. We can add an on load callback by using the `onload` URL param.

In `GoogleSignInButton.svelte`, append the platform URL with `?onload=<NAME OF CALLBACK>`
```html
<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script>
```

In `App.svelte` we can handle the case where the user accesses the site. We check if a Google User exists and act accordingly.

```html
<script>
  let userLoggedIn = false;
  window.onLoadCallback = () => {
    userLoggedIn = gapi.auth2.getAuthInstance().isSignedIn.get();
    if (userLoggedIn) {  
      // Handle login
    }
  }
</script>
```

Now we have persistent sessions with Google authentication! ✅🎉


Leave a comment if this was helpful or have any questions!

-------------------------------------------------------------------------

You can find me on Twitter [@safaiyeh](https://twitter.com/safaiyeh)

or maintaining [react-native-webview](https://github.com/react-native-community/react-native-webview) and [@react-native-community/react-native-cookies](https://github.com/react-native-community/react-native-cookies).

Keep Building!