CINXE.COM
OAuth 2.0 for Mobile & Desktop Apps | Authorization | Google for Developers
<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="721724668570-nbkv1cfusk7kk4eni4pjvepaus73b13t.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="Google for Developers"> <meta property="og:type" content="website"><meta name="theme-color" content="#009688"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/developers/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/css/app.css"> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/favicon-new.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/touchicon-180-new.png"><link rel="canonical" href="https://developers.google.com/identity/protocols/oauth2/native-app"><link rel="search" type="application/opensearchdescription+xml" title="Google for Developers" href="https://developers.google.com/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://developers.google.com/identity/protocols/oauth2/native-app" /><link rel="alternate" hreflang="x-default" href="https://developers.google.com/identity/protocols/oauth2/native-app" /><link rel="alternate" hreflang="ar" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=ar" /><link rel="alternate" hreflang="bn" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=fa" /><link rel="alternate" hreflang="fr" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=fr" /><link rel="alternate" hreflang="de" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=de" /><link rel="alternate" hreflang="he" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=he" /><link rel="alternate" hreflang="hi" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=hi" /><link rel="alternate" hreflang="id" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=id" /><link rel="alternate" hreflang="it" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=it" /><link rel="alternate" hreflang="ja" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=ja" /><link rel="alternate" hreflang="ko" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=ko" /><link rel="alternate" hreflang="pl" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=ru" /><link rel="alternate" hreflang="es-419" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=es-419" /><link rel="alternate" hreflang="th" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=th" /><link rel="alternate" hreflang="tr" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=tr" /><link rel="alternate" hreflang="vi" href="https://developers.google.com/identity/protocols/oauth2/native-app?hl=vi" /><title>OAuth 2.0 for Mobile & Desktop Apps | Authorization | Google for Developers</title> <meta property="og:title" content="OAuth 2.0 for Mobile & Desktop Apps | Authorization | Google for Developers"><meta property="og:url" content="https://developers.google.com/identity/protocols/oauth2/native-app"><meta property="og:image" content="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/opengraph/teal.png"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="675"><meta property="og:locale" content="en"><meta name="twitter:card" content="summary_large_image"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "headline": "OAuth 2.0 for Mobile & Desktop Apps" } </script><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Google Identity", "item": "https://developers.google.com/identity" },{ "@type": "ListItem", "position": 2, "name": "Authorization", "item": "https://developers.google.com/identity/authorization" },{ "@type": "ListItem", "position": 3, "name": "OAuth 2.0 for Mobile & Desktop Apps", "item": "https://developers.google.com/identity/protocols/oauth2/native-app" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="teal" type="article" layout="docs" concierge='closed' display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item devsite-has-google-wordmark"> <a href="https://developers.google.com/identity" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Upper Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Google Identity" > <svg class="devsite-google-wordmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 148 48"> <title>Google</title> <path class="devsite-google-wordmark-svg-path" d="M19.58,37.65c-9.87,0-18.17-8.04-18.17-17.91c0-9.87,8.3-17.91,18.17-17.91c5.46,0,9.35,2.14,12.27,4.94l-3.45,3.45c-2.1-1.97-4.93-3.49-8.82-3.49c-7.21,0-12.84,5.81-12.84,13.02c0,7.21,5.64,13.02,12.84,13.02c4.67,0,7.34-1.88,9.04-3.58c1.4-1.4,2.32-3.41,2.66-6.16H19.58v-4.89h16.47c0.18,0.87,0.26,1.92,0.26,3.06c0,3.67-1.01,8.21-4.24,11.44C28.93,35.9,24.91,37.65,19.58,37.65z M61.78,26.12c0,6.64-5.1,11.53-11.36,11.53s-11.36-4.89-11.36-11.53c0-6.68,5.1-11.53,11.36-11.53S61.78,19.43,61.78,26.12z M56.8,26.12c0-4.15-2.96-6.99-6.39-6.99c-3.43,0-6.39,2.84-6.39,6.99c0,4.11,2.96,6.99,6.39,6.99C53.84,33.11,56.8,30.22,56.8,26.12z M87.25,26.12c0,6.64-5.1,11.53-11.36,11.53c-6.26,0-11.36-4.89-11.36-11.53c0-6.68,5.1-11.53,11.36-11.53C82.15,14.59,87.25,19.43,87.25,26.12zM82.28,26.12c0-4.15-2.96-6.99-6.39-6.99c-3.43,0-6.39,2.84-6.39,6.99c0,4.11,2.96,6.99,6.39,6.99C79.32,33.11,82.28,30.22,82.28,26.12z M112.09,15.29v20.7c0,8.52-5.02,12.01-10.96,12.01c-5.59,0-8.95-3.76-10.22-6.81l4.41-1.83c0.79,1.88,2.71,4.1,5.81,4.1c3.8,0,6.16-2.36,6.16-6.77v-1.66h-0.18c-1.14,1.4-3.32,2.62-6.07,2.62c-5.76,0-11.05-5.02-11.05-11.49c0-6.51,5.28-11.57,11.05-11.57c2.75,0,4.93,1.22,6.07,2.58h0.18v-1.88H112.09z M107.64,26.16c0-4.06-2.71-7.03-6.16-7.03c-3.49,0-6.42,2.97-6.42,7.03c0,4.02,2.93,6.94,6.42,6.94C104.93,33.11,107.64,30.18,107.64,26.16z M120.97,3.06v33.89h-5.07V3.06H120.97z M140.89,29.92l3.93,2.62c-1.27,1.88-4.32,5.11-9.61,5.11c-6.55,0-11.28-5.07-11.28-11.53c0-6.86,4.77-11.53,10.71-11.53c5.98,0,8.91,4.76,9.87,7.34l0.52,1.31l-15.42,6.38c1.18,2.31,3.01,3.49,5.59,3.49C137.79,33.11,139.58,31.84,140.89,29.92zM128.79,25.77l10.31-4.28c-0.57-1.44-2.27-2.45-4.28-2.45C132.24,19.04,128.66,21.31,128.79,25.77z"/> </svg>Identity </a> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab class="devsite-dropdown "> <a href="https://developers.google.com/identity/authentication" track-metadata-eventdetail="https://developers.google.com/identity/authentication" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - authentication" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Authentication" track-name="authentication" > Authentication </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Authentication" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/authentication" track-metadata-position="nav - authentication" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Authentication" track-name="authentication" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Sign In with Google SDKs</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/android-credential-manager" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/android-credential-manager" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> Credential Manager for Android </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/gsi/web/guides/overview" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/gsi/web/guides/overview" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> Sign In with Google for Web (including One Tap) </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/sign-in/ios/start" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/sign-in/ios/start" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> Google Sign-In for iOS and macOS </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Industry standards</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/passkeys" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/passkeys" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> Passkeys </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/openid-connect/openid-connect" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/openid-connect/openid-connect" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> OpenID Connect </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Legacy Sign In</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/one-tap/android/overview" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/one-tap/android/overview" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> One Tap sign-up/sign-in for Android </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/sign-in/android/legacy-start-integrating" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/sign-in/android/legacy-start-integrating" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> Google Sign-In for Android </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/sign-in/web/sign-in" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/sign-in/web/sign-in" track-metadata-position="nav - authentication" track-metadata-module="tertiary nav" track-metadata-module_headline="sign in with google sdks" tooltip > <div class="devsite-nav-item-title"> Google Sign-In for Web </div> </a> </li> </ul> </div> </div> </div> </tab> <tab class="devsite-dropdown devsite-active "> <a href="https://developers.google.com/identity/authorization" track-metadata-eventdetail="https://developers.google.com/identity/authorization" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - authorization" track-metadata-module="primary nav" aria-label="Authorization, selected" data-category="Site-Wide Custom Events" data-label="Tab: Authorization" track-name="authorization" > Authorization </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Authorization" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/authorization" track-metadata-position="nav - authorization" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Authorization" track-name="authorization" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Call Google APIs</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/sign-in/android/authorize-access" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/sign-in/android/authorize-access" track-metadata-position="nav - authorization" track-metadata-module="tertiary nav" track-metadata-module_headline="call google apis" tooltip > <div class="devsite-nav-item-title"> Authorizing for Android </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/oauth2/web/guides/overview" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/oauth2/web/guides/overview" track-metadata-position="nav - authorization" track-metadata-module="tertiary nav" track-metadata-module_headline="call google apis" tooltip > <div class="devsite-nav-item-title"> Authorizing for Web </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/sign-in/ios/api-access" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/sign-in/ios/api-access" track-metadata-position="nav - authorization" track-metadata-module="tertiary nav" track-metadata-module_headline="call google apis" tooltip > <div class="devsite-nav-item-title"> Authorizing for iOS/macOS </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/protocols/oauth2" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/protocols/oauth2" track-metadata-position="nav - authorization" track-metadata-module="tertiary nav" track-metadata-module_headline="call google apis" tooltip > <div class="devsite-nav-item-title"> Using OAuth 2.0 </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Share data with Google apps and devices</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/account-linking" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/account-linking" track-metadata-position="nav - authorization" track-metadata-module="tertiary nav" track-metadata-module_headline="call google apis" tooltip > <div class="devsite-nav-item-title"> Google Account Linking </div> </a> </li> </ul> </div> </div> </div> </tab> <tab class="devsite-dropdown "> <a href="https://developers.google.com/identity/credential-management" track-metadata-eventdetail="https://developers.google.com/identity/credential-management" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - credential management" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Credential management" track-name="credential management" > Credential management </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Credential management" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/credential-management" track-metadata-position="nav - credential management" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Credential management" track-name="credential management" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Android</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/android-credential-manager" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/android-credential-manager" track-metadata-position="nav - credential management" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Credential Manager </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/blockstore/android" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/blockstore/android" track-metadata-position="nav - credential management" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Blockstore </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/smartlock-passwords/android/associate-apps-and-sites" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/smartlock-passwords/android/associate-apps-and-sites" track-metadata-position="nav - credential management" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Digital Asset Links </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.android.com/guide/topics/text/autofill" track-type="nav" track-metadata-eventdetail="https://developer.android.com/guide/topics/text/autofill" track-metadata-position="nav - credential management" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Android autofill framework </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Web</li> <li class="devsite-nav-item"> <a href="https://web.dev/sign-in-form-best-practices/" track-type="nav" track-metadata-eventdetail="https://web.dev/sign-in-form-best-practices/" track-metadata-position="nav - credential management" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Autocomplete </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Cross-platform</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/credential-sharing" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/credential-sharing" track-metadata-position="nav - credential management" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Seamless credential sharing </div> </a> </li> </ul> </div> </div> </div> </tab> <tab class="devsite-dropdown "> <a href="https://developers.google.com/identity/credential-verification" track-metadata-eventdetail="https://developers.google.com/identity/credential-verification" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - credential verification" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Credential verification" track-name="credential verification" > Credential verification </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Credential verification" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/credential-verification" track-metadata-position="nav - credential verification" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Credential verification" track-name="credential verification" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Android</li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/sms-retriever/overview" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/sms-retriever/overview" track-metadata-position="nav - credential verification" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Verify users by SMS </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developers.google.com/identity/phone-number-hint/android" track-type="nav" track-metadata-eventdetail="https://developers.google.com/identity/phone-number-hint/android" track-metadata-position="nav - credential verification" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Phone Number Hint </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Web</li> <li class="devsite-nav-item"> <a href="https://web.dev/web-otp/" track-type="nav" track-metadata-eventdetail="https://web.dev/web-otp/" track-metadata-position="nav - credential verification" track-metadata-module="tertiary nav" track-metadata-module_headline="android" tooltip > <div class="devsite-nav-item-title"> Verify phone numbers on the web </div> </a> </li> </ul> </div> </div> </div> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Authorization" tenant-name="Google for Developers" project-scope="/identity/authorization" url-scoped="https://developers.google.com/s/results/identity/authorization" > <form class="devsite-search-form" action="https://developers.google.com/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <devsite-user enable-profiles fp-auth id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section "> <div class="devsite-header-background"> <div class="devsite-product-id-row" > <div class="devsite-product-description-row"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> <a href="https://developers.google.com/identity/authorization" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Lower Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Authorization" > Authorization </a> </li> </ul> </div> </div> <div class="devsite-doc-set-nav-row"> <devsite-tabs class="lower-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Lower tabs"> <tab class="devsite-active"> <a href="https://developers.google.com/identity/protocols/oauth2" track-metadata-eventdetail="https://developers.google.com/identity/protocols/oauth2" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - oauth 2.0" track-metadata-module="primary nav" aria-label="OAuth 2.0, selected" data-category="Site-Wide Custom Events" data-label="Tab: OAuth 2.0" track-name="oauth 2.0" > OAuth 2.0 </a> </tab> <tab > <a href="https://developers.google.com/identity/authorization/android" track-metadata-eventdetail="https://developers.google.com/identity/authorization/android" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - android" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Android" track-name="android" > Android </a> </tab> <tab > <a href="https://developers.google.com/identity/oauth2/web/guides/overview" track-metadata-eventdetail="https://developers.google.com/identity/oauth2/web/guides/overview" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - web" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Web" track-name="web" > Web </a> </tab> <tab > <a href="https://developers.google.com/identity/account-linking" track-metadata-eventdetail="https://developers.google.com/identity/account-linking" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - google account linking" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Google Account Linking" track-name="google account linking" > Google Account Linking </a> </tab> </nav> </devsite-tabs> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars > <div class="devsite-book-nav-filter" > <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item devsite-has-google-wordmark"> <a href="https://developers.google.com/identity" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Upper Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Google Identity" > <svg class="devsite-google-wordmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 148 48"> <title>Google</title> <path class="devsite-google-wordmark-svg-path" d="M19.58,37.65c-9.87,0-18.17-8.04-18.17-17.91c0-9.87,8.3-17.91,18.17-17.91c5.46,0,9.35,2.14,12.27,4.94l-3.45,3.45c-2.1-1.97-4.93-3.49-8.82-3.49c-7.21,0-12.84,5.81-12.84,13.02c0,7.21,5.64,13.02,12.84,13.02c4.67,0,7.34-1.88,9.04-3.58c1.4-1.4,2.32-3.41,2.66-6.16H19.58v-4.89h16.47c0.18,0.87,0.26,1.92,0.26,3.06c0,3.67-1.01,8.21-4.24,11.44C28.93,35.9,24.91,37.65,19.58,37.65z M61.78,26.12c0,6.64-5.1,11.53-11.36,11.53s-11.36-4.89-11.36-11.53c0-6.68,5.1-11.53,11.36-11.53S61.78,19.43,61.78,26.12z M56.8,26.12c0-4.15-2.96-6.99-6.39-6.99c-3.43,0-6.39,2.84-6.39,6.99c0,4.11,2.96,6.99,6.39,6.99C53.84,33.11,56.8,30.22,56.8,26.12z M87.25,26.12c0,6.64-5.1,11.53-11.36,11.53c-6.26,0-11.36-4.89-11.36-11.53c0-6.68,5.1-11.53,11.36-11.53C82.15,14.59,87.25,19.43,87.25,26.12zM82.28,26.12c0-4.15-2.96-6.99-6.39-6.99c-3.43,0-6.39,2.84-6.39,6.99c0,4.11,2.96,6.99,6.39,6.99C79.32,33.11,82.28,30.22,82.28,26.12z M112.09,15.29v20.7c0,8.52-5.02,12.01-10.96,12.01c-5.59,0-8.95-3.76-10.22-6.81l4.41-1.83c0.79,1.88,2.71,4.1,5.81,4.1c3.8,0,6.16-2.36,6.16-6.77v-1.66h-0.18c-1.14,1.4-3.32,2.62-6.07,2.62c-5.76,0-11.05-5.02-11.05-11.49c0-6.51,5.28-11.57,11.05-11.57c2.75,0,4.93,1.22,6.07,2.58h0.18v-1.88H112.09z M107.64,26.16c0-4.06-2.71-7.03-6.16-7.03c-3.49,0-6.42,2.97-6.42,7.03c0,4.02,2.93,6.94,6.42,6.94C104.93,33.11,107.64,30.18,107.64,26.16z M120.97,3.06v33.89h-5.07V3.06H120.97z M140.89,29.92l3.93,2.62c-1.27,1.88-4.32,5.11-9.61,5.11c-6.55,0-11.28-5.07-11.28-11.53c0-6.86,4.77-11.53,10.71-11.53c5.98,0,8.91,4.76,9.87,7.34l0.52,1.31l-15.42,6.38c1.18,2.31,3.01,3.49,5.59,3.49C137.79,33.11,139.58,31.84,140.89,29.92zM128.79,25.77l10.31-4.28c-0.57-1.44-2.27-2.45-4.28-2.45C132.24,19.04,128.66,21.31,128.79,25.77z"/> </svg>Identity </a> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/identity/authentication" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Authentication" track-name="authentication" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Authentication" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Authentication </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Authentication" track-name="authentication" > <span class="devsite-nav-text" tooltip menu="Authentication"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Authentication"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/identity/authorization" class="devsite-nav-title gc-analytics-event devsite-nav-active" data-category="Site-Wide Custom Events" data-label="Tab: Authorization" track-name="authorization" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Authorization" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Authorization </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Authorization" track-name="authorization" > <span class="devsite-nav-text" tooltip menu="Authorization"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Authorization"> </span> </span> </li> </ul> <ul class="devsite-nav-responsive-tabs"> <li class="devsite-nav-item"> <a href="/identity/protocols/oauth2" class="devsite-nav-title gc-analytics-event devsite-nav-has-children devsite-nav-active" data-category="Site-Wide Custom Events" data-label="Tab: OAuth 2.0" track-name="oauth 2.0" data-category="Site-Wide Custom Events" data-label="Responsive Tab: OAuth 2.0" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip menu="_book"> OAuth 2.0 </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="_book"> </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/authorization/android" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Android" track-name="android" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Android" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Android </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/oauth2/web/guides/overview" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Web" track-name="web" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Web" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Web </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/account-linking" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Google Account Linking" track-name="google account linking" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Google Account Linking" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Google Account Linking </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/identity/credential-management" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Credential management" track-name="credential management" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Credential management" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Credential management </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Credential management" track-name="credential management" > <span class="devsite-nav-text" tooltip menu="Credential management"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Credential management"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/identity/credential-verification" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Credential verification" track-name="credential verification" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Credential verification" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Credential verification </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Credential verification" track-name="credential verification" > <span class="devsite-nav-text" tooltip menu="Credential verification"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Credential verification"> </span> </span> </li> </ul> </li> </ul> </div> <div class="devsite-mobile-nav-bottom"> <ul class="devsite-nav-list" menu="_book"> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2" ><span class="devsite-nav-text" tooltip>Overview</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/cross-client-identity" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/cross-client-identity" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/cross-client-identity" ><span class="devsite-nav-text" tooltip>Cross-client Identity</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/scopes" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/scopes" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/scopes" ><span class="devsite-nav-text" tooltip>OAuth 2.0 Scopes</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/policies" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/policies" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/policies" ><span class="devsite-nav-text" tooltip>OAuth 2.0 Policies</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Access to Google APIs</span> </div></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/web-server" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/web-server" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/web-server" ><span class="devsite-nav-text" tooltip>for Server-side Web Apps</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/javascript-implicit-flow" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/javascript-implicit-flow" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/javascript-implicit-flow" ><span class="devsite-nav-text" tooltip>for JavaScript Web Apps</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/native-app" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/native-app" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/native-app" ><span class="devsite-nav-text" tooltip>for Mobile & Desktop Apps</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/limited-input-device" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/limited-input-device" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/limited-input-device" ><span class="devsite-nav-text" tooltip>for TV & Device Apps</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/service-account" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/service-account" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/service-account" ><span class="devsite-nav-text" tooltip>for Service Accounts</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Prepare your app for production</span> </div></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/production-readiness/policy-compliance" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/production-readiness/policy-compliance" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/production-readiness/policy-compliance" ><span class="devsite-nav-text" tooltip>Comply with OAuth 2.0 policies</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/production-readiness/brand-verification" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/production-readiness/brand-verification" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/production-readiness/brand-verification" ><span class="devsite-nav-text" tooltip>Submit for brand verification</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/production-readiness/sensitive-scope-verification" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/production-readiness/sensitive-scope-verification" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/production-readiness/sensitive-scope-verification" ><span class="devsite-nav-text" tooltip>Sensitive scope verification</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/production-readiness/restricted-scope-verification" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/production-readiness/restricted-scope-verification" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/production-readiness/restricted-scope-verification" ><span class="devsite-nav-text" tooltip>Restricted scope verification</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/production-readiness/google-workspace" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/production-readiness/google-workspace" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/production-readiness/google-workspace" ><span class="devsite-nav-text" tooltip>Additional considerations for Google Workspace</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Resources</span> </div></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/resources/best-practices" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/resources/best-practices" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/resources/best-practices" ><span class="devsite-nav-text" tooltip>Best practices</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/resources/granular-permissions" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/resources/granular-permissions" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/resources/granular-permissions" ><span class="devsite-nav-text" tooltip>How to handle granular permissions</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/resources/oob-migration" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/resources/oob-migration" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/resources/oob-migration" ><span class="devsite-nav-text" tooltip>Out-of-band (OOB) Migration</span></a></li> <li class="devsite-nav-item"><a href="/identity/protocols/oauth2/resources/loopback-migration" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/oauth2/resources/loopback-migration" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/oauth2/resources/loopback-migration" ><span class="devsite-nav-text" tooltip>Loopback IP Address Migration for Mobile and Chrome Apps</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Related topics</span> </div></li> <li class="devsite-nav-item"><a href="/identity/protocols/risc" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /identity/protocols/risc" track-type="bookNav" track-name="click" track-metadata-eventdetail="/identity/protocols/risc" ><span class="devsite-nav-text" tooltip>Cross-Account Protection (RISC)</span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://webauthn.guide/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://webauthn.guide/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://webauthn.guide/" ><span class="devsite-nav-text" tooltip>WebAuthn</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> </ul> <ul class="devsite-nav-list" menu="Authentication" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Sign In with Google SDKs </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/android-credential-manager" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Credential Manager for Android" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Credential Manager for Android </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/gsi/web/guides/overview" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Sign In with Google for Web (including One Tap)" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Sign In with Google for Web (including One Tap) </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/sign-in/ios/start" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Google Sign-In for iOS and macOS" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Google Sign-In for iOS and macOS </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Industry standards </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/passkeys" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Passkeys" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Passkeys </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/openid-connect/openid-connect" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: OpenID Connect" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > OpenID Connect </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Legacy Sign In </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/one-tap/android/overview" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: One Tap sign-up/sign-in for Android" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > One Tap sign-up/sign-in for Android </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/sign-in/android/legacy-start-integrating" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Google Sign-In for Android" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Google Sign-In for Android </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/sign-in/web/sign-in" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Google Sign-In for Web" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Google Sign-In for Web </span> </a> </li> </ul> <ul class="devsite-nav-list" menu="Authorization" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Call Google APIs </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/sign-in/android/authorize-access" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Authorizing for Android" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Authorizing for Android </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/oauth2/web/guides/overview" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Authorizing for Web" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Authorizing for Web </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/sign-in/ios/api-access" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Authorizing for iOS/macOS" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Authorizing for iOS/macOS </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/protocols/oauth2" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Using OAuth 2.0" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Using OAuth 2.0 </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Share data with Google apps and devices </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/account-linking" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Google Account Linking" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Google Account Linking </span> </a> </li> </ul> <ul class="devsite-nav-list" menu="Credential management" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Android </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/android-credential-manager" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Credential Manager" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Credential Manager </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/blockstore/android" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Blockstore" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Blockstore </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/smartlock-passwords/android/associate-apps-and-sites" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Digital Asset Links" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Digital Asset Links </span> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.android.com/guide/topics/text/autofill" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Android autofill framework" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Android autofill framework </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Web </span> </span> </li> <li class="devsite-nav-item"> <a href="https://web.dev/sign-in-form-best-practices/" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Autocomplete" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Autocomplete </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Cross-platform </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/credential-sharing" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Seamless credential sharing" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Seamless credential sharing </span> </a> </li> </ul> <ul class="devsite-nav-list" menu="Credential verification" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Android </span> </span> </li> <li class="devsite-nav-item"> <a href="/identity/sms-retriever/overview" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Verify users by SMS" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Verify users by SMS </span> </a> </li> <li class="devsite-nav-item"> <a href="/identity/phone-number-hint/android" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Phone Number Hint" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Phone Number Hint </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Web </span> </span> </li> <li class="devsite-nav-item"> <a href="https://web.dev/web-otp/" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Verify phone numbers on the web" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Verify phone numbers on the web </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" has-book-nav > <devsite-content> <article class="devsite-article"><style> .code-var-color { color: #ec407a; font-weight: bold; } </style> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://developers.google.com/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Home </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developers.google.com/products" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="" > Products </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developers.google.com/identity" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="3" track-type="globalNav" track-name="breadcrumb" track-metadata-position="3" track-metadata-eventdetail="Google Identity" > Google Identity </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developers.google.com/identity/authorization" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="4" track-type="globalNav" track-name="breadcrumb" track-metadata-position="4" track-metadata-eventdetail="Authorization" > Authorization </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developers.google.com/identity/protocols/oauth2" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="5" track-type="globalNav" track-name="breadcrumb" track-metadata-position="5" track-metadata-eventdetail="" > OAuth 2.0 </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <devsite-feedback position="header" project-name="Authorization" product-id="5186570" bucket="Identity guides" context="External devsite feedback" version="t-devsite-webserver-20241114-r00-rc02.464922260396498922" data-label="Send Feedback Button" track-type="feedback" track-name="sendFeedbackLink" track-metadata-position="header" class="nocontent" project-icon="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/touchicon-180-new.png" > <button> Send feedback </button> </devsite-feedback> <h1 class="devsite-page-title" tabindex="-1"> OAuth 2.0 for Mobile & Desktop Apps </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <aside class="note"><b>Note:</b> If you are new to OAuth 2.0, we recommend that you read the <a href="/identity/protocols/oauth2">OAuth 2.0 overview</a> before getting started. The overview summarizes OAuth 2.0 flows that Google supports, which can help you to ensure that you've selected the right flow for your application.</aside> <p>This document explains how applications installed on devices like phones, tablets, and computers use Google's OAuth 2.0 endpoints to authorize access to Google APIs.</p> <p>OAuth 2.0 allows users to share specific data with an application while keeping their usernames, passwords, and other information private. For example, an application can use OAuth 2.0 to obtain permission from users to store files in their Google Drives. </p> <p>Installed apps are distributed to individual devices, and it is assumed that these apps cannot keep secrets. They can access Google APIs while the user is present at the app or when the app is running in the background.</p> <p>This authorization flow is similar to the one used for <a href="/identity/protocols/oauth2/web-server">web server applications</a>. The main difference is that installed apps must open the system browser and supply a local redirect URI to handle responses from Google's authorization server.</p> <p><b>Alternatives</b></p> <p>For mobile apps, you may prefer to use Google Sign-in for <a href="/identity/sign-in/android" title="Google Sign-in for Android">Android</a> or <a href="/identity/sign-in/ios" title="Google Sign-in for iOS">iOS</a>. The Google Sign-in client libraries handle authentication and user authorization, and they may be simpler to implement than the lower-level protocol described here.</p> <p>For apps running on devices that do not support a system browser or that have limited input capabilities, such as TVs, game consoles, cameras, or printers, see <a href="/identity/protocols/oauth2/limited-input-device">OAuth 2.0 for TVs & Devices</a> or <a href="/identity/gsi/web/guides/devices">Sign-In on TVs and Limited Input Devices</a>.</p> <h2 id="libraries" data-text="Libraries and samples" tabindex="-1">Libraries and samples</h2> <p>We recommend the following libraries and samples to help you implement the OAuth 2.0 flow described in this document:</p> <ul> <li><a href="https://openid.github.io/AppAuth-Android/">AppAuth for Android</a> library</li> <li><a href="https://openid.github.io/AppAuth-iOS/">AppAuth for iOS</a> library</li> <li><a href="https://github.com/googlesamples/oauth-apps-for-windows">OAuth for Apps: Windows Samples</a></li> </ul> <h2 id="prerequisites" data-text="Prerequisites" tabindex="-1">Prerequisites</h2> <h3 id="enable-apis" data-text="Enable APIs for your project" tabindex="-1">Enable APIs for your project</h3> <p>Any application that calls Google APIs needs to enable those APIs in the API Console.</p> <p>To enable an API for your project:</p> <ol> <li><a href="https://console.developers.google.com/apis/library">Open the API Library</a> in the Google API Console.</li> <li>If prompted, select a project, or create a new one.</li> <li>The API Library lists all available APIs, grouped by product family and popularity. If the API you want to enable isn't visible in the list, use search to find it, or click <b>View All</b> in the product family it belongs to.</li> <li>Select the API you want to enable, then click the <b>Enable</b> button.</li> <li>If prompted, enable billing.</li> <li>If prompted, read and accept the API's Terms of Service.</li> </ol> <h3 id="creatingcred" data-text="Create authorization credentials" tabindex="-1">Create authorization credentials</h3> <p>Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server. The following steps explain how to create credentials for your project. Your applications can then use the credentials to access APIs that you have enabled for that project.</p> <ol> <li>Go to the <a href="https://console.developers.google.com/apis/credentials">Credentials page</a>.</li> <li>Click <b>Create credentials > OAuth client ID</b>.</li> <li>The following sections describe the client types that Google's authorization server supports. Choose the client type that is recommended for your application, name your OAuth client, and set the other fields in the form as appropriate.</li> </ol> <div class="ds-selector-tabs"> <section> <h5 id="android" data-text="Android" tabindex="-1">Android</h5> <ol> <li>Select the <b>Android</b> application type.</li> <li>Enter a name for the OAuth client. This name is displayed on your project's <a href="https://console.developers.google.com/apis/credentials">Credentials page</a> to identify the client.</li> <li>Enter the package name of your Android app. This value is defined in the <a href="https://developer.android.com/guide/topics/manifest/manifest-element#package" rel="external"> <code translate="no" dir="ltr">package</code> attribute of the <code translate="no" dir="ltr"><manifest></code> element</a> in your app manifest file. </li> <li>Enter the SHA-1 signing certificate fingerprint of the app distribution. <ul> <li>If your app uses <a href="https://support.google.com/googleplay/android-developer/answer/7384423" rel="external">app signing by Google Play</a>, copy the SHA-1 fingerprint from the app signing page of the Play Console.</li> <li>If you manage your own keystore and signing keys, use the <kbd>keytool</kbd> utility included with Java to print certificate information in a human-readable format. Copy the <code translate="no" dir="ltr">SHA1</code> value in the <code translate="no" dir="ltr">Certificate fingerprints</code> section of the <kbd>keytool</kbd> output. See <a href="/android/guides/client-auth">Authenticating Your Client</a> in the Google APIs for Android documentation for more information.</li> </ul> </li> <li>(Optional) <a href="#verify-app-ownership">Verify ownership</a> of your Android application.</li> <li>Click <b>Create</b>.</li> </ol> </section> <section> <h5 id="ios" data-text="iOS" tabindex="-1">iOS</h5> <ol> <li>Select the <b>iOS</b> application type.</li> <li>Enter a name for the OAuth client. This name is displayed on your project's <a href="https://console.developers.google.com/apis/credentials">Credentials page</a> to identify the client.</li> <li>Enter the bundle identifier for your app. The bundle ID is the value of the <a href="https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleidentifier" class="external" rel="external">CFBundleIdentifier</a> key in your app's information property list resource file (<kbd>info.plist</kbd>). The value is most commonly displayed in the General pane or the Signing & Capabilities pane of the Xcode project editor. The bundle ID is also displayed in the General Information section of the App Information page for the app on <a href="https://appstoreconnect.apple.com/" class="external" rel="external">Apple's App Store Connect site</a>. <p>Confirm that you are using the correct bundle ID for your app, as you won't be able to change it if you are using the App Check feature.</p> </li> <li>(Optional) <p>Enter your app's App Store ID if the app is published in Apple's App Store. The Store ID is a numeric string included in every Apple App Store URL.</p> <ol> <li>Open the <a href="https://www.apple.com/ios/app-store/" class="external" rel="external">Apple App Store app</a> on your iOS or iPadOS device.</li> <li>Search for your app.</li> <li>Select the Share button (square and arrow up symbol).</li> <li>Select <b>Copy Link</b>.</li> <li>Paste the link into a text editor. The App Store ID is the final part of the URL. <p>Example: <code translate="no" dir="ltr">https://apps.apple.com/app/google/id<var translate="no">284815942</var></code></p> </li> </ol></li> <li>(Optional) <p>Enter your Team ID. See <a href="https://help.apple.com/developer-account/#/dev55c3c710c" title="Apple Developer Account Help: Locate your Team ID" class="external" rel="external">Locate your Team ID</a> in the Apple Developer Account documentation for more information.</p> <b>Note:</b> The Team ID field is required if you are enabling App Check for your client. </li> <li>(Optional) <p>Enable App Check for your iOS app. When you enable App Check, Apple's <a class="external" href="https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity">App Attest service</a> is used to verify that OAuth 2.0 requests originating from your OAuth client are genuine and come from your app. This helps to reduce the risk of app impersonation. <a href="#enable-app-check-for-your-ios-client">Learn more about enabling App Check for your iOS app</a>. </p> </li> <li>Click <b>Create</b>.</li> </ol> </section> <section> <h5 id="uwp" data-text="UWP" tabindex="-1">UWP</h5> <ol> <li>Select the <b>Universal Windows Platform</b> application type.</li> <li>Enter a name for the OAuth client. This name is displayed on your project's <a href="https://console.developers.google.com/apis/credentials">Credentials page</a> to identify the client.</li> <li>Enter your app's 12-character Microsoft Store ID. You can find this value in <a href="https://partner.microsoft.com/dashboard" class="external" rel="external">Microsoft Partner Center</a> on the <a href="https://docs.microsoft.com/windows/uwp/publish/view-app-identity-details" title="Microsoft Windows Dev Center: View app identity details" class="external" rel="external">App identity</a> page in the App management section.</li> <li>Click <b>Create</b>.</li> </ol> <p>For UWP apps, the custom URI scheme cannot be longer than 39 characters.</p> </section> </div> <h3 id="identify-access-scopes" data-text="Identify access scopes" tabindex="-1">Identify access scopes</h3> <p>Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there may be an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.</p> <p>Before you start implementing OAuth 2.0 authorization, we recommend that you identify the scopes that your app will need permission to access.</p> <aside class="note"><b>Note:</b> Incremental authorization is not supported for installed apps or devices.</aside> <p>The <a href="/identity/protocols/oauth2/scopes">OAuth 2.0 API Scopes</a> document contains a full list of scopes that you might use to access Google APIs.</p> <aside class="warning">If your public application uses scopes that permit access to certain user data, it must complete a verification process. If you see <strong>unverified app</strong> on the screen when testing your application, you must submit a verification request to remove it. Find out more about <a href="https://support.google.com/cloud/answer/7454865" class="external" target="_blank">unverified apps</a> and get answers to <a href="https://support.google.com/cloud/answer/9110914" class="external" target="_blank"> frequently asked questions about app verification</a> in the Help Center. </aside> <h2 id="obtainingaccesstokens" data-text="Obtaining OAuth 2.0 access tokens" tabindex="-1">Obtaining OAuth 2.0 access tokens</h2> <p>The following steps show how your application interacts with Google's OAuth 2.0 server to obtain a user's consent to perform an API request on the user's behalf. Your application must have that consent before it can execute a Google API request that requires user authorization.</p> <h3 id="step1-code-verifier" data-text="Step 1: Generate a code verifier and challenge" tabindex="-1">Step 1: Generate a code verifier and challenge</h3> <p>Google supports the <a href="https://tools.ietf.org/html/rfc7636">Proof Key for Code Exchange</a> (PKCE) protocol to make the installed app flow more secure. A unique code verifier is created for every authorization request, and its transformed value, called "code_challenge", is sent to the authorization server to obtain the authorization code.</p> <h4 id="create-code-challenge" data-text="Create the code verifier" tabindex="-1">Create the code verifier</h4> <p>A <code translate="no" dir="ltr">code_verifier</code> is a high-entropy cryptographic random string using the unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~", with a minimum length of 43 characters and a maximum length of 128 characters.</p> <p>The code verifier should have enough entropy to make it impractical to guess the value.</p> <h4 id="create-the-code-challenge" data-text="Create the code challenge" tabindex="-1">Create the code challenge</h4> <p>Two methods of creating the code challenge are supported.</p> <table class="responsive"> <thead> <tr> <th colspan="2">Code Challenge Generation Methods</th> </tr> </thead> <tbody> <tr> <td><b>S256 (recommended)</b></td> <td>The code challenge is the Base64URL (with no padding) encoded SHA256 hash of the code verifier.<br> <div></div><devsite-code><pre class="notranslate" dir="ltr" is-upgraded> <code translate="no" dir="ltr">code_challenge</code> = BASE64URL-ENCODE(SHA256(ASCII(<code translate="no" dir="ltr">code_verifier</code>)))</pre></devsite-code> </td> </tr> <tr> <td><b>plain</b></td> <td>The code challenge is the same value as the code verifier generated above.<br> <div></div><devsite-code><pre class="notranslate" dir="ltr" is-upgraded> <code translate="no" dir="ltr">code_challenge</code> = <code translate="no" dir="ltr">code_verifier</code></pre></devsite-code> </td> </tr> </tbody> </table> <h3 id="step-2:-send-a-request-to-googles-oauth-2.0-server" data-text="Step 2: Send a request to Google's OAuth 2.0 server" tabindex="-1">Step 2: Send a request to Google's OAuth 2.0 server</h3> <p>To obtain user authorization, send a request to Google's authorization server at <code translate="no" dir="ltr">https://accounts.google.com/o/oauth2/v2/auth</code>. This endpoint handles active session lookup, authenticates the user, and obtains user consent. The endpoint is only accessible over SSL, and it refuses HTTP (non-SSL) connections.</p> <p>The authorization server supports the following query string parameters for installed applications:</p> <table class="responsive details"> <thead> <tr> <th colspan="2">Parameters</th> </tr> </thead> <tbody> <tr id="request-parameter-client_id"> <td><code translate="no" dir="ltr">client_id</code></td> <td><strong>Required</strong> <p>The client ID for your application. You can find this value in the API Console <a href="https://console.developers.google.com/apis/credentials">Credentials page</a>.</p> </td> </tr> <tr id="request-parameter-redirect_uri"> <td><code translate="no" dir="ltr">redirect_uri</code></td> <td><strong>Required</strong> <p>Determines how Google's authorization server sends a response to your app. There are several redirect options available to installed apps, and you will have set up your <a href="#creatingcred">authorization credentials</a> with a particular redirect method in mind.</p> <p>The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client, which you configured in your client's API Console <a href="https://console.developers.google.com/apis/credentials">Credentials page</a>. If this value doesn't match an authorized URI, you will get a <code translate="no" dir="ltr">redirect_uri_mismatch</code> error.</p> <p>The table below shows the appropriate <code translate="no" dir="ltr">redirect_uri</code> parameter value for each method:</p> <table class="responsive"> <thead> <tr> <th colspan="2"><code translate="no" dir="ltr">redirect_uri</code> values</th> </tr> </thead> <tbody> <tr> <td><strong>Custom URI scheme</strong></td> <td><code translate="no" dir="ltr"><var translate="no">com.example.app</var>:<var translate="no">redirect_uri_path</var></code> <p>or</p> <code translate="no" dir="ltr"><var translate="no">com.googleusercontent.apps.123</var>:<var translate="no">redirect_uri_path</var> </code> <ul> <li><var translate="no">com.example.app</var> is the reverse DNS notation of a domain under your control. The custom scheme must contain a period to be valid.</li> <li><var translate="no">com.googleusercontent.apps.123</var> is the reverse DNS notation of the client ID.</li> <li><var translate="no">redirect_uri_path</var> is an optional path component, such as <code translate="no" dir="ltr">/oauth2redirect</code>. Note that the path should begin with a single slash, which is different from regular HTTP URLs.</li> </ul> <aside class="deprecated"> <b>Note</b> : Custom URI schemes are no longer supported on Chrome apps and are disabled by default on Android. <a href="#redirect-uri_custom-scheme">Learn more</a> about custom scheme alternatives for Android and Chrome apps. </aside> </td> </tr> <tr> <td><strong>Loopback IP address</strong></td> <td><code translate="no" dir="ltr">http://127.0.0.1:<var translate="no">port</var></code> or <code translate="no" dir="ltr">http://[::1]:<var translate="no">port</var></code> <p>Query your platform for the relevant loopback IP address and start an HTTP listener on a random available port. Substitute <var translate="no">port</var> with the actual port number your app listens on.</p> <p>Note that support for the loopback IP address redirect option on <b>mobile apps</b> is <a href="https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html#disallowed-loopback"> DEPRECATED</a>.</p></td> </tr> </table> </td> </tr> <tr id="request-parameter-response_type"> <td><code translate="no" dir="ltr">response_type</code></td> <td><strong>Required</strong> <p>Determines whether the Google OAuth 2.0 endpoint returns an authorization code.</p> <p>Set the parameter value to <code translate="no" dir="ltr">code</code> for installed applications.</p> </td> </tr> <tr id="request-parameter-scope"> <td id="scope"><code translate="no" dir="ltr">scope</code></td> <td><strong>Required</strong> <p>A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values inform the consent screen that Google displays to the user.</p> <p>Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there is an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.</p> </td> </tr> <tr id="request-parameter-code-challenge"> <td><code translate="no" dir="ltr">code_challenge</code></td> <td><strong>Recommended</strong> <p>Specifies an encoded <code translate="no" dir="ltr">code_verifier</code> that will be used as a server-side challenge during authorization code exchange. See <a href="/identity/protocols/oauth2/native-app#create-code-challenge">create code challenge</a> section above for more information.</p></td> </tr> <tr id="request-parameter-code-challenge-method"> <td><code translate="no" dir="ltr">code_challenge_method</code></td> <td><strong>Recommended</strong> <p>Specifies what method was used to encode a <code translate="no" dir="ltr">code_verifier</code> that will be used during authorization code exchange. This parameter must be used with the <code translate="no" dir="ltr">code_challenge</code> parameter described above. The value of the <code translate="no" dir="ltr">code_challenge_method</code> defaults to <code translate="no" dir="ltr">plain</code> if not present in the request that includes a <code translate="no" dir="ltr">code_challenge</code>. The only supported values for this parameter are <code translate="no" dir="ltr">S256</code> or <code translate="no" dir="ltr">plain</code>.</td> </tr> <tr id="request-parameter-state"> <td><code translate="no" dir="ltr">state</code></td> <td><strong>Recommended</strong> <p>Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. The server returns the exact value that you send as a <code translate="no" dir="ltr">name=value</code> pair in the URL fragment identifier (<code translate="no" dir="ltr">#</code>) of the <code translate="no" dir="ltr">redirect_uri</code> after the user consents to or denies your application's access request.</p> <p>You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery. Since your <code translate="no" dir="ltr">redirect_uri</code> can be guessed, using a <code translate="no" dir="ltr">state</code> value can increase your assurance that an incoming connection is the result of an authentication request. If you generate a random string or encode the hash of a cookie or another value that captures the client's state, you can validate the response to additionally ensure that the request and response originated in the same browser, providing protection against attacks such as <a href="https://datatracker.ietf.org/doc/html/rfc6749#section-10.12">cross-site request forgery</a>. See the <a href="/identity/protocols/oauth2/openid-connect#createxsrftoken">OpenID Connect</a> documentation for an example of how to create and confirm a <code translate="no" dir="ltr">state</code> token.</p> <aside class="special"> <b>Important:</b> The OAuth client must prevent CSRF as called out in the <a href="https://datatracker.ietf.org/doc/html/rfc6749#section-10.12">OAuth2 Specification </a>. One way to achieve this is by using the <code translate="no" dir="ltr">state</code> parameter to maintain state between your authorization request and the authorization server's response. </aside> </td> </tr> <tr id="request-parameter-login_hint"> <td><code translate="no" dir="ltr">login_hint</code></td> <td><strong>Optional</strong> <p>If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Google Authentication Server. The server uses the hint to simplify the login flow either by prefilling the email field in the sign-in form or by selecting the appropriate multi-login session.</p> <p>Set the parameter value to an email address or <code translate="no" dir="ltr">sub</code> identifier, which is equivalent to the user's Google ID.</p> </td> </tr> </tbody> </table> <aside class="note"><b>Note:</b> incremental authorization with installed apps is not supported due to the fact that the client cannot keep the <code translate="no" dir="ltr">client_secret</code> confidential.</aside> <h4 id="sample-authorization-urls" data-text="Sample authorization URLs" tabindex="-1">Sample authorization URLs</h4> <p>The tabs below show sample authorization URLs for the different redirect URI options.</p> <p>The URLs are identical except for the value of the <code translate="no" dir="ltr">redirect_uri</code> parameter. The URLs also contain the required <code translate="no" dir="ltr">response_type</code> and <code translate="no" dir="ltr">client_id</code> parameters as well as the optional <code translate="no" dir="ltr">state</code> parameter. Each URL contains line breaks and spaces for readability.</p> <div class="ds-selector-tabs" data-ds-scope="lang"> <section> <h3 class="hide-from-toc" id="custom-uri-scheme" data-text="Custom URI scheme" tabindex="-1">Custom URI scheme</h3> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=<strong>com.example.app%3A/oauth2redirect</strong>& client_id=<var translate="no">client_id</var></pre></devsite-code> </section> <section> <h3 class="hide-from-toc" id="loopback-ip-address" data-text="Loopback IP address" tabindex="-1">Loopback IP address</h3> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded>https://accounts.google.com/o/oauth2/v2/auth? scope=email%20profile& response_type=code& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken& redirect_uri=<strong>http%3A//127.0.0.1%3A9004</strong>& client_id=<var translate="no">client_id</var></pre></devsite-code> </section> </div> <h3 id="handlingresponse" data-text="Step 3: Google prompts user for consent" tabindex="-1">Step 3: Google prompts user for consent</h3> <p>In this step, the user decides whether to grant your application the requested access. At this stage, Google displays a consent window that shows the name of your application and the Google API services that it is requesting permission to access with the user's authorization credentials and a summary of the scopes of access to be granted. The user can then consent to grant access to one or more scopes requested by your application or refuse the request.</p> <p>Your application doesn't need to do anything at this stage as it waits for the response from Google's OAuth 2.0 server indicating whether any access was granted. That response is explained in the following step.</p> <section aria-labelledby="authorization-errors"> <h4 id="authorization-errors" data-text="Errors" tabindex="-1">Errors</h4> <p>Requests to Google's OAuth 2.0 authorization endpoint may display user-facing error messages instead of the expected authentication and authorization flows. Common error codes and suggested resolutions are listed below.</p> <section aria-labelledby="authorization-errors-admin-policy-enforced"> <h5 id="authorization-errors-admin-policy-enforced" data-text="admin_policy_enforced" tabindex="-1"><code translate="no" dir="ltr">admin_policy_enforced</code></h5> <p>The Google Account is unable to authorize one or more scopes requested due to the policies of their Google Workspace administrator. See the Google Workspace Admin help article <a href="https://support.google.com/a/answer/7281227"> Control which third-party & internal apps access Google Workspace data</a> for more information about how an administrator may restrict access to all scopes or sensitive and restricted scopes until access is explicitly granted to your OAuth client ID.</p> </section> <section aria-labelledby="authorization-errors-disallowed-useragent"> <h5 id="authorization-errors-disallowed-useragent" data-text="disallowed_useragent" tabindex="-1"><code translate="no" dir="ltr">disallowed_useragent</code></h5> <p>The authorization endpoint is displayed inside an embedded user-agent disallowed by Google's <a href="/identity/protocols/oauth2/policies#browsers">OAuth 2.0 Policies</a>.</p> <devsite-selector> <section> <h6 id="android_1" data-text="Android" tabindex="-1">Android</h6> <p>Android developers may encounter this error message when opening authorization requests in <a href="https://developer.android.com/reference/android/webkit/WebView" rel="external" class="external"><code translate="no" dir="ltr">android.webkit.WebView</code></a>. Developers should instead use Android libraries such as <a href="/identity/sign-in/android">Google Sign-In for Android</a> or OpenID Foundation's <a href="https://openid.github.io/AppAuth-Android/" rel="external" class="external">AppAuth for Android</a>.</p> <p>Web developers may encounter this error when an Android app opens a general web link in an embedded user-agent and a user navigates to Google's OAuth 2.0 authorization endpoint from your site. Developers should allow general links to open in the default link handler of the operating system, which includes both <a href="https://developer.android.com/training/app-links" rel="external" class="external">Android App Links</a> handlers or the default browser app. The <a href="https://developer.chrome.com/docs/android/custom-tabs/overview/" rel="external" class="external">Android Custom Tabs</a> library is also a supported option.</p> </section> <section> <h6 id="ios_1" data-text="iOS" tabindex="-1">iOS</h6> <p>iOS and macOS developers may encounter this error when opening authorization requests in <a href="https://developer.apple.com/documentation/webkit/wkwebview" rel="external" class="external"><code translate="no" dir="ltr">WKWebView</code></a>. Developers should instead use iOS libraries such as <a href="/identity/sign-in/ios">Google Sign-In for iOS</a> or OpenID Foundation's <a href="https://openid.github.io/AppAuth-iOS/" rel="external" class="external">AppAuth for iOS</a>.</p> <p>Web developers may encounter this error when an iOS or macOS app opens a general web link in an embedded user-agent and a user navigates to Google's OAuth 2.0 authorization endpoint from your site. Developers should allow general links to open in the default link handler of the operating system, which includes both <a href="https://developer.apple.com/ios/universal-links/" rel="external" class="external">Universal Links</a> handlers or the default browser app. The <a href="https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller" rel="external" class="external"><code translate="no" dir="ltr">SFSafariViewController</code></a> library is also a supported option.</p> </section> </devsite-selector> </section> <section aria-labelledby="authorization-errors-org-internal"> <h5 id="authorization-errors-org-internal" data-text="org_internal" tabindex="-1"><code translate="no" dir="ltr">org_internal</code></h5> <p>The OAuth client ID in the request is part of a project limiting access to Google Accounts in a specific <a href="https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy#organizations"> Google Cloud Organization</a>. For more information about this configuration option see the <a href="https://support.google.com/cloud/answer/10311615#user-type">User type</a> section in the Setting up your OAuth consent screen help article.</p> </section> <section aria-labelledby="authorization-errors-invalid-grant"> <h5 id="authorization-errors-invalid-grant" data-text="invalid_grant" tabindex="-1"><code translate="no" dir="ltr">invalid_grant</code></h5> <p> If you are using a <a href="/identity/protocols/oauth2/native-app#step1-code-verifier">code verifier and challenge</a>, the <code translate="no" dir="ltr">code_callenge</code> parameter is invalid or missing. Ensure that the <code translate="no" dir="ltr">code_challenge</code> parameter is set correctly.</p> <p><a href="#offline">When refreshing an access token</a>, the token may have expired or has beeninvalidated. Authenticate the user again and ask for user consent to obtain new tokens. If you are continuing to see this error, ensure that your application has been configured correctly and that you are using the correct tokens and parameters in your request. Otherwise, the user account may have been deleted or disabled.</p> </section> <section aria-labelledby="authorization-errors-redirect-uri-mismatch"> <h5 id="authorization-errors-redirect-uri-mismatch" data-text="redirect_uri_mismatch" tabindex="-1"><code translate="no" dir="ltr">redirect_uri_mismatch</code></h5> <p>The <code translate="no" dir="ltr">redirect_uri</code> passed in the authorization request does not match an authorized redirect URI for the OAuth client ID. Review authorized redirect URIs in the Google API Console <a href="https://console.developers.google.com/apis/credentials">Credentials page</a>.</p> <p>The passed <code translate="no" dir="ltr">redirect_uri</code> may be invalid for the client type.</p> <p>The <code translate="no" dir="ltr">redirect_uri</code> parameter may refer to the OAuth out-of-band (OOB) flow that has been deprecated and is no longer supported. Refer to the <a href="/identity/protocols/oauth2/resources/oob-migration">migration guide</a> to update your integration.</p> </section> <section aria-labelledby="authorization-errors-invalid-request"> <h5 id="authorization-errors-invalid-request" data-text="invalid_request" tabindex="-1"><code translate="no" dir="ltr">invalid_request</code></h5> <p>There was something wrong with the request you made. This could be due to a number of reasons: </p> <ul> <li>The request was not properly formatted</li> <li>The request was missing required parameters</li> <li> The request uses an authorization method that Google doesn't support. Verify your OAuth integration uses a recommended integration method</li> <li> A custom scheme is used for the redirect uri : If you see the error message <strong> Custom URI scheme is not supported on Chrome apps</strong> or <strong>Custom URI scheme is not enabled for your Android client</strong>, it means you are using a custom URI scheme which isn't supported on Chrome apps and is disabled by default on Android. <a href="#redirect-uri_custom-scheme">Learn more</a> about custom URI scheme alternatives</li> </ul> </section> </section> <h3 id="handlingresponse" data-text="Step 4: Handle the OAuth 2.0 server response" tabindex="-1">Step 4: Handle the OAuth 2.0 server response</h3> <p>The manner in which your application receives the authorization response depends on the <a href="#creatingcred">redirect URI scheme</a> that it uses. Regardless of the scheme, the response will either contain an authorization code (<code translate="no" dir="ltr">code</code>) or an error (<code translate="no" dir="ltr">error</code>). For example, <code translate="no" dir="ltr">error=access_denied</code> indicates that the user declined the request.</p> <p>If the user grants access to your application, you can exchange the authorization code for an access token and a refresh token as described in the next step.</p> <h3 id="exchange-authorization-code" data-text="Step 5: Exchange authorization code for refresh and access tokens" tabindex="-1">Step 5: Exchange authorization code for refresh and access tokens</h3> <p>To exchange an authorization code for an access token, call the <code translate="no" dir="ltr">https://oauth2.googleapis.com/token</code> endpoint and set the following parameters:</p> <table class="responsive"> <thead> <tr> <th colspan="2">Fields</th> </tr> </thead> <tbody> <tr> <td><code translate="no" dir="ltr">client_id</code></td> <td>The client ID obtained from the API Console <a href="https://console.developers.google.com/apis/credentials">Credentials page</a>.</td> </tr> <tr> <td><code translate="no" dir="ltr">client_secret</code></td> <td>The client secret obtained from the API Console <a href="https://console.developers.google.com/apis/credentials">Credentials page</a>.</td> </tr> <tr> <td><code translate="no" dir="ltr">code</code></td> <td>The authorization code returned from the initial request.</td> </tr> <tr> <td><code translate="no" dir="ltr">code_verifier</code></td> <td>The code verifier you created in <a href="/identity/protocols/oauth2/native-app#step1-code-verifier">Step 1</a>.</td> </tr> <tr> <td><code translate="no" dir="ltr">grant_type</code></td> <td><a href="https://tools.ietf.org/html/rfc6749#section-4.1.3">As defined in the OAuth 2.0 specification</a>, this field's value must be set to <code translate="no" dir="ltr">authorization_code</code>.</td> </tr> <tr> <td><code translate="no" dir="ltr">redirect_uri</code></td> <td>One of the redirect URIs listed for your project in the API Console <a href="https://console.developers.google.com/apis/credentials">Credentials page</a> for the given <code translate="no" dir="ltr">client_id</code>.</td> </tr> </tbody> </table> <p>The following snippet shows a sample request:</p> <div></div><devsite-code><pre class="notranslate" dir="ltr" is-upgraded>POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=<var class="apiparam" translate="no">your_client_id</var>& client_secret=<var class="apiparam" translate="no">your_client_secret</var>& redirect_uri=http://127.0.0.1:9004& grant_type=authorization_code</pre></devsite-code> <p>Google responds to this request by returning a JSON object that contains a short-lived access token and a refresh token. </p> <p>The response contains the following fields:</p> <table class="responsive details"> <thead> <tr> <th colspan="2">Fields</th> </tr> </thead> <tbody> <tr> <td><code translate="no" dir="ltr">access_token</code></td> <td>The token that your application sends to authorize a Google API request.</td> </tr> <tr> <td><code translate="no" dir="ltr">expires_in</code></td> <td>The remaining lifetime of the access token in seconds.</td> </tr> <tr> <td><code translate="no" dir="ltr">id_token</code></td> <td><b>Note:</b> This property is only returned if your request included an identity scope, such as <code translate="no" dir="ltr">openid</code>, <code translate="no" dir="ltr">profile</code>, or <code translate="no" dir="ltr">email</code>. The value is a JSON Web Token (JWT) that contains digitally signed identity information about the user.</td> </tr> <tr> <td><code translate="no" dir="ltr">refresh_token</code></td> <td>A token that you can use to obtain a new access token. Refresh tokens are valid until the user revokes access. Note that refresh tokens are always returned for installed applications. </td> </tr> <tr> <td><code translate="no" dir="ltr">scope</code></td> <td>The scopes of access granted by the <code translate="no" dir="ltr">access_token</code> expressed as a list of space-delimited, case-sensitive strings.</td> </tr> <tr> <td><code translate="no" dir="ltr">token_type</code></td> <td>The type of token returned. At this time, this field's value is always set to <code translate="no" dir="ltr">Bearer</code>.</td> </tr> </tbody> </table> <aside class="key-point"><b>Important:</b> Your application should store both tokens in a secure, long-lived location that is accessible between different invocations of your application. The refresh token enables your application to obtain a new access token if the one that you have expires. As such, if your application loses the refresh token, the user will need to repeat the OAuth 2.0 consent flow so that your application can obtain a new refresh token.</aside> <p>The following snippet shows a sample response:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"access_token"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"1/fFAGRNJru1FTz70BzhT3Zg"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"expires_in"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">3920</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"token_type"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Bearer"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"scope"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"refresh_token"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"</span> <span class="devsite-syntax-p">}</span></pre></devsite-code> <aside class="note"><b>Note:</b> Your application should ignore any unrecognized fields included in the response.</aside> <h3 id="check-granted-scopes" data-text="Step 6: Check which scopes users granted" tabindex="-1">Step 6: Check which scopes users granted</h3> <p>When requesting multiple scopes at once, users may not grant all scopes your app requests. Your app should always check which scopes were granted by the user and handle any denial of scopes by disabling relevant features. Review <a href="/identity/protocols/oauth2/resources/granular-permissions">How to handle granular permissions</a> for more information. </p> <p> To check whether the user has granted your application access to a particular scope, exam the <code translate="no" dir="ltr">scope</code> field in the access token response. The scopes of access granted by the access_token expressed as a list of space-delimited, case-sensitive strings. </p> <p> For example, the following sample access token response indicates that the user has granted your application access to the read-only Drive activity and Calendar events permissions: </p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Carbon"><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"access_token"</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"1/fFAGRNJru1FTz70BzhT3Zg"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"expires_in"</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mi">3920</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"token_type"</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"Bearer"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><b><span class="devsite-syntax-s">"scope"</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly"</span></b><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"refresh_token"</span><span class="devsite-syntax-p">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span></pre></devsite-code> <h2 id="callinganapi" data-text="Calling Google APIs" tabindex="-1">Calling Google APIs</h2> <p>After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account if the scope(s) of access required by the API have been granted. To do this, include the access token in a request to the API by including either an <code translate="no" dir="ltr">access_token</code> query parameter or an <code translate="no" dir="ltr">Authorization</code> HTTP header <code translate="no" dir="ltr">Bearer</code> value. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when <a href="/drive/api/v2/reference#Files">calling the Drive Files API</a>).</p> <p>You can try out all the Google APIs and view their scopes at the <a href="https://developers.google.com/oauthplayground/">OAuth 2.0 Playground</a>.</p> <h4 id="http-get-examples" data-text="HTTP GET examples" tabindex="-1">HTTP GET examples</h4> <p>A call to the <a href="/drive/v2/reference/files/list"> <code translate="no" dir="ltr">drive.files</code></a> endpoint (the Drive Files API) using the <code translate="no" dir="ltr">Authorization: Bearer</code> HTTP header might look like the following. Note that you need to specify your own access token:<p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded> GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com <strong>Authorization: Bearer <var translate="no">access_token</var></strong></pre></devsite-code> <p>Here is a call to the same API for the authenticated user using the <code translate="no" dir="ltr">access_token</code> query string parameter:</p> <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded> GET https://www.googleapis.com/drive/v2/files?access_token=<var translate="no">access_token</var></pre></devsite-code> <h4 id="curl-examples" data-text="curl examples" tabindex="-1"><code translate="no" dir="ltr">curl</code> examples</h4> <p>You can test these commands with the <code translate="no" dir="ltr">curl</code> command-line application. Here's an example that uses the HTTP header option (preferred):</p> <div></div><devsite-code><pre class="devsite-terminal" translate="no" dir="ltr" is-upgraded> curl -H "Authorization: Bearer <var translate="no">access_token</var>" https://www.googleapis.com/drive/v2/files</pre></devsite-code> <p>Or, alternatively, the query string parameter option:</p> <div></div><devsite-code><pre class="devsite-terminal" translate="no" dir="ltr" is-upgraded> curl https://www.googleapis.com/drive/v2/files?access_token=<var translate="no">access_token</var></pre></devsite-code> <h2 id="offline" data-text="Refreshing an access token" tabindex="-1">Refreshing an access token</h2> <p>Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.</p> <p>To refresh an access token, your application sends an HTTPS <code class="notranslate" dir="ltr">POST</code> request to Google's authorization server (<code translate="no" dir="ltr">https://oauth2.googleapis.com/token</code>) that includes the following parameters: <table class="responsive"> <thead> <tr> <th colspan="2">Fields</th> </tr> </thead> <tbody> <tr> <td><code translate="no" dir="ltr">client_id</code></td> <td>The client ID obtained from the <a href="https://console.developers.google.com/">API Console</a>.</td> </tr> <tr> <td><code translate="no" dir="ltr">client_secret</code></td> <td>The client secret obtained from the <a href="https://console.developers.google.com/">API Console</a>. (The <code translate="no" dir="ltr">client_secret</code> is not applicable to requests from clients registered as Android, iOS, or Chrome applications.) </td> </tr> <tr> <td><code translate="no" dir="ltr">grant_type</code></td> <td>As <a href="https://tools.ietf.org/html/rfc6749#section-6" class="external">defined in the OAuth 2.0 specification</a>, this field's value must be set to <code translate="no" dir="ltr">refresh_token</code>.</td> </tr> <tr> <td><code translate="no" dir="ltr">refresh_token</code></td> <td>The refresh token returned from the authorization code exchange.</td> </tr> </tbody> </table> <p>The following snippet shows a sample request:</p> <div></div><devsite-code><pre class="notranslate" dir="ltr" is-upgraded> POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=<var translate="no">your_client_id</var>& client_secret=<var translate="no">your_client_secret</var>& refresh_token=<var translate="no">refresh_token</var>& grant_type=refresh_token</pre></devsite-code> <p>As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:</p> <div></div><devsite-code><pre class="devsite-click-to-copy notranslate" dir="ltr" is-upgraded syntax="JavaScript"><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"access_token"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"1/fFAGRNJru1FTz70BzhT3Zg"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"expires_in"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">3920</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"scope"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly"</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"token_type"</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s2">"Bearer"</span> <span class="devsite-syntax-p">}</span></pre></devsite-code> <p>Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.</p> <h2 id="tokenrevoke" data-text="Revoking a token" tabindex="-1">Revoking a token</h2> <p>In some cases a user may wish to revoke access given to an application. A user can revoke access by visiting <a href="https://myaccount.google.com/permissions" class="external"> Account Settings</a>. See the <a href="https://support.google.com/accounts/answer/3466521#remove-access" class="external">Remove site or app access section of the Third-party sites & apps with access to your account</a> support document for more information.</p> <p>It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.</p> <p>To programmatically revoke a token, your application makes a request to <code translate="no" dir="ltr">https://oauth2.googleapis.com/revoke</code> and includes the token as a parameter:</p> <div></div><devsite-code><pre class="devsite-terminal" translate="no" dir="ltr" is-upgraded> curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token=<var translate="no">{token}</var></pre></devsite-code> <p>The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.</p> <p>If the revocation is successfully processed, then the HTTP status code of the response is <code translate="no" dir="ltr">200</code>. For error conditions, an HTTP status code <code translate="no" dir="ltr">400</code> is returned along with an error code.</p> <aside class="note"><b>Note:</b> Following a successful revocation response, it might take some time before the revocation has full effect.</aside> <h2 id="installed_app_redirect_methods" data-text="App redirect methods" tabindex="-1">App redirect methods</h2> <section> <h3 id="redirect-uri_custom-scheme" data-text="Custom URI scheme (Android, iOS, UWP)" tabindex="-1">Custom URI scheme (Android, iOS, UWP)</h3> <p> Custom URI schemes are a form of deeplinking that use a custom-defined scheme to open your app. </p> <aside class="deprecated"> <b>Important:</b> Custom URI schemes are no longer supported on new Chrome apps and are disabled by default on new Android clients due to the risk of app impersonation. </aside> <h4 id="alternative-to-using-custom-uri-schemes-on-android" data-text="Alternative to using custom URI schemes on Android" tabindex="-1">Alternative to using custom URI schemes on Android</h4> <p> Use the <a href="https://developers.google.com/identity/sign-in/android/offline-access" >Google Sign-In for Android SDK</a > which delivers the OAuth 2.0 response directly to your app, eliminating the need for a redirect URI. </p> <devsite-expandable> <h5 class="showalways" id="how-to-migrate-to-the-google-sign-in-for-android-sdk" data-text="How to migrate to the Google Sign-In for Android SDK" tabindex="-1">How to migrate to the Google Sign-In for Android SDK</h5> <p> If you use a custom scheme for your OAuth integration on Android, you would need to complete the following actions to fully migrate to using the recommended Google Sign-In for Android SDK: </p> <ol> <li>Update your code to use the Google Sign-In SDK.</li> <li>Disable support for custom scheme in the Google API Console.</li> </ol> <aside class="note"> <b>Note:</b> You should complete and deploy your code updates (accounting for adoption time across your user base or older devices) before disabling support for custom schemes in the Google API Console to avoid users getting an <a href="https://support.google.com/accounts/answer/12917337#400invalid" ><code translate="no" dir="ltr">invalid_request</code> error message</a > when they try to use your app. </aside> <p> Follow the below steps to migrate to the Google Sign-In Android SDK: </p> <ol> <li> Update your code to use the Google Sign-In Android SDK: <ol> <li> Examine your code to identify where you are <a href="#step-2:-send-a-request-to-googles-oauth-2.0-server" >sending a request to Google's OAuth 2.0 server</a >; if using a custom scheme, your request would look like the below: <div></div><devsite-code><pre translate="no" dir="ltr" is-upgraded> https://accounts.google.com/o/oauth2/v2/auth? scope=<var translate="no"><SCOPES></var>& response_type=code& &state=<var translate="no"><STATE></var>& <strong>redirect_uri=com.example.app:/oauth2redirect</strong>& client_id=<var translate="no"><CLIENT_ID></var> </pre></devsite-code> <code translate="no" dir="ltr">com.example.app:/oauth2redirect</code> is the custom scheme redirect URI in the above example. See the <a href="/identity/protocols/oauth2/native-app#request-parameter-redirect_uri"> <code translate="no" dir="ltr">redirect_uri</code></a> parameter definition for more details about the format of the custom URI scheme value. </li> <li> Make note of the <code translate="no" dir="ltr">scope</code> and <code translate="no" dir="ltr">client_id</code> request parameters which you would need to configure the Google Sign-In SDK. <aside class="note"> <b>Note:</b> If you are using a third-party library, review the library's configuration file to find these information. </aside> </li> <li> Follow the <a href="https://developers.google.com/identity/sign-in/android/legacy-start-integrating"> Start Integrating Google Sign-In into Your Android App</a > instructions to set up the SDK. You can skip the <strong>Get your backend server's OAuth 2.0 client ID</strong> step as you would re-use the <code translate="no" dir="ltr">client_id</code> you retrieved from the previous step. </li> <li> Follow the <a href="https://developers.google.com/identity/sign-in/android/offline-access#enable_server-side_api_access_for_your_app" > Enabling Server-Side API access</a > instructions. This includes the following steps: <ol> <li> Use the <code translate="no" dir="ltr">getServerAuthCode</code> method to retrieve an auth code for the scopes you are requesting permission for. </li> <li> Send the auth code to your app's backend to exchange it for an access & refresh token. </li> <li> Use the retrieved access token to make calls to Google APIs on behalf of the user. </li> </ol> <aside class="note"> <b>Note:</b> If your application does not require offline access, follow <a href="https://developers.google.com/identity/sign-in/android/additional-scopes"> these instructions</a> instead to request client-side API access. </aside> </li> </ol> </li> <li> Disable support for custom scheme in the Google API Console: <ol> <li> Go to your <a href="https://console.cloud.google.com/apis/credentials">OAuth 2.0 credentials</a> list and select your Android client. </li> <li> Navigate to the <strong>Advanced Settings</strong> section, uncheck the <strong>Enable Custom URI Scheme</strong> checkbox, and click <strong>Save</strong> to disable custom URI scheme support. </li> </ol> </li> </ol> </devsite-expandable> <h4 id="enabling-custom-uri-scheme" data-text="Enable custom URI scheme" tabindex="-1">Enable custom URI scheme</h4> If the recommended alternative does not work for you, you can enable custom URI schemes for your Android client by following the below instructions: <ol> <li> Go to your <a href="https://console.cloud.google.com/apis/credentials">OAuth 2.0 credentials</a> list and select your Android client. </li> <li> Navigate to the <strong>Advanced Settings</strong> section, check the <strong>Enable Custom URI Scheme</strong> checkbox, and click <strong>Save</strong> to enable custom URI scheme support. </li> </ol> <h4 id="alternative-to-using-custom-uri-schemes-on-chrome-apps" data-text=" Alternative to using custom URI schemes on Chrome apps" tabindex="-1"> Alternative to using custom URI schemes on Chrome apps</h4> <p> Use the <a href="https://developer.chrome.com/docs/extensions/mv3/tut_oauth/">Chrome Identity API</a> which delivers the OAuth 2.0 response directly to your app, eliminating the need for a redirect URI. </p> </section> <section> <h3 id="redirect-uri_loopback" data-text="Loopback IP address (macOS, Linux, Windows desktop)" tabindex="-1">Loopback IP address (macOS, Linux, Windows desktop)</h3> <aside class="deprecated"><b>Important:</b> The loopback IP address redirect option is DEPRECATED for the <b>Android</b>, <b>Chrome app</b>, and <b>iOS</b> OAuth client types. Review the <a href="/identity/protocols/oauth2/resources/loopback-migration">loopback IP address migration guide</a> for instructions on how to migrate to a supported alternative. </aside> <p>To receive the authorization code using this URL, your application must be listening on the local web server. That is possible on many, but not all, platforms. However, if your platform supports it, this is the recommended mechanism for obtaining the authorization code.</p> <p>When your app receives the authorization response, for best usability it should respond by displaying an HTML page that instructs the user to close the browser and return to your app.</p> <table class="responsive details"> <tr> <td><b>Recommended usage</b></td> <td>macOS, Linux, and Windows desktop (but not Universal Windows Platform) apps</td> </tr> <tr> <td><b>Form values</b></td> <td>Set the application type to <b>Desktop app</b>.</td> </tr> </table> <aside class="note"><b>Note:</b> See the <a href="#request-parameter-redirect_uri"><code translate="no" dir="ltr">redirect_uri</code></a> parameter definition for more information about the loopback IP address. It is also possible to use <code translate="no" dir="ltr">localhost</code> in place of the loopback IP, but this configuration may cause issues with client firewalls. Most, but not all, firewalls allow loopback communication.</aside> </section> <section> <h3 id="manual-copypaste-deprecated" data-text="Manual copy/paste (Deprecated)" tabindex="-1">Manual copy/paste (Deprecated)</h3> <aside class="deprecated"><b>Important:</b> The manual copy/paste option, also referred to as an out of band (OOB) redirect method, is <a href="https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html"> no longer supported</a>. Review the <a href="/identity/protocols/oauth2/resources/oob-migration">OOB migration guide</a> for instructions on how to migrate to a secure alternative. </aside> </section> <h2 id="protect_your_apps" data-text="Protect your apps" tabindex="-1">Protect your apps</h2> <section> <h3 id="verify-app-ownership" data-text="Verify app ownership (Android, Chrome)" tabindex="-1">Verify app ownership (Android, Chrome)</h3> <p>You can verify ownership of your application to reduce the risk of app impersonation.</p> <div class="ds-selector-tabs"> <section> <h5 id="android_2" data-text="Android" tabindex="-1">Android</h5> <aside class="note"> <b>Note:</b> Android app ownership verification is only available for Google Play apps. </aside> <p> To complete the verification process, you can use your Google Play Developer Account if you have one and your app is registered on the <a href="https://play.google.com/console/">Google Play Console</a>. The following requirements must be met for a successful verification: </p> <ul> <li> You must have a registered application in the Google Play Console with the same package name and SHA-1 signing certificate fingerprint as the Android OAuth client you are completing the verification for. </li> <li> You must have <strong>Admin</strong> permission for the app in the Google Play Console. <a href="https://support.google.com/googleplay/android-developer/answer/9844686" >Learn more</a > about access management in the Google Play Console. </li> </ul> <p> In the <strong>Verify App Ownership</strong> section of the Android client, click the <strong>Verify Ownership</strong> button to complete the verification process. </p> <p> If the verification is successful, a notification will be displayed to confirm the success of the verification process. Otherwise, an error prompt will be shown. </p> <p>To fix a failed verification, try the following:</p> <ul> <li> Make sure the app you are verifying is a registered app in the Google Play Console. </li> <li> Make sure you have <strong>Admin</strong> permission for the app in the Google Play Console. </li> </ul> </section> <section> <h5 id="chrome" data-text="Chrome" tabindex="-1">Chrome</h5> <p> To complete the verification process, you would use your Chrome Web Store Developer account. The following requirements must be met for a successful verification: </p> <ul> <li> You must have a registered item in the <a href="https://chrome.google.com/webstore/devconsole/" >Chrome Web Store Developer Dashboard</a > with the same item ID as the Chrome Extension OAuth client you are completing the verification for. </li> <li> You must be a publisher for the Chrome Web Store item. <a href="https://developer.chrome.com/docs/webstore/group-publishers/">Learn more</a> about access management in the Chrome Web Store Developer Dashboard. </li> </ul> <p> In the <strong>Verify App Ownership</strong> section of the Chrome Extension client, click the <strong>Verify Ownership</strong> button to complete the verification process. </p> <p> <b>Note:</b> Wait a few minutes before completing the verification process after granting access to your account. </p> <p> If the verification is successful, a notification will be displayed to confirm the success of the verification process. Otherwise, an error prompt will be shown. </p> <p>To fix a failed verification, try the following:</p> <ul> <li> Make sure there is a registered item in the Chrome Web Store Developer Dashboard with the same item ID as the Chrome Extension OAuth client you are completing the verification for. </li> <li> Make sure you are a publisher for the app, that is, you must either be the individual publisher of the app or a member of the group publisher of the app. <a href="https://developer.chrome.com/docs/webstore/group-publishers/">Learn more</a> about access management in the Chrome Web Store Developer Dashboard. </li> <li> If you just updated your group publisher list, verify that the group publisher membership list is synced in the Chrome Web Store Developer Dashboard. <a href="https://developer.chrome.com/docs/webstore/group-publishers/#adding-developers-to-or-removing-them-from-the-group-publisher" >Learn more</a > about syncing your publisher membership list. </li> </ul> </section> </div> </section> <section> <h3 id="ios-app-check" data-text="App Check (iOS only)" tabindex="-1">App Check (iOS only)</h3> <p> The <a href="https://developers.google.com/identity/sign-in/ios/appcheck">App Check</a> feature helps safeguard your iOS applications from unauthorized usage by using Apple's <a href="https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity" class="external" >App Attest service</a > to verify that requests made to Google OAuth 2.0 endpoints originate from your authentic applications. This helps to reduce the risk of app impersonation. </p> <h4 id="enable-app-check" data-text="Enable App Check for your iOS Client" tabindex="-1">Enable App Check for your iOS Client</h4> The following requirements must be met to successfully enable App Check for your iOS client: <ul> <li>You must specify a team ID for your iOS client.</li> <li> You must not use a wildcard in your bundle ID since it can resolve to more than one app. This means that the bundle ID must not include the asterisk (*) symbol. </li> </ul> <aside class="warning"> <b>Warning:</b> When App Check is enabled, you won't be able to edit your OAuth client bundle ID without creating a new client. Before creating your iOS client or enabling App Check, verify that you are using the correct bundle ID. Updating your bundle ID for an existing project can result in a broken experience for users of your apps if you are using the bundle ID as a redirect URI. </aside> To enable App Check, turn on the <b>Protect your OAuth client from abuse with Firebase App Check</b> toggle button in the edit view of your iOS client. <p> After enabling App Check, you will start seeing metrics related to OAuth requests from your client in the edit view of the OAuth client. Requests from unverified sources won't be blocked until you <a href="#enforce-app-check">enforce App Check</a>. The information in the metrics monitoring page can help you determine when to start enforcement. </p> <p> You might see errors related to the App Check feature when enabling App Check for your iOS app. To fix these errors, try the following: </p> <ul> <li>Verify that the bundle ID and team ID you specified are valid.</li> <li>Verify that you are not using a wildcard for the bundle ID.</li> </ul> <h4 id="enforce-app-check" data-text="Enforce App Check for your iOS Client" tabindex="-1">Enforce App Check for your iOS Client</h4> Enabling App Check for your app does not automatically block unrecognized requests. To enforce this protection, go to the edit view of your iOS client. There, you will see App Check metrics to the right of the page under the <b>Google Identity for iOS</b> section. The metrics include the following information: <ul> <li> <b>Number of verified requests</b> - requests that have a valid App Check token. After you enable App Check enforcement, only requests in this category will succeed. </li> <li> <b>Number of unverified requests: likely outdated client requests</b> - requests missing an App Check token; these request may be from an older version of your app that doesn't include an App Check implementation. </li> <li> <b>Number of unverified requests: unknown origin requests</b> - requests missing an App Check token that don't look like they are coming from your app. </li> <li> <b>Number of unverified requests: invalid requests</b> - requests with an invalid App Check token, which may be from an inauthentic client attempting to impersonate your app, or from emulated environments. </li> </ul> Review these metrics to understand how enforcing App Check will affect your users. <p> To enforce App Check, click the <b>ENFORCE</b> button and confirm your choice. Once enforcement is active, all unverified requests from your client will be rejected. </p> <p> <b>Note</b>: after you enable enforcement, it can take up to 15 minutes for the changes to take effect. </p> <h4 id="unenforce-app-check" data-text="Unenforce App Check for your iOS Client" tabindex="-1">Unenforce App Check for your iOS Client</h4> <p> Unenforcing App Check for your app will stop <a href="#enforce-app-check">enforcement</a> and will allow all requests from your client to Google OAuth 2.0 endpoints, including unverified requests. </p> <p> To unenforce App Check for your iOS client, navigate to the edit view of the iOS client and click the <b>UNENFORCE</b> button and confirm your choice. </p> <p> <b>Note</b>: after unenforcing App Check, it can take up to 15 minutes for the changes to take effect. </p> <h4 id="disable-app-check" data-text="Disable App Check for your iOS Client" tabindex="-1">Disable App Check for your iOS Client</h4> <p> Disabling App Check for your app will stop all App Check monitoring and <a href="#enforce-app-check">enforcement</a>. Consider <a href="#unenforce-app-check">unenforcing</a> App Check instead so you can continue monitoring metrics for your client. </p> <p> To disable App Check for your iOS client, navigate to the edit view of the iOS client and turn off the <b>Protect your OAuth client from abuse with Firebase App Check</b> toggle button. </p> <p> <b>Note</b>: after disabling App Check, it can take up to 15 minutes for the changes to take effect. </p> </section> <h2 id="further_reading" data-text="Further Reading" tabindex="-1">Further Reading</h2> <p>The IETF Best Current Practice <a href="https://tools.ietf.org/html/rfc8252">OAuth 2.0 for Native Apps</a> establishes many of the best practices documented here.</p> <section> <h2 id="cross-account-protection" data-text="Implementing Cross-Account Protection" tabindex="-1">Implementing Cross-Account Protection</h2> <p> An additional step you should take to protect your users' accounts is implementing Cross-Account Protection by utilizing Google's Cross-Account Protection Service. This service lets you subscribe to security event notifications which provide information to your application about major changes to the user account. You can then use the information to take action depending on how you decide to respond to events. </p> <p> Some examples of the event types sent to your app by Google's Cross-Account Protection Service are: </p> <ul> <li> <code translate="no" dir="ltr">https://schemas.openid.net/secevent/risc/event-type/sessions-revoked</code> </li> <li> <code translate="no" dir="ltr">https://schemas.openid.net/secevent/oauth/event-type/token-revoked</code> </li> <li> <code translate="no" dir="ltr">https://schemas.openid.net/secevent/risc/event-type/account-disabled</code> </li> </ul> <p> See the <a href="https://developers.google.com/identity/protocols/risc"> Protect user accounts with Cross-Account Protection page </a> for more information on how to implement Cross Account Protection and for the full list of available events. </p> </section> </div> <devsite-recommendations display="in-page" hidden yield> </devsite-recommendations> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <devsite-feedback position="footer" project-name="Authorization" product-id="5186570" bucket="Identity guides" context="External devsite feedback" version="t-devsite-webserver-20241114-r00-rc02.464922260396498922" data-label="Send Feedback Button" track-type="feedback" track-name="sendFeedbackLink" track-metadata-position="footer" class="nocontent" project-icon="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/touchicon-180-new.png" > <button> Send feedback </button> </devsite-feedback> <devsite-recommendations id="recommendations-link" yield></devsite-recommendations> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2024-11-14 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-thumb-rating-feedback"> <devsite-feedback position="thumb-rating" project-name="Authorization" product-id="5186570" bucket="Identity guides" context="External devsite feedback" version="t-devsite-webserver-20241114-r00-rc02.464922260396498922" data-label="Send Feedback Button" track-type="feedback" track-name="sendFeedbackLink" track-metadata-position="thumb-rating" class="nocontent" project-icon="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/touchicon-180-new.png" > <button> Need to tell us more? </button> </devsite-feedback> </template> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-11-14 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> <nav class="devsite-footer-promos nocontent" aria-label="Promotions"> <ul class="devsite-footer-promos-list"> <li class="devsite-footer-promo"> <a href="//github.com/googlesamples" class="devsite-footer-promo-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Promo Link (index 1)" > <picture> <img class="devsite-footer-promo-icon" src="/static/site-assets/logo-github.svg" loading="lazy" alt="GitHub"> </picture> <span class="devsite-footer-promo-label"> GitHub </span> </a> <div class="devsite-footer-promo-description">Fork our samples and try them yourself</div> </li> <li class="devsite-footer-promo"> <a href="//stackoverflow.com/questions/tagged/google-oauth" class="devsite-footer-promo-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Promo Link (index 2)" > <picture> <img class="devsite-footer-promo-icon" src="/static/site-assets/logo-stack-overflow.svg" loading="lazy" alt="Stack Overflow"> </picture> <span class="devsite-footer-promo-label"> Stack Overflow </span> </a> <div class="devsite-footer-promo-description">Ask a question under the google-oauth tag</div> </li> <li class="devsite-footer-promo"> <a href="//googledevelopers.blogspot.com/search/label/oauth" class="devsite-footer-promo-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Promo Link (index 3)" > <picture> <img class="devsite-footer-promo-icon" src="/static/site-assets/developers_64dp.png" loading="lazy" alt="Blog"> </picture> <span class="devsite-footer-promo-label"> Blog </span> </a> <div class="devsite-footer-promo-description">The latest news on the Google Developers blog</div> </li> </ul> </nav> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Product Info</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/terms" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Terms of Service </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/terms/api-services-user-data-policy" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > APIs User Data Policy </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/identity/branding-guidelines" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Branding Guidelines </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Stack Overflow</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://stackoverflow.com/questions/tagged/google-identity" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Google Identity </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//stackoverflow.com/questions/tagged/google-signin" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Sign In With Google </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://stackoverflow.com/questions/tagged/google-oauth" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Google OAuth 2.0 and OpenID Connect </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//stackoverflow.com/questions/tagged/account-linking" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Google Account Linking </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Developer consoles</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="//console.developers.google.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Google API Console </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//console.cloud.google.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Google Cloud Platform Console </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//play.google.com/apps/publish" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Google Play Console </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//console.firebase.google.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Firebase Console </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//console.actions.google.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Actions on Google Console </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//cast.google.com/publish" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 6)" > Cast SDK Developer Console </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//chrome.google.com/webstore/developer/dashboard" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 7)" > Chrome Web Store Dashboard </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//console.home.google.com" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 8)" > Google Home Developer Console </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-sites" aria-label="Other Google Developers websites"> <a href="https://developers.google.com/" class="devsite-footer-sites-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Developers Link"> <picture> <img class="devsite-footer-sites-logo" src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/lockup-google-for-developers.svg" loading="lazy" alt="Google Developers"> </picture> </a> <ul class="devsite-footer-sites-list"> <li class="devsite-footer-sites-item"> <a href="//developer.android.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Android Link" > Android </a> </li> <li class="devsite-footer-sites-item"> <a href="//developer.chrome.com/home" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Chrome Link" > Chrome </a> </li> <li class="devsite-footer-sites-item"> <a href="//firebase.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Firebase Link" > Firebase </a> </li> <li class="devsite-footer-sites-item"> <a href="//cloud.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Cloud Platform Link" > Google Cloud Platform </a> </li> <li class="devsite-footer-sites-item"> <a href="//ai.google.dev/" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google AI Link" > Google AI </a> </li> <li class="devsite-footer-sites-item"> <a href="/products" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer All products Link" > All products </a> </li> </ul> </nav> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="/terms/site-terms" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> <li class="devsite-footer-utility-item devsite-footer-utility-button"> <span class="devsite-footer-utility-description">Sign up for the Google for Developers newsletter</span> <a class="devsite-footer-utility-link gc-analytics-event" href="/newsletter/subscribe" data-category="Site-Wide Custom Events" data-label="Footer Subscribe link" > Subscribe </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> <devsite-concierge data-info-panel data-ai-panel data-api-explorer-panel > </devsite-concierge> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[{"dimensions": {"dimension5": "en", "dimension3": false, "dimension11": false, "dimension4": "Authorization", "dimension6": "en", "dimension1": "Signed out"}, "gaid": "UA-24532603-1", "metrics": {"ratings_count": "metric2", "ratings_value": "metric1"}, "purpose": 1}]</script> <script type="application/json" tag-management>{"at": "True", "ga4": [{"id": "G-272J68FCRF", "purpose": 1}], "ga4p": [{"id": "G-272J68FCRF", "purpose": 1}], "gtm": [], "parameters": {"internalUser": "False", "language": {"machineTranslated": "False", "requested": "en", "served": "en"}, "pageType": "article", "projectName": "Authorization", "signedIn": "False", "tenant": "developers", "recommendations": {"sourcePage": "", "sourceType": 0, "sourceRank": 0, "sourceIdenticalDescriptions": 0, "sourceTitleWords": 0, "sourceDescriptionWords": 0, "experiment": ""}, "experiment": {"ids": ""}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <script nonce="E/Z/HsJrS+8h3pqCvyf8vnwE2jY7Yv"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/js/app_loader.js', '[1,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers","https://developers-dot-devsite-v2-prod.appspot.com",null,null,["/_pwa/developers/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/developers/images/favicon-new.png","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyAP-jjEJBzmIyKR4F-3XITp8yM9T1gEEI8","AIzaSyB6xiKGDR5O3Ak2okS4rLkauxGUG7XP0hg","developers.google.com","AIzaSyAQk0fBONSGUqCNznf6Krs82Ap1-NV6J4o","AIzaSyCCxcqdrZ_7QMeLCRY20bh_SXdAYqy70KY",null,null,null,["Cloud__enable_cloud_dlp_service","Cloud__enable_free_trial_server_call","Search__enable_ai_eligibility_checks","Profiles__enable_awarding_url","Experiments__reqs_query_experiments","Search__enable_page_map","MiscFeatureFlags__enable_explain_this_code","CloudShell__cloud_code_overflow_menu","Profiles__enable_complete_playlist_endpoint","MiscFeatureFlags__enable_view_transitions","Profiles__enable_developer_profiles_callout","TpcFeatures__enable_mirror_tenant_redirects","Profiles__enable_public_developer_profiles","Concierge__enable_concierge_restricted","MiscFeatureFlags__enable_project_variables","MiscFeatureFlags__enable_variable_operator","CloudShell__cloud_shell_button","Cloud__enable_cloudx_experiment_ids","MiscFeatureFlags__developers_footer_image","MiscFeatureFlags__developers_footer_dark_image","DevPro__enable_cloud_innovators_plus","Cloud__enable_cloudx_ping","MiscFeatureFlags__emergency_css","DevPro__enable_developer_subscriptions","Profiles__enable_completecodelab_endpoint","Profiles__enable_recognition_badges","EngEduTelemetry__enable_engedu_telemetry","Search__enable_ai_search_summaries","Profiles__enable_release_notes_notifications","Significatio__enable_by_tenant","BookNav__enable_tenant_cache_key","Concierge__enable_pushui","Profiles__enable_dashboard_curated_recommendations","Cloud__enable_llm_concierge_chat","Analytics__enable_clearcut_logging","Profiles__require_profile_eligibility_for_signin","Concierge__enable_concierge","Profiles__enable_page_saving","Search__enable_ai_search_summaries_restricted","TpcFeatures__enable_required_headers","Cloud__enable_cloud_shell_fte_user_flow","Cloud__enable_cloud_shell","Search__enable_suggestions_from_borg","Cloud__enable_legacy_calculator_redirect","Cloud__enable_cloud_facet_chat","MiscFeatureFlags__enable_firebase_utm","Search__enable_dynamic_content_confidential_banner","Profiles__enable_profile_collections"],null,null,"AIzaSyBLEMok-5suZ67qRPzx0qUtbnLmyT_kCVE","https://developerscontentserving-pa.clients6.google.com","AIzaSyCM4QpTRSqP5qI4Dvjt4OAScIN8sOUlO-k","https://developerscontentsearch-pa.clients6.google.com",1,4,null,"https://developerprofiles-pa.clients6.google.com",[1,"developers","Google for Developers","developers.google.com",null,"developers-dot-devsite-v2-prod.appspot.com",null,null,[1,1,[1],null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],[1,null,null,[1,20],"/recommendations/information"],null,null,null,[1,1,1],[1,1,null,1,1]],null,[null,null,null,null,null,null,"/images/lockup-new.svg","/images/touchicon-180-new.png",null,null,null,null,1,null,null,null,null,null,null,null,null,1,null,null,null,"/images/lockup-dark-theme-new.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[6,1,14,15,20,22,23,29,32,36],null,[[null,null,null,[3,7,10,2,39,17,4,32,24,11,12,13,34,15,25],null,null,[1,[["docType","Choose a content type",[["Tutorial",null,null,null,null,null,null,null,null,"Tutorial"],["Guide",null,null,null,null,null,null,null,null,"Guide"],["Sample",null,null,null,null,null,null,null,null,"Sample"]]],["product","Choose a product",[["Android",null,null,null,null,null,null,null,null,"Android"],["ARCore",null,null,null,null,null,null,null,null,"ARCore"],["ChromeOS",null,null,null,null,null,null,null,null,"ChromeOS"],["Firebase",null,null,null,null,null,null,null,null,"Firebase"],["Flutter",null,null,null,null,null,null,null,null,"Flutter"],["Assistant",null,null,null,null,null,null,null,null,"Google Assistant"],["GoogleCloud",null,null,null,null,null,null,null,null,"Google Cloud"],["GoogleMapsPlatform",null,null,null,null,null,null,null,null,"Google Maps Platform"],["GooglePay",null,null,null,null,null,null,null,null,"Google Pay & Google Wallet"],["GooglePlay",null,null,null,null,null,null,null,null,"Google Play"],["Tensorflow",null,null,null,null,null,null,null,null,"TensorFlow"]]],["category","Choose a topic",[["AiAndMachineLearning",null,null,null,null,null,null,null,null,"AI and Machine Learning"],["Data",null,null,null,null,null,null,null,null,"Data"],["Enterprise",null,null,null,null,null,null,null,null,"Enterprise"],["Gaming",null,null,null,null,null,null,null,null,"Gaming"],["Mobile",null,null,null,null,null,null,null,null,"Mobile"],["Web",null,null,null,null,null,null,null,null,"Web"]]]]]],[1,1],null,1],[[["UA-24532603-1"],["UA-22084204-5"],null,null,["UA-24532603-5"],null,null,[["G-272J68FCRF"],null,null,[["G-272J68FCRF",2]]],[["UA-24532603-1",2]],null,[["UA-24532603-5",2]],null,1],[[13,10],[6,5],[1,1],[12,9],[11,8],[16,13],[15,12],[3,2],[5,4],[14,11],[4,3]],[[2,2],[1,1]]],null,4,null,null,null,null,null,null,null,null,null,null,null,null,null,"developers.devsite.google"],null,"pk_live_5170syrHvgGVmSx9sBrnWtA5luvk9BwnVcvIi7HizpwauFG96WedXsuXh790rtij9AmGllqPtMLfhe2RSwD6Pn38V00uBCydV4m"]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>