Download - Google+ for Mobile Apps on iOS and Android
Google+ for Mobile Apps on iOS & Android
Peter Friese Developer Advocate, Google
google.com/+PeterFriese @peterfriese
http://peterfriese.de
What is Google+ ?
Google+ is…!a social network
Image credit: https://www.flickr.com/photos/dainbinder/10538549606/
An identity provider
Image credit: http://www.wlmht.nhs.uk/wp-content/uploads/2012/09/passport-photos.jpg
Sign-in with Google
αὐθεντικός (greek):!!• “that comes from the author”!• authentic!• original!• genuine
Ownership Knowledge Inherence
Authentication - How hard can it be?
Image credit: https://www.flickr.com/photos/92269745@N00/3801617675
Quite hard, actually…
Hard for developers…!... Implementation!... Infrastructure!... Security!... Multiple platforms
Hard for your users…
... more passwords
... more devices
... more trustImage credit: https://flic.kr/p/frJ48
You might even be in the news!
… but not in a good way…
Image credit: https://kezialubanszky.files.wordpress.com/2013/03/don-t-panic-2568311.jpg
Image credit: https://kezialubanszky.files.wordpress.com/2013/03/don-t-panic-2568311.jpg
±KEEP CALM
ANDSIGN INWITH
GOOGLE+
Easier for youEasier for the user
Established, trusted brandFocus on your business
model
Over-the-Air Installs
Over-the-Air Installs
Over-the-Air Installs
Over-the-Air Installs
Over-the-Air Installs
Over-the-Air Installs
Over-the-Air Installs
Cross-Device Single Sign-on
No tap required, log-in will happen automatically!
Cross-Device Single Sign-on
Cross-Device Single Sign-on
Implementing Google+ Sign-in
How does Google+ Sign-in work?Based on OAuth 2.0
AppUser
Consent Permission
No password sharing
Scoped access
Revocable
Setting up
Developer Console Project
https://developers.google.com/console
APIs
CredentialsiOS Client ID
Android Client ID
Web Client ID
Branding
Permissions
Management
The Auth Triangle
You Google
Connecting lines need authentication
Client
Server
Google APIs
Client Authentication
You Google
Client
Server
Google APIs
Client Authentication
Client Authentication: AndroidOverview
Create OAuth 2.0 client ID
Link with Google Play Services API
Setup Sign-In
Client Authentication: AndroidSDK Architecture
Android
Your App
Google APIs
Google Play Client Library
Google Play Services APK
Authorize using existing accounts on Android device
Client Authentication: AndroidGoogleApiClient Lifecycle
mApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(Plus.API, null) .addScope(Plus.SCOPE_PLUS_LOGIN) .build();
Java
onCreate()
onStart() mApiClient.connect(); Java
onStop()if (mApiClient.isConnected()) { mApiClient.disconnect();}
Java
<com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
XML
running
Client Authentication: AndroidHandling Connection Failure
public void onConnectionFailed(ConnectionResult result) { if (!mIntentInProgress && result.hasResolution()) { try { mIntentInProgress = true; startIntentSenderForResult(result.getResolution().getIntentSender(), RC_SIGN_IN, null, 0, 0, 0); } catch (SendIntentException e) { // The intent was canceled before it was sent. Return to the default // state and attempt to connect to get an updated ConnectionResult. mIntentInProgress = false; mApiClient.connect(); } }}
Java
Client Authentication: AndroidHandle connection failure
public void onConnectionFailed(ConnectionResult result) { if (!mIntentInProgress && result.hasResolution()) { try { mIntentInProgress = true; startIntentSenderForResult(result.getResolution().getIntentSender(), RC_SIGN_IN, null, 0, 0, 0); } catch (SendIntentException e) { // The intent was canceled before it was sent. Return to the default // state and attempt to connect to get an updated ConnectionResult. mIntentInProgress = false; mApiClient.connect(); } }}
Java
User needs to select account, consent to permissions, ensure network connectivity, etc. to connect
Client Authentication: AndroidConnection successful
public void onConnected(Bundle connectionHint) { // Retrieve some profile information to personalize our app for the user. Person currentUser = Plus.PeopleApi.getCurrentPerson(mApiClient); // Indicate that the sign in process is complete. mSignInProgress = STATE_DEFAULT;}
Java
Client Authentication: AndroidConnection successful
public void onConnected(Bundle connectionHint) { // Retrieve some profile information to personalize our app for the user. Person currentUser = Plus.PeopleApi.getCurrentPerson(mApiClient); // Indicate that the sign in process is complete. mSignInProgress = STATE_DEFAULT;}
Java
Client Authentication: iOSOverview
Create OAuth 2.0 client ID
Integrate SDK
Setup Sign-In
Client Authentication: iOSSDK Architecture
iOS
Your App
Google APIsGoogle+ iOS SDK
Statically linked library
Client Authentication: iOSConfigure Sign-In
#import <GooglePlus/GooglePlus.h> #import <GoogleOpenSource/GoogleOpenSource.h> !... !!GPPSignIn *signIn = [GPPSignIn sharedInstance]; signIn.shouldFetchGoogleUserEmail = YES; !signIn.clientID = @“YOUR_CLIENT_ID”; signIn.scopes = @[@"profile"]; signIn.delegate = self;
Objective-C
Client Authentication: iOSPerform Sign-In, Option 1 (use our button)
Client Authentication: iOSPerform Sign-In, Option 2 (create your own button)
Create own button / use action sheet / …
// trigger sign-in [[GPPSignIn sharedInstance] authenticate];
Objective-C
Silent sign-in if user has signed in before
// silently sign in [[GPPSignIn sharedInstance] trySilentAuthentication];
Objective-C
Client Authentication: iOSReceiving the authorisation
// In ApplicationDelegate - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation]; } !!// GPPSignInDelegate - (void)finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error { if (!error) { NSString *gplusId = [GPPSignIn sharedInstance].userID; } }
Objective-C
Client Authentication: WebOverview
Create OAuth 2.0 client ID
Include JavaScript client on your web page
Add Google+ Sign-in button
Handle callback
Client Authentication: WebArchitecture
Browser
Your site
Google APIsplusone.js
Client Authentication: WebIntegrate sign-in button
<div id="gConnect"> <button class="g-signin" data-scope="https://www.googleapis.com/auth/plus.login" data-requestvisibleactions="http://schemas.google.com/AddActivity" data-clientId="YOUR_CLIENT_ID" data-callback="onSignInCallback" data-cookiepolicy="single_host_origin"> </button> </div> !<!-- Place plusone.js asynchronous JavaScript just before your </body> tag —>
HTML
Client Authentication: WebHandle authorization callback
function onSignInCallback(authResult) { if (authResult['access_token']) { // Successfully authorized } else if (authResult['error']) { // User is not signed in. } }
JavaScript
Server Authentication
You Google
Client
Server
Google APIs
One-Time-Code Flow
Client
Server
Google APIs
1: Client-side auth request
2: OAuth dialog
triggeredOAuth
2.0 Dialog
3: access_token, one-time code, id_token
4: one-time code 5: exchange one-time code for access_token and refresh_token
6: access_token,
refresh_token
7: “fully logged in”
Server Auth: One-Time CodeIntegrate sign-in button
<div id="gConnect"> <button class="g-signin" data-scope="https://www.googleapis.com/auth/plus.login" data-requestvisibleactions="http://schemas.google.com/AddActivity" data-clientId="YOUR_CLIENT_ID" data-callback="onSignInCallback" data-cookiepolicy=“single_host_origin"> data-callback="signInCallback"> </button> </div> !<!-- Place plusone.js asynchronous JavaScript just before your </body> tag —>
HTML
Server Auth: One-Time CodeHandle authorization callback
function signInCallback(authResult) { if (authResult['code']) { // Send the code to the server $.ajax({ type: 'POST', url: 'plus.php?storeToken', contentType: 'application/octet-stream; charset=utf-8', success: function(result) { // Handle or verify the server response if necessary. console.log(result); } else { $('#results').html('Failed to make a server-side call.'); } }, processData: false, data: authResult['code'] }); } else if (authResult['error']) { console.log('There was an error: ' + authResult['error']); } }
JavaScript
Server Auth: One-Time CodeExchange one-time code
$code = $request->getContent(); !// Exchange the OAuth 2.0 authorization code for user credentials. $client->authenticate($code); !$token = json_decode($client->getAccessToken()); !// Verify the token ... !// Store the token in the session for later use. $app['session']->set('token', $client->getAccessToken()); $response = 'Successfully connected with token: ' . print_r($token, true);
PHP
Sharing with Google+
Use interactive posts to engage your users
Use interactive posts to engage your users
Use interactive posts to engage your users
Sharing: iOSInteractive Posts
#import <GooglePlus/GooglePlus.h> #import <GoogleOpenSource/GoogleOpenSource.h> ... id <GPPNativeShareBuilder> shareBuilder = [[GPPShare sharedInstance] nativeShareDialog]; [shareBuilder setURLToShare:[NSURL URLWithString:@“...”]]; ![shareBuilder setPrefillText:@"Do you want to learn more ...”]; [shareBuilder setContentDeepLinkID:@"talk/googleplusdwx2014"]; [shareBuilder setCallToActionButtonWithLabel: @"LEARN_MORE" URL:[NSURL URLWithString:@“...”] deepLinkID:@“talk/googleplusdwx2014"]; ![shareBuilder open];
Objective-C
Sharing: iOSInteractive Posts
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GPPDeepLink setDelegate:self]; [GPPDeepLink readDeepLinkAfterInstall]; ! return YES; }
Objective-C
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [GPPURLHandler handleURL:url sourceApplication:sourceApplication annotation:annotation]; }
Objective-C
Sharing: iOSInteractive Posts
Sharing: AndroidInteractive Posts
PlusShare.Builder builder = new PlusShare.Builder(this); !builder.addCallToAction( "CREATE_ITEM", Uri.parse(“http://...”), “/deep/linkid"); !builder.setContentUrl(Uri.parse(“https://...”)); !builder.setContentDeepLinkId(“/deep/linkid", null, null, null); !builder.setText("Do you want to learn more ..."); !startActivityForResult(builder.getIntent(), 0);
Java
Summary
Summary
Do not build your own authentication system
Google+ makes authentication easy
Use interactive posts to engage your users
More info at http://developers.google.com/+
Peter Friese Developer Advocate, Google
google.com/+PeterFriese @peterfriese
http://peterfriese.de