should I use a webview or external browser? Isn't ...
# android-architecture
u
should I use a webview or external browser? Isn't the point of it the delegating to a trusted 3rd party?
s
Use "Chrome Custom Tabs". It runs as part of your app (not like an external browser), but it is safer than a WebView. Look at the AppAuth open source library, it takes care of a lot for you.
u
The thing is this is a first party oauth2, so, does it makes sense?
I think its kind of pointless, but its already implemented so -_-
v
I might be mistaken, but it doesn’t look like a lot of apps display oauth functionality via a webview or custom tabs but rather a native display. Are they all doing it the wrong way?
s
You can make Chrome Custom Tabs look really like a native UI. Like hosting a plain WebView, you can style the ‘chrome’ around the web-view part of the Chrome Custom Tabs and make the HTML look like a native UI. I have not yet seen an oAuth flow entirely done in a native UI, apart from refreshing access-tokens. It always has involved an HTTP/HTML flow.
b
When you say first party does that mean it is an oauth api from within your company? If you use oauth in the webview then you cannot take advantage of previous cookies set in the browser, so that would be one downside. Using a webview was discouraged in a few IETF documents with the reasoning that it trains users to trust entering their credentials in a way that the hosting app can snoop on. Oauth providers have lets apps know they will be banned if caught using a webview. I wouldn't be surprised if you might eventually run afoul of a future apple or google rule around accepted webview usage. A combination of implementing proof key for code exchange (PKCE) in addition to app links seems like a safer bet; though app links is a bit of a pain to get setup.
s
WebViews are indeed discouraged. That is why “Chrome Custom Tabs” were introduced. They run in a separate process but appear natively inside the app and are well suited to run an oAuth flow.
b
Worth mentioning that chrome custom tabs is essentially a skinnable external browser app. When I was working on oauth2 implementation a few weeks ago, I found the name distracting to what it actually is.
s
And the ‘chrome custom tabs’ can run in your activity task stack for more seamless experience. But yes, the name does not make much sense to me either 🙂
👍 1
u
if you use chrome tabs, how you then intercept the redirect to your custom schema?
b
same way you handle normal deep links, add an intent-filter to your manifest. Ideally implement app links by adding a config file to your server, so no other app can listen for the same uri
u
@Brendan Weinstein yes its my company and multiple products use it (so I dont anticipate us banning us 😄 for using webview)
oh, right.. btw currntly this is the 1st activity of the app (has webview in layout). This probably wont work with chrome tabs, do you have sort of a intro activity where you have a "start" button which kicks you off to chrome tabs?
👌 2
b
if you control all the apps why not use contentprovider's to share auth tokens between the apps?
u
well, its complicated, and i didnt mean multiple android apps, nevermind it
what they did before is they had a app developer separate and didnt trust them so..oauth2, now you could argue its pointless but whatever
@Brendan Weinstein one more thing, can you clear the cookie jar somehow with chrome tabs programatically, or do I have to open up the thing on a special logout url just to clear it?
or simply put, how do you logout
b
I do not know. I would have to check the documentation
u
What my issue is that you too presumably, refresh tokens via okhttp interceptors, if that refresh fails. then you should logout the user
but to do that now, you need to open up the chrome tabs, thats such bs to code..terrible
or if you just borq the app data, then your cookies are still in the chrome tabs so, that will cause issues
b
I last used oauth2 for social login where we generate our own token after one-time auth
u
okay so the cookies you think are not part of the oauth2 protocol but our thing?
b
the reason I mentioned cookies is you do not want the user to have to re-enter their credentials every time you redirect them to the oauth provider. If they are already auth'd then the oauth provider can see that and offer a one-tap experience. When you create a webview it's like you are creating a brand new browser, so you won't have access to cookies stored while the user was browsing in their main browser app.
s
You don't use cookies when using oAuth(2). You get back an JWT. This JWT has an ID token which you then can use to obtain an access token (and a refresh token). Save the JWT token that is provided to you by the so-called callback URL. For your callback-URL, use a custom scheme that can be intercepted by either an Activity or a Service of your app (use intent-filter). When the Chrome Custom Tab, at the end of the auth flow, tries to go to that callback-URL your Activity/Service will intercept it, extract the JWT and store that JWT in secure storage. That stored JWT is your 'cookie'. Just delete your stored JWT to 'logout'. You may want to add a
logout
endpoint to your oAuth as well, to tell the backend the user has logged out, allowing it to perhaps clear session related data.
1
Note that almost all of this work is handled by 3rd party libraries such as AppAuth (apart from storing the JWT in (secure) storage).
f
Maybe you already know it but This is how it's been handled in AppAuth and it really explains well. https://github.com/openid/AppAuth-Android/blob/master/library/java/net/openid/appauth/AuthorizationManagementActivity.java Also this article explains how it is been handled in a some Fintech company like AppAuth https://blog.plaid.com/securing-webviews-with-chrome-custom-tabs/amp/?__twitter_impression=true