5

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.

Jayson
  • 1,689
  • 14
  • 26
  • Any updates? We're against the same issue here using a WKWebView -- pressing the "Sign in With Google" has no effect. This is in SoundCloud's court it would seem. Can you add `soundcloud` as a tag? – Drew O'Meara Feb 07 '17 at 00:04
  • @DrewO'Meara no solutions as of yet. I've just been telling users about the Safari workaround on a case by case basis – Jayson Feb 07 '17 at 00:07
  • Squeak squeak http://stackoverflow.com/questions/42079684/soundcloud-oauth-flow-on-ios-broken-for-google – Drew O'Meara Feb 07 '17 at 00:26
  • any thoughts below on my progress below about finishing oauth with SC with the google token in hand? – Drew O'Meara Feb 08 '17 at 18:19
  • @DrewO'Meara see my comment below – Jayson Feb 08 '17 at 18:59

1 Answers1

0

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
Drew O'Meara
  • 401
  • 2
  • 14
  • Apple recommends to use `WKWebView` instead of `UIWebView` if you are on `iOS8` and higher; will this approach still work? – koen Feb 08 '17 at 18:21
  • Great question @Koen -- we had been using `WKWebView` and was reproducing identical results, with the exception that I didn't find the point to insert the `getElementById('response-form-encoded')` before I found it with `UIWebView`. The difference I observed was that `WKWebView` just appeared to sit there after google authentication while `UIWebView` went to a blank pane (which was the tipoff to check what response data was also there). – Drew O'Meara Feb 08 '17 at 18:28
  • It should, I'm changing our code back to `WKWebView` and expect to find the place to put it. The question is how to finish SC auth with the google token! – Drew O'Meara Feb 08 '17 at 18:39
  • 1
    Try passing the returned values to `https://soundcloud.com/connect/via/google_plus/returning?code=&state=`. I pulled this from `googlePlusSigninCallback` in `https://a1.sndcdn.com/javascripts/base_mobile.js`. – Jayson Feb 08 '17 at 18:46
  • First I get that `client_id` is missing error, and after adding that plus `client_secret` I get `Request failed: method not allowed (405)`. See my above edits to my post to see the URI SC is telling Google to go to. We should be able to figure this out. – Drew O'Meara Feb 08 '17 at 20:18
  • Been working so hard on this -- I wish a SC dev would help – Drew O'Meara Feb 09 '17 at 22:01