Tutorial: Signin
DUE Wed, 11/19, 2 pm
This tutorial may be completed individually or in teams of at most 2. You can partner differently for each tutorial.
In this tutorial, we add Google Sign-In, with biometric authentication, to Chatter.
We will build on the code base from the second tutorial, Chatter.
The course backend server mada.eecs.umich.edu is not available
for this tutorial.
Expected behavior
Posting a new chatt with image and/or video:
DISCLAIMER: the video demo shows you one aspect of the app’s behavior. It is not a substitute for the spec. If there are any discrepancies between the demo and the spec, please follow the spec. The spec is the single source of truth. If the spec is ambiguous, please consult the teaching staff for clarification.
Objectives
Learn:
- OAuth2.0 API (Google Sign-in)
- Simple persistent storage of user variables
- Biometric-guarded key-value store
- Back-end token checking
Using Google Sign-In for authentication
The goals of this tutorial are twofold: first, to introduce you to use of
OAuth 2.0 and
OpenID Connect for
authentication as implemented by
Google Sign-In,
an iOS SDK that is part of the
Google Identity Platform.
Second, to introduce you to Apple’s Keychain with biometric authentication.
Apple, Meta, X, WeChat, among others, all use OAuth 2.0. We’ve chosen Google Sign-in for illustrative purposes as it seems to be the most popular and accessible.
DISCLAIMER: this tutorial is not an exercise in designing a secure authentication protocol. It is only meant to familiarize you with some of the authentication tools available in the mobile environment. The protocol implemented here has not been vetted by a security expert.
In this tutorial, we assume that authentication is authorization. As long as you’re
authenticated, you can perform any of the app’s functions. We don’t separately check
whether you’re authorized to perform each task. We design Chatter to allow users to
view chatts without requiring authentication. We authenticate users only when they
post chatts.
Here’s the authentication flow:
-
Following common practice amongst popular sites such as stackoverflow and reddit, we’ve designed the app to require authentication only for posting
chatts, not for viewing them. However, to reduce the number of trips to the secured storage, we retrieve any previously stored authorization token (calledchatterID) at the launch of the app. It is not an error not to have a previously storedchatterID. -
When the user tries to post a
chatt, if we don’t have a validchatterID, we first obtain one. Otherwise, we post thechattas usual (as in theChattertutorial). -
We need a valid Google ID Token to obtain a
chatterID. We first check if the user is already signed in or if their ID Token is still valid and can be refreshed. Otherwise, we let the user sign in and obtain a new ID Token. -
Once the user has a valid ID Token, we contact the
chatterdback end with the ID Token and the app’s Google Client ID to obtain achatterID. -
Upon receiving a new
chatterID, we save it to the device’s secured storage. -
While the
chatterIDis valid, i.e., its lifetime hasn’t expired, we can use it to postchatts without further checking the user’s sign-in status.
Later we will add biometric check to control access to the device’s secure storage:
- to retrieve previously stored
chatterIDat launch (#1 above) - to save or update
chatterIDin secure storage (#5)
Our use of biometric check does not make the sign-in process itself any more secure.
If you don’t have chatterID stored from a previous run of the app, or if storing your
chatterID failed for whatever reasons, you can still sign in with Google and post
chatt normally. Even without a stored chatterID, as long as your previous Google
Sign-in has not expired, you can also still post chatt without being prompted to
sign in again, as per standard Google Sign-in behavior. The only purpose of the
biometric check is to control access to the stored chatterID across invocations
of the app.
Signing out is not logging out
WARNING: With Google Sign-In, signing out only signs the user out of the app,
it does not log the user out of Google on the device. Subsequently, all the user
has to do to sign back in on the app is to select their account. Google will not
challenge them for password again. Apparently, this is OAuth 2.0 standard-compliant
behavior, including, for example for X sign-in. The user is thus left vulnerable
on public computers (see github
and stackoverflow postings). Further, if
the app is killed or force closed from outside the app, the user will not be
signed out. The only way to sign a user out from the device is through the user’s
Manage your Google Account button on a browser. Navigate to Security > Your devices.
Click on the three vertical dots on the upper right of your device’s card on
the web page and choose Sign out.
Modified Chatter API
To retrieve chatts, we use the same getchatts API endpoint from the chatter
tutorial, unmodified.
To post a chatt, users are now required to first be authenticated. We add two APIs
to Chatter:
adduser: uses HTTP POST to add an authenticated user andpostauth: uses HTTP POST to post achattas authenticated user.
Using this syntax:
url-endpoint
-> request: data sent to Server
<- response: data sent to Client
The additional protocol handshakes consist of:
/adduser
-> HTTP POST { clientID, idToken }
<- { chatterID, lifetime } 200 OK
If the idToken fails authentication, in this tutorial Google’s, adduser
returns HTTP status code 511, “Network Authentication Required”.
/postauth
-> HTTP POST { chatterID, message }
<- {} 200 OK
If the lifetime of chatterID has expired, postauth
returns HTTP status code 401, “Unauthorized”.
New Chatter API data formats
The data format adduser expects is, assuming use of Google Signin for authentication:
{
"clientID": "YOUR_APP'S_OAUTH2.0_CLIENT_ID",
"idToken": "YOUR_GOOGLE_ID_TOKEN"
}
where YOUR_APP'S_OAUTH2.0_CLIENT_ID is issued by Google Signin when you create an
OAuth 2.0 Client ID with Google Sign-In and the YOUR_GOOGLE_ID_TOKEN is issued to
the user when they sign in.
The data format postauth expects is:
{
"chatterID": "YOUR_CHATTER_ID",
"message": "Chitt chatts"
}
where YOUR_CHATTER_ID is the chatterID returned by the adduser API above.
Assignment specs
The suggested work flow is to work on the front end until you can obtain the ID Token issued by Google Sign-in, then switch to work on the back end, and then return to finish up the front end:
Upgrade one of the alternative back-end servers: unlike the other tutorials, the back end of this one is rather more substantive:
If you choose to work on the back end first, be prepared that you won’t be able to test it until you’re part way through your front end.
| Prepared by Sugih Jamin | Last updated: August 29th, 2025 |