Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handleAuthorizationResult, response is 'nil' on iOS #103

Closed
yassinejebli opened this issue Jun 12, 2020 · 6 comments · Fixed by #161
Closed

handleAuthorizationResult, response is 'nil' on iOS #103

yassinejebli opened this issue Jun 12, 2020 · 6 comments · Fixed by #161
Labels
bug Something isn't working ios
Milestone

Comments

@yassinejebli
Copy link

Capacitor version:

💊   Capacitor Doctor  💊 

Latest Dependencies:

  @capacitor/cli: 2.2.0

  @capacitor/core: 2.2.0

  @capacitor/android: 2.2.0

  @capacitor/electron: 2.2.0

  @capacitor/ios: 2.2.0

Installed Dependencies:

  @capacitor/electron not installed


  @capacitor/cli 2.2.0

  @capacitor/core 2.2.0

  @capacitor/ios 2.2.0

  @capacitor/android 2.2.0

[success] Android looking great! 👌
  Found 4 Capacitor plugins for ios:
    @byteowls/capacitor-oauth2 (2.0.0)
    cordova-plugin-buildinfo (4.0.0)
    cordova-plugin-file (6.0.2)
    cordova-plugin-advanced-http (2.4.1)
[success] iOS looking great! 👌

Library version:

  • 2.0.0

OAuth Provider:

(function() {
        const url = new URL(window.location.href);
        const state = url.searchParams.get("state");
        const redirectUri = url.searchParams.get("redirect_uri");

        window.location.href = redirectUri+"#access_token=123&state="+state+"&userId=123&firstName=Yassine"
      })()

Normally there should be a webview in the backend side that will redirect the mobile user to an auth provider which can be accessible only by that backend (whitelisted backend IP) then after successful login backend should send back the received data from that Auth provider.

Your Plugin Configuration

const redirectUrlMobile = window.BuildInfo?.packageName+":/"
    OAuth2Client.authenticate(
      {
        appId: window.BuildInfo?.packageName||"xx.xxx.xxxx",
        state: makeId(20),
        authorizationBaseUrl: "https://stoic-leavitt-eb1e9f.netlify.app",
        responseType: "token",
        web:{
          redirectUrl: "http://localhost:8080", // for dev
          windowOptions: "width=500,height=600,left=0,top=0",
        },
        android: {
          redirectUrl: redirectUrlMobile,
        },
        ios:{
          redirectUrl: redirectUrlMobile,
        },
      }
    ).then(response => {
      console.log({response})
    }).catch(error => {
      console.error("OAuth rejected", error);
    });

Screenshot 2020-06-12 at 14 12 35

@moberwasserlechner
Copy link
Collaborator

Hi @yassinejebli,

the plugin needs a oauth2 server that follow the specs. The plugin is very generic and tries to support as much providers as possible but it needs a well implemented oauth2 server.

I clicked on the link provided and it might be a good idea to have a look at the /null? part and discover why this is null. Moreover you set a state but do not return it.

https://stoic-leavitt-eb1e9f.netlify.app/null?access_token=123&state=null&userId=1234&firstName=Yassine&lastName=Jebli&code=1

I am certain that you understand that it is out of scope to debug your server side.

@moberwasserlechner moberwasserlechner added invalid This doesn't seem right and removed invalid This doesn't seem right labels Jun 15, 2020
@yassinejebli
Copy link
Author

yassinejebli commented Jun 15, 2020

@moberwasserlechner thanks for responding.

I think you should add in the url redirect_uri param as well as state.

something like
https://stoic-leavitt-eb1e9f.netlify.app/?redirect_uri=<auth_provider_uri>&state=<generated_state_in_frontend>&<...other params generated by capacitor-oauth2 plugin from configs (response type...)>

I think you got that link because you tested it out of context (directly on browser), to reproduce the issue it should be tested with in the plugin, redirection works fine on Android & on browser for me.

Alternative solution could be using Plugins.App.addListener('appUrlOpen', callback), but as I'm willing in the future to use your plugin for Google & FB auth it would be great if it's possible to use it with whatever auth provider.

That page I hosted on netlify is just an HTML file which mocks the behaviour of an auth provider, code below

<html>
<head>
    <title>Test Auth</title>
</head>
<body>
    <script>
      (function() {
        const url = new URL(window.location.href);
        const state = url.searchParams.get("state");
        const redirectUri = url.searchParams.get("redirect_uri");

        window.location.replace(redirectUri+"?access_token=123&state="+state+"&userId=1234&firstName=Yassine&lastName=Jebli")
      })()
    </script>
</body>
</html>

@moberwasserlechner
Copy link
Collaborator

moberwasserlechner commented Jun 15, 2020

I think you got that link because you tested it out of context (directly on browser), to reproduce the issue it should be tested with in the plugin, redirection works fine on Android & on browser for me.

You're right of course.

@moberwasserlechner
Copy link
Collaborator

I mark this as a bug for now, because it works on web and Android. Although I'm unsure because you mock the backend.

@moberwasserlechner moberwasserlechner added the bug Something isn't working label Jun 15, 2020
@moberwasserlechner moberwasserlechner added this to the 2.1.0 milestone Jun 15, 2020
@moberwasserlechner moberwasserlechner removed this from the 2.1.0 milestone Aug 27, 2020
@vmdominguez-usaa
Copy link

vmdominguez-usaa commented Nov 17, 2020

I saw this same behavior when trying to authorize using the implicit flow. I tweaked part of the handleAuthorizationResult function locally to get it working:

} else if let responseData = response?.data {
  do {
    let jsonObj = try JSONSerialization.jsonObject(with: responseData, options: []) as! JSObject
    call.resolve(jsonObj)
  } catch {
    self.log("Invalid json in response \(error.localizedDescription)")
    call.reject(self.ERR_GENERAL)
  }
} else {
  call.resolve(parameters) // not sure if parameters is what should be passed, but it contains the access_token
}

@korywkoch
Copy link

I saw this same behavior when trying to authorize using the implicit flow. I tweaked part of the handleAuthorizationResult function locally to get it working:

} else if let responseData = response?.data {
  do {
    let jsonObj = try JSONSerialization.jsonObject(with: responseData, options: []) as! JSObject
    call.resolve(jsonObj)
  } catch {
    self.log("Invalid json in response \(error.localizedDescription)")
    call.reject(self.ERR_GENERAL)
  }
} else {
  call.resolve(parameters) // not sure if parameters is what should be passed, but it contains the access_token
}

I implemented a similar workaround locally as well. You should create a PR vmdominguez-usaa and bask in open source accolades!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working ios
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants