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

Would this library work for a rest endpoint? #5

Closed
jlubeck opened this issue Oct 17, 2019 · 7 comments
Closed

Would this library work for a rest endpoint? #5

jlubeck opened this issue Oct 17, 2019 · 7 comments

Comments

@jlubeck
Copy link

jlubeck commented Oct 17, 2019

Forgive me if this is not acceptable. I don't have much experience with Laravel so this might be a dumb question.

I'm making the backend/services of my iOS app in Laravel, so I'm not using it as a website, and I was looking to implement the auth flow on the server and found your package. But on the Readme I only see how to use it with the SIWA button on the website.

Would this work without a website and only through a REST api?

Thank you!

@mikebronner
Copy link
Owner

Hi @jlubeck, you would have to use iOS integration methods for the SIWA button, instead of web integration, then send the respective data points to your sign-in endpoint on your Laravel server, and store them. My package is only geared toward usage on the web.

Alternatively, you could use this package in a WebView in your iOS app and handle the login that way, but I wouldn't recommend it. (Straightforward iOS SIWA integration using Xcode would be better.)

I hope I was able to answer your question. Let me know if you have any further questions. :) Best of luck on your project!

@jlubeck
Copy link
Author

jlubeck commented Oct 17, 2019

Yes, I'm aware that I would need to implement the SIWA button natively. I actually have that already. But I'm stuck at what do I do with the data now in order to tie that info to a user on my db and save the session on the server so that I can keep calling the other authorized endpoints...

With regular user and password I would just save them on they keychain and re-login after the session was expired, but I can't seem to do that since the token that apple returns only lasts 15 minutes...

So I was maybe hoping that this library would have that solved somehow hehe

Looks like I need to keep looking
Thanks for the prompt reply!

@mikebronner
Copy link
Owner

Hmm, the token that apple returns should last as long as you need it to, as there is no need to fetch any information from Apple in the future. As far as I understand it, the token lifetime is arbitrarily set on Apples end, because they don't have a refresh functionality. You keep it active in your app session as long as you need it to, then when you expire the session, or when it expires, show the user the SIWA button again to re-authenticate.

What I do in my Laravel app is:

  1. User clicks SIWA button and triggers auth process.
  2. Apple returns user data, including id_token, which contains a sub data-point. That is the unique ID of the user (not the email address).
  3. I check if the user exists based on the sub field. If the user doesn't exist, I create a new users record with the name and email address and a totally random password. Note that the name and email is only provided the first time they log in with Apple.
  4. Then I store the relevant user data in a social_credentials table, which links back to the user record, as well.
  5. The next time the user authenticates, I find the social_credentials record based on the unique ID provided by apple, retrieve the user relationship, and sign the user in.

I believe the data-points provided in the native sign-in process are the same as the ones in the web process.

Is this what you were looking for? Sorry if I misunderstood your question.

@jlubeck
Copy link
Author

jlubeck commented Oct 17, 2019

Thank you so much for taking your time to go through this with me.

Back to what I was saying, when I Sign In With Apple, I get back an identityToken which according to Apple's docs is:

A JSON Web Token (JWT) used to communicate information about the identity of the user in a secure way to the app. The ID token will contain the following information: Issuer Identifier, Subject Identifier, Audience, Expiry Time and Issuance Time signed by Apple's identity service.

Here is an example of the token I'm getting

{
  "iss": "https://appleid.apple.com",
  "aud": "my.bundle.id",
  "exp": 1571344329,
  "iat": 1571343729,
  "sub": "my.generated.user.id",
  "c_hash": "some.hash",
  "auth_time": 1571343729
}

As you can see, the difference between iat and exp is just 600 (10 minutes). And there is no way to get a new token unless you show the SIWA dialog to the user again (not a very good UX)

I got a lot of data from this blog post as well: https://blog.curtisherbert.com/so-theyve-signed-in-with-apple-now-what/

What he recommends is that on initial login, the server creates a refresh_token, and that is what I would save locally to re-auth after expiration.

Does that make sense to you? And if it does, would you know what would be the proper way to create this refresh_token (and use it as auth on subsequent calls) on Laravel?

Thanks again!

@mikebronner
Copy link
Owner

mikebronner commented Oct 17, 2019

@jlubeck From what I have been reading in the developer forums, there is no real use for the refresh token, and the refresh URL doesn't actually work. (I haven't tested this.)

Also, a lot has changed since many of these articles were written.

Refresh URLs and timeouts really are only of concern to OAuth endpoints that provide data or functionality, beyond just authentication. Right now SIWA is ONLY used for authentication purposes, so the expiration of the token is irrelevant at this time.

In Laravel I only ask the user to sign in again, if the Laravel session expires, I completely ignore SIWA expiration at this point.

Regarding handing off the refreshing of the token to Laravel, you could do that if it had any use, but it doesn't at this time.

I would only worry about your Laravel session, and if you are stateless, and only use your backend through an API, then you don't really need to re-auth your user at all, right? If you do need to identify your user, simply store his credendials (the sub element) in your iOS app and pass that along to your Laravel backend to identify the user.

I had a hard time wrapping my head around the differences between Apple's implementation and other OAuth implementations, until I realized that it is only an authentication service, and doesn't actually have additional endpoints where the access_token is used against. That means all the additional OAuth functionality one would expect isn't actually there, beyond just getting a positive identification on a user.

Hope this helps. :)

@jlubeck
Copy link
Author

jlubeck commented Oct 17, 2019

Hehe, that's funny, because you mention

I would only worry about your Laravel session, and if you are stateless, and only use your backend through an API

and that is precisely my situation haha

But all good! between you and that post I showed you, I think I know what to do.

I'll keep you posted if you are interested!

@mikebronner
Copy link
Owner

Sure, would love to hear how you end up solving this.

My initial ideas would be (if I were starting this from scratch):

  • use Laravel Passport for securing the API endpoints.
  • identify the user through middleware (by passing the necessary info as discussed above) from your iOS app to the Laravel app).
  • log the user in, and refer to the user as auth()->user() wherever you need to in your code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants