# Migrate from Google+ sign-in

> [!WARNING]
> **Warning:** The Google Sign-In library optionally uses FedCM APIs, and their use will become a requirement. [Conduct an impact assessment](https://developers.google.com/identity/sign-in/web/gsi-with-fedcm) to confirm that user sign-in continues to function as expected.   
>
> Support for the Google Sign-In library is deprecated, see the [Deprecation and Sunset](https://developers.google.com/identity/sign-in/web/deprecation-and-sunset) guide for more.

> [!CAUTION]
> **Important:** The scope
> `profile.emails.read` is now classified as a
> [sensitive scope](https://support.google.com/cloud/answer/9110914#sensitive-scope-verification).
> You can achieve the same functionality with the OpenID Connect (OIDC) scope
> of `email`. To minimize impact on your users, complete the
> [steps](https://developers.google.com/identity/sign-in/web/quick-migration-guide#steps) in this guide.
>
> If you don't complete these steps, any user with an active token that still
> has access to the scope that we have phased out might be shown an
> [unverified app screen or "Sign-in disabled" message](https://support.google.com/cloud/answer/9110914#verified-but-app-disabled)
> and receive a Security Center warning to
> [remove risky access](https://support.google.com/accounts/answer/3466521)
> to their data. This occurs because the user has an active token where the
> API scope is no longer verified. If your application doesn't revoke the
> token as described in the prescribed [steps](https://developers.google.com/identity/sign-in/web/quick-migration-guide#steps), the user
> might continue to receive a warning.

## Steps to minimize the impact of scope changes on users

1. If your application requires the email address of an authenticated user, and you've previously used `profile.emails.read` for that purpose, use `email` instead.
2. Obtain approval for `profile.emails.read` with an approved verification request. Refer to [How do I submit for verification?](https://support.google.com/cloud/answer/9110914#submit-howto)
3. [Revoke](https://developers.google.com/identity/protocols/oauth2/web-server#tokenrevoke) the prior user token to the scope that's to be removed or remove access to the application entirely. For example, a token with `profile.emails.read` access should be revoked. We recommend you apply the revocation while your users are in your application so that you can get user consent immediately.
4. Prompt your users to re-consent with the new scope, such as `email`, without `profile.emails.read`.
5. Remove the scope that's to be phased out of your Google APIs OAuth consent screen configuration.

> [!WARNING]
> The Google+ Sign-in feature has been fully deprecated as of March 7, 2019.
>
> Developers should migrate to the more comprehensive
> [Google Sign-in](https://developers.google.com/identity/sign-in/web) authentication system.
>
> Migration tips are also available for
> [Android](https://developers.google.com/identity/sign-in/android/quick-migration-guide).

The changes you must make to migrate your site from Google+ Sign-In to Google
Sign-In depend on which Google+ Sign-In flow you use. Generally, the migration
requires you to update your sign-in button, requested scopes, and instructions
on how to retrieve profile information from Google.

When you update your sign-in button, do not refer to G+ or use the color red.
Conform to our updated
[branding guidelines](https://developers.google.com/identity/branding-guidelines).

Most G+ Sign-In applications requested some combination of the scopes:
`plus.login`, `plus.me` and `plus.profile.emails.read`. You need to remap
your scopes as follows:

| Old scope | New scope |
|---|---|
| `plus.login` | `profile` |
| `plus.me` | `openid` |
| `plus.profile.emails.read` | `email` |

Many implementers of Google+ Sign-In used the
[code flow](https://developers.google.com/identity/protocols/oauth2/web-server#handlingresponse). This means
that the Android, iOS, or JavaScript apps obtain an OAuth code from Google, and
the client sends that code back to the server, along with cross-site request
forgery protection. The server then validates the code and obtains refresh and
access tokens to pull user profile information from the `people.get` API.

Google now recommends that you request an ID token and send that ID token from
your client to your server. ID tokens have cross-site forgery protections
built-in and also can be statically verified on your server, which avoids an
extra API call to get user profile information from Google's servers. Follow the
instructions to [validate ID tokens on your server](https://developers.google.com/identity/sign-in/android/backend-auth#verify-the-integrity-of-the-id-token).

If you still prefer to use the code flow to obtain profile information,
you may do so. Once your server has an access token, you need to
[obtain user profile information](https://developers.google.com/identity/protocols/oauth2/openid-connect#obtaininguserprofileinformation)
from the `userinfo` endpoints specified in our Sign-In
[Discovery document](https://developers.google.com/identity/protocols/oauth2/openid-connect#discovery). The API
response is formatted differently than the Google+ profile response, so you
need to update your parsing to the new format.

## Migrate an HTML sign-in button

If you included a Google+ Sign-In button in your page by assignment of the class
`g-signin` to an element, make the following changes:

- When you specify your client ID, either in a `<meta>` tag, a `data-`
  attribute, or a parameters object, change the string `clientid` to
  `client_id`, as in the following example:

      <!-- Google+ Sign-in (old) -->
      <meta name="google-signin-clientid" content="YOUR_CLIENT_ID">

  <br />

      <!-- Google Sign-in (new) -->
      <meta name="google-signin-client_id" content="YOUR_CLIENT_ID">

- Assign the class `g-signin2` to the sign-in button element instead of
  `g-signin`. Also, specify separate success and failure callbacks instead of a
  single callback, as in the following example:

      <!-- Google+ Sign-in (old) -->
      <div
        class="g-signin"
        data-callback="signinCallback">
      </div>

  <br />

      <!-- Google Sign-in (new) -->
      <div
        class="g-signin2"
        data-onsuccess="onSignIn"
        data-onfailure="onSignInFailure">
      </div>

- Instead of a single callback handler, define success and failure handlers,
  as in the following example:

      // Google+ Sign-in (old)
      function signinCallback(authResult) {
        if (authResult['status']['signed_in']) {
          // Handle successful sign-in
        } else {
          // Handle sign-in errors
          console.log('Sign-in error: ' + authResult['error']);
        }
      }

  <br />

      // Google Sign-in (new)
      function onSignIn(googleUser) {
        // Handle successful sign-in
      }
      function onSignInFailure() {
        // Handle sign-in errors
      }

- These changes update your default scopes to `profile email openid`.
  You can get the user's basic profile information, like name, email, and photo
  image URL, as follows:

      // Google Sign-in (new)
      function onSignIn(googleUser) {
        let profile = googleUser.getBasicProfile();
        let fullName = profile.getName();
        let email = profile.getEmail();
        let imageUrl = profile.getImageUrl();
      }

## Migrate a dynamically-rendered sign-in button

If you included a Google+ Sign-In button in your page by calling
`gapi.signin.render()`, make the following changes:

- When you specify your client ID, either in a `<meta>` tag, a `data-`
  attribute, or a parameters object, change the string `clientid` to
  `client_id`, as in the following example:

      <!-- Google+ Sign-in (old) -->
      <meta name="google-signin-clientid" content="YOUR_CLIENT_ID">

  <br />

      <!-- Google Sign-in (new) -->
      <meta name="google-signin-client_id" content="YOUR_CLIENT_ID">

- Render the sign-in button with `gapi.signin2.render()` rather than
  `gapi.signin.render()`, as in the following example:

      // Google+ Sign-in (old)
      gapi.signin.render('myButton', additionalParams);

  <br />

      // Google Sign-in (new)
      gapi.signin2.render('myButton', additionalParams);

- Instead of a single callback handler, define success and failure handlers,
  as in the following example:

      // Google+ Sign-in (old)
      function signinCallback(authResult) {
        if (authResult['status']['signed_in']) {
          // Handle successful sign-in
        } else {
          // Handle sign-in errors
          console.log('Sign-in error: ' + authResult['error']);
        }
      }

  <br />

      // Google Sign-in (new)
      function onSignIn(googleUser) {
        // Handle successful sign-in
      }
      function onSignInFailure() {
        // Handle sign-in errors
      }

These changes update your default scopes to `profile email openid`. You can
get the user's basic profile information with the `getBasicProfile()` method.

## Migrate a JavaScript-initiated sign-in flow

If you initiated the sign-in flow with a call to `gapi.auth.signIn()` when users
click the sign-in button, make the following changes:

- When you specify your client ID, either in a `<meta>` tag, a `data-`
  attribute, or a parameters object, change the string `clientid` to
  `client_id`, as in the followingr example:

      <!-- Google+ Sign-in (old) -->
      <meta name="google-signin-clientid" content="YOUR_CLIENT_ID">

  <br />

      <!-- Google Sign-in (new) -->
      <meta name="google-signin-client_id" content="YOUR_CLIENT_ID">

- Use `gapi.auth2.attachClickHandler()` to start the sign-in flow when a button
  is pressed, as in the following example:

      // Google+ Sign-in (old)
      var signinButton = document.getElementById('signinButton');
      signinButton.addEventListener('click', function() {
        gapi.auth.signIn(additionalParams);
      });

  <br />

      // Google Sign-in (new)
      auth2 = gapi.auth2.init();
      auth2.attachClickHandler('signinButton', additionalParams, onSignIn, onSignInFailure);

- Instead of a single callback handler, define success and failure handlers,
  as in the following example:

      // Google+ Sign-in (old)
      function signinCallback(authResult) {
        if (authResult['status']['signed_in']) {
          // Handle successful sign-in
        } else {
          // Handle sign-in errors
          console.log('Sign-in error: ' + authResult['error']);
        }
      }

  <br />

      // Google Sign-in (new)
      function onSignIn(googleUser) {
        // Handle successful sign-in
      }
      function onSignInFailure() {
        // Handle sign-in errors
      }

These changes update your default scopes to `profile email openid`. You can
get the user's basic profile information by a call to the `getBasicProfile()`
method.

## Migrate a hybrid server-side flow

If you used the JavaScript API to acquire a one-time authorization code for you
to pass to your server, make the following changes:

- Change the scope from `https://www.googleapis.com/auth/plus.login` to
  `profile`.

- Use the `gapi.auth2.grantOfflineAccess()` method with your existing callback
  function, as in the following example:

      <!-- Google+ Sign-in (old) -->
      <div class="g-signin"
        data-scope="https://www.googleapis.com/auth/plus.login"
        data-clientid="YOUR_CLIENT_ID"
        data-redirecturi="postmessage"
        data-accesstype="offline"
        data-callback="signInCallback">
      </div>

  <br />

      // Google Sign-in (new)
      auth2 = gapi.auth2.init({
        client_id: 'YOUR_CLIENT_ID',
        scope: 'profile'
      });

      ...

      auth2.grantOfflineAccess().then(signInCallback);

If you also need access to the user's email, add `email` to the scope parameter.