Swift OAuth2.0 with redirectURI

Viewed 2381

I'm using a service that provides an OAuth2.0 authentication. This are the steps i need:

  • Open a URL with user Id as params
  • User approves my app (which is correctyle registered).
  • The user is redirected to a RedirectUri, with access token in the hash.

The third point is my main problem.

I've implemented the OAuth with microsoft libraries and everything works fine. But I cant use them here so I'm trying https://github.com/OAuthSwift/OAuthSwift this one.

This is my code:

private func authenticationService() {
    // create an instance and retain it
    let oauthswift = OAuth2Swift(
        consumerKey:    "xx",
        consumerSecret: "xxx",
        authorizeUrl:   "//myurl + userId",
        responseType:   "token"
    )

    oauthswift.authorizeURLHandler = OAuthSwiftOpenURLExternally.sharedInstance

    let handle = oauthswift.authorize(
        withCallbackURL: "???",
        scope: "", state:"") { result in
        switch result {
        case .success(let (credential, response, parameters)):
          print(credential.oauthToken)
          // Do your request
        case .failure(let error):
          print(error.localizedDescription)
        }
    }
}

This open correctly my Safari but then I'm redirected to the URI with access token in the hash and nothing happened.

The main problem here is that I've a redirect uri so I guess the callback URL is not called? And this is not opening a sheet but it is redirecting to Safari. And I dont like this approach.

How can I perform OAuth2.0 in swift with the steps above? How can I get the access token from an url? What is the best library and how can I get the most of it?


Update:

This is my code for stackExchange:

    let request: OAuth2Request = .init(authUrl: "https://stackexchange.com/oauth/dialog?client_id=<MYCLIENTID>&scope=private_info&redirect_uri=https://stackexchange.com/oauth/login_success",
                                   tokenUrl: "https://stackoverflow.com/oauth/access_token/json",
                                   clientId: "<MYCLIENTID>",
                                   redirectUri: "https://stackexchange.com/oauth/login_success",
                                   clientSecret: "",
                                   scopes: [])

The OAuth domain in stack apps is => stackexchange.com So i've added in my URL Types the following: redirect-uri://<stackexchange.com> (even without <>)

But everytimes I approve my app i'm stacked in the "Authorizing application" which contains my token and i'm not redirected.

2 Answers

If you are targeting iOS 13 you can use the new AuthenticationServices library provided by Apple.

It will work on both macOS and iOS.

Maybe this would help other developers, I create a simple and small swift package to handle OAuth2 in Swift, you can check the demo project it works very well

https://github.com/hadiidbouk/SimpleOAuth2

Edit:

You are passing the wrong URLs, they should be like this

let request: OAuth2Request = .init(authUrl: "https://stackoverflow.com/oauth",
                                       tokenUrl: "https://stackoverflow.com/oauth/access_token/json",
                                       clientId: "<<your client id>>",
                                       redirectUri: "redirect-uri://stackexchange.com",
                                       clientSecret: "<<your client secret>>",
                                       scopes: ["private_info"])

In the below code:

private func authenticationService() {
    // create an instance and retain it
    let oauthswift = OAuth2Swift(...)

you don't retain oauthswift (nor handle). They will be deallocated as soon as you finish executing the authenticationService function.

You need to store references to oauthswift and handle outside the function (at the class level).

let oauthswift: OAuth2Swift
let handle: ...

init() {
    oauthswift = OAuth2Swift(
        consumerKey:    "xx",
        consumerSecret: "xxx",
        authorizeUrl:   "//myurl + userId",
        responseType:   "token"
    )
    ...
}

private func authenticationService() {
    handle = oauthswift.authorize(...)
}
Related