I'm implementing a SoundCloud login flow in my app. The app opens https://soundcloud.com/connect
in an SFSafariViewController
with a redirect_uri
that uses my app's custom URL scheme to receive the response. It works fine for direct SoundCloud logins, but fails when trying to use their "Sign in with Google" button.
In Safari, that button opens a new tab (popup on desktop) with a Google sign-in page, which then communicates back to the SoundCloud tab via postMessage
. This login flow works fine if you use the iOS Safari app, but fails in an SFSafariViewController
(clicking the button goes to a white page with a Google url: https://accounts.google.com/o/oauth2/auth?...
).
Right now my workaround is to advise users using Google to tap the Safari icon on the SFSafariViewController
to complete the login flow in the Safari app, but I'm wondering if there's a way to handle this without leaving my app.
Well, if I use a UIWebView
, you can grab the final oauth response from google after the user authenticates with Google. However, how do we turn that back around to SoundCloud (e.g. soundcloud.com/connect/via/google_plus/returning
)
- (void) webViewDidFinishLoad:(UIWebView*)inWebView {
NSString* str = [inWebView stringByEvaluatingJavaScriptFromString:@"document.getElementById('response-form-encoded').value"];
if ( str.length > 0 ) {
NSDictionary* params = parseURLParams( str );
NSLog( @"%@", params );
}
}
Output:
{
"access_token" = "ya2...<removed>...4g";
authuser = 0;
code = "4/sU_g7....<removed>...fnRELA";
"expires_in" = 3600;
"id_token" = "eyJhb...<removed>...DA";
prompt = none;
scope = "https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/plus.login+https://www.googleapis.com/auth/userinfo.profile+https://www.googleapis.com/auth/plus.moments.write+https://www.googleapis.com/auth/plus.me+https://www.googleapis.com/auth/plus.profile.agerange.read+https://www.googleapis.com/auth/plus.profile.language.read+https://www.googleapis.com/auth/plus.circles.members.read";
"session_state" = "c8703a085b885bbe8c8d0e29277b0c2fdf9c6c87..65aa";
state = "392921654%7C0.288515904";
"token_type" = Bearer;
}
The URL that initiates the google login step is below -- I've decoded the URL escape encoding below for convenience:
https://accounts.google.com/o/oauth2/auth?client_id=984739005367.apps.googleusercontent.com&response_type=code token id_token gsession&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.profile&state=425511939|0.2912748339&access_type=offline&request_visible_actions=http://schemas.google.com/AddActivity http://schemas.google.com/ListenActivity http://schemas.google.com/CreateActivity&after_redirect=keep_open&cookie_policy=single_host_origin&prompt=none&include_granted_scopes=true&proxy=oauth2relay751149297&redirect_uri=postmessage&origin=https://soundcloud.com&gsiwebsdk=1&authuser=0&jsh=m;/_/scs/apps-static/_/js/k=oz.gapi.en.TA32fes-0yU.O/m=__features__/am=AQ/rt=j/d=1/rs=AGLTcCOuWXPCbMjoOmrZx_gBsAG8J20NLA