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

Is there a reason why the LINE SDKs do not return an authorization code to be used by a backend service? #167

Closed
lostllama opened this issue Aug 4, 2021 · 2 comments

Comments

@lostllama
Copy link

lostllama commented Aug 4, 2021

Referring to the documentation, native clients will send an access token and id token to our backend service. This means that we can't then obtain a refresh token, so when the access token expires we have no access to LINE APIs on behalf of the user. The only way to solve this is for the client to reauthenticate and send new tokens.

Web-based login on the other hand provides the server with an authorization code (docs) which can be exchanged for an access token and a refresh token.

This is a problem for us because we have implemented a login service, for both our web application and native applications, which exchanges external tokens for our own tokens. This works fine for other services (sign in with Apple, sign in with Google, etc.) which do provide an authorization code and therefore allow us to obtain a refresh token for those services. Internally we use the provider refresh token when the access token expires. As LINE does not provide a refresh token, we would have to also have the client send a new LINE access token if the old one has expired, and therefore update our database. I'm sure you can see how this will require us to branch our logic (i.e. if (line) { specialRefreshToken } else { normalRefreshToken }).

Considering the authorization code is used internally within the SDK, I don't quite understand why this is being closely guaraded client-side rather than making this available to pass to backend services instead of being exchanged behind the scenes. Can anybody comment on the reasons behind this (and why LINE is so different to other SSO providers like Google or Apple)?

@onevcat
Copy link
Member

onevcat commented Aug 4, 2021

Hi,

Thanks for opening this.

About authorization code

The native LINE SDK is not only an SSO login component (LINE Login), but also an API client for using other public LINE APIs. So a main target of this project is providing a self-contained solution for most developers. Making a client authorization code exchange can help those developers who wants to use LINE APIs even when they do not own their own server. Also, since the LINE Login in LINE SDK is a "mobile-first" login SSO, it contains more client-oriented secure features, but lack of the notorious client_secret.

You can intercept the authorization code from the URL which LINE Login service returns to you in the app delegate. It should be a URL query parameter under "code" and you can even refer to the LoginProcessURLResponse. However, you still need to expose the state and the PKPE codeVerifier, then send them to your server together to exchange the final token.

About refresh token

Since it might be a bit complicated to use the authorization code on your server, another more realistic way is just leaving the token exchange to LINE SDK, and sending access token and refresh token to your server.

However, sending and storing these tokens (access token or refresh token) is considered as violating agains Apple's App Store Review Guidelines:

An app may not store credentials or tokens to social networks off of the device and may only use such credentials or tokens to directly connect to the social network from the app itself while the app is in use.

We before also received some rejection report on this, so we recognize it as a "mis-use" to sending LINE access token or refresh token to your server for storing purpose. This is why we marked the refreshToken deprecated and private in AccessToken type (the access token is left as public since it is necessary to be used to identify user for your server).

LINE SDK manages the refreshing automatically. If you really need the refresh token, it would be trivial to fork this repo and change the _refreshToken from private to public. But keep in mind, refreshing the token on your server would lead an un-sync state between the token stored in your app and on your server, so some racing might happen if you use LINE's API on both side.

@lostllama
Copy link
Author

Thank you for your detailed reply. We might look into the intercept route in that case.

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