5

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
  • This is a good question, i'm gonna link a new lib take a look => Commented Dec 23, 2020 at 19:38
  • Try this from this good tutorial! Commented Jan 6, 2021 at 17:04

2 Answers 2

3

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"])
Sign up to request clarification or add additional context in comments.

9 Comments

This is super interesting, I'm trying this. I'm trying to implement OAuth with StackExchange, but I really cant figure out how to do it. I'm adding all the info required but once the "Authorize" page prompr and I click it, i'm redirected to a new page and I'm not able to close the "authentication sheet" in order to get the token. Have you tried with StackExchange? I would really appreciate any kind of help
I tried GitLab only, will try StackExchange and get back to you 👍🏻
It's working now, you can use the 1.0.4 version of the package, I change the OAuth2Credentials struct to the one defined in RFC 6749 OAuth 2.0 tools.ietf.org/html/rfc6749#section-5.1. StackExchange is returning "expires" but the recommended one is "expires_in", so I handle this in the new version. PS: For redirecting you need to register your scheme in target>info>URL Types. Something like "redirect-uri://<<your domain on stackApps>>" will works. Tell me if it's working for you now and if I need to edit the library, I am always opened for modification since I am using it in my apps
Also don't forget to use the JSON format of the access token response "stackoverflow.com/oauth/access_token/json"
you are so kind. I really appreciate your help and ill share your library. But i'm still facing the issue, I updated my answer with all the details. You tried the StackExchange Oauth right? And i'ts working? Is there anything different between my update and your code?
|
1

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(...)
}

2 Comments

This is a good point, i didnt noticed that. But this is what happend => I tap my button => redirect to Safari => I log in and im readirected to a page with the access code in hash. But nothing happend in my code, safari is not dismissed, the UX is not good and I dont have token. In "withCallBackURL i'm adding my bundleIdentifier + :/oauth2Callback
I have my redirect uri inside authorizeUrl and when I'm redirected I have accessToken in this url

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.