Overview
On February 16 2022, we
announced
plans to make Google OAuth interactions safer by using more secure OAuth
flows. This guide helps you to understand the necessary changes and steps to
successfully migrate from the loopback IP address flow to supported alternatives.
This effort is a protective measure against phishing and app impersonation
attacks during interactions with Google's OAuth 2.0 authorization endpoints.
What is the Loopback IP Address flow?
The
loopback IP address flow
supports the use of a loopback IP address or
localhost
as the host component of the redirect URI where
credentials are sent to after a user approves an OAuth consent request. This flow is
vulnerable to
man in the middle
attacks where a nefarious app, accessing the same loopback interface on some
operating systems, may intercept the response from the authorization server to the given
redirect URI and gain access to the authorization code.
The loopback IP address flow is being deprecated for the native iOS, Android,
and Chrome OAuth client types but will continue to be supported on desktop
apps.
Key compliance dates
-
March 14, 2022
- new OAuth clients blocked from using the Loopback
IP address flow
-
August 1, 2022
- a user-facing warning message may be
displayed to non-compliant OAuth requests
-
August 31, 2022
- the Loopback IP address flow is blocked
for native Android, Chrome app, and iOS OAuth clients created before March 14, 2022
-
October 21, 2022
- all existing clients are blocked
(including exempted clients)
A user-facing error message will be displayed for non-compliant requests.
The message will convey to users that the app is blocked while
displaying the support email that you have registered in the
OAuth consent screen in Google API Console
.
There are two main steps to complete to get through the migration process:
- Determine if you are affected.
- Migrate to a supported alternative if you are affected.
Determine if you are affected
Review your OAuth client ID type
Navigate to the
Credentials page
of the
Google API Console and view your OAuth client ID type under the
OAuth 2.0 Client IDs
section. It will be any one of the
following:
Web application
,
Android
,
iOS
,
Universal Windows Platform (UWP)
,
Chrome app
,
TVs & Limited Input devices
,
Desktop app
.
Proceed to the next step if your client type is Android, Chrome app, or iOS and you are using
the loopback IP address flow.
You do not need to do anything related to this deprecation if you are using
the loopback IP address flow on a Desktop app OAuth client as usage with that OAuth client type
will continue to be supported.
How to determine if your app is using the loopback IP address flow
Inspect your app code
or the
outgoing network call
(in case
your app is using an OAuth library) to determine if the Google OAuth
authorization request
your app is making is using loopback redirect URI values.
Inspect your application code
Review the section of your application code where you are making calls to
the Google OAuth
authorization endpoints
and determine if the
redirect_uri
parameter has any of the
following values:
-
redirect_uri=http://127.0.0.1:
<port>
e.g.
redirect_uri=http://127.0.0.1:
3000
-
redirect_uri=http://[::1]:
<port>
e.g.
redirect_uri=http://[::1]:
3000
-
redirect_uri=http://localhost:
<port>
e.g.
redirect_uri=http://localhost:
3000
A sample loopback IP address redirect flow request will look like the one
below:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:
3000
&
response_type=code&
scope=
<SCOPES>
&
state=
<STATE>
&
client_id=
<CLIENT_ID>
Inspect outgoing network call
The method for inspecting network calls will vary depending on your
application client type.
While inspecting network calls, look for requests sent to the Google OAuth
authorization endpoints
and determine if the
redirect_uri
parameter has any of the
following values:
-
redirect_uri=http://127.0.0.1:
<port>
e.g.
redirect_uri=http://127.0.0.1:
3000
-
redirect_uri=http://[::1]:
<port>
e.g.
redirect_uri=http://[::1]:
3000
-
redirect_uri=http://localhost:
<port>
e.g.
redirect_uri=http://localhost:
3000
A sample loopback IP address redirect flow request will look like the one below:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:
3000
&
response_type=code&
scope=
<SCOPES>
&
state=
<STATE>
&
client_id=
<CLIENT_ID>
Migrate to a supported alternative
Mobile Clients (Android / iOS)
If you determine that your app is using the loopback IP address flow with an Android or iOS
OAuth client type, you should migrate to using our Google Sign-In mobile SDKs
(
Android
,
iOS
).
The SDK makes it easy to access Google APIs and handles all the calls to
Google's OAuth 2.0 authorization endpoints.
The documentation links below provides information on how to use the Google
Sign-In SDKs to access Google APIs without using a loopback IP address redirect URI.
Access Google APIs on Android
Server-Side (offline) access
The example below shows how to
access Google APIs on the server side on Android
.
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
GoogleSignInAccount account = task.getResult(ApiException.class);
// request a one-time authorization code that your server exchanges for an
// access token and sometimes refresh token
String authCode = account.getServerAuthCode();
// Show signed-in UI
updateUI(account);
// TODO(developer): send code to server and exchange for access/refresh/ID tokens
} catch (ApiException e) {
Log.w(TAG, "Sign-in failed", e);
updateUI(null);
}
Review the
server-side access guide
on how to access Google APIs from the server side.
Access Google APIs in an iOS App
Client-side access
The example below shows how to
access Google APIs on the client side on iOS
.
user.authentication.do { authentication, error in
guard error == nil else { return }
guard let authentication = authentication else { return }
// Get the access token to attach it to a REST or gRPC request.
let accessToken = authentication.accessToken
// Or, get an object that conforms to GTMFetcherAuthorizationProtocol for
// use with GTMAppAuth and the Google APIs client library.
let authorizer = authentication.fetcherAuthorizer()
}
Use the access token to call the API, by either including the access token in
the header of a REST or gRPC request (
Authorization: Bearer
ACCESS_TOKEN
),
or by using the fetcher authorizer (
GTMFetcherAuthorizationProtocol
) with the
Google APIs client library for Objective-C for REST
.
Review the
client-side access
guide
on how to access Google APIs on the client side.
on how to access Google APIs on the client side.
Server-side (offline) access
The example below shows how to access Google APIs on the server side to support an iOS client.
GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
guard error == nil else { return }
guard let user = user else { return }
// request a one-time authorization code that your server exchanges for
// an access token and refresh token
let authCode = user.serverAuthCode
}
Review the
server-side access
guide
on how to access Google APIs from the server side.
Chrome App Client
If you determine that your app is using the loopback IP address flow on the Chrome
app client, you should migrate to using the
Chrome Identity API
.
The example below shows how to get all user contacts without the use of a loopback IP address redirect URI.
window.onload = function() {
document.querySelector('button').addEventListener('click', function() {
// retrieve access token
chrome.identity.getAuthToken({interactive: true}, function(token) {
// ..........
// the example below shows how to use a retrieved access token with an appropriate scope
// to call the Google People API contactGroups.get endpoint
fetch(
'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=
API_KEY
',
init)
.then((response) => response.json())
.then(function(data) {
console.log(data)
});
});
});
};
Review the
Chrome Identity API guide
for more information on how to access authenticate users and call Google
endpoints with the Chrome Identity API.