- 📱 Mobile
- 🖥️ Web
This library uses Auth0.Android on Android, and Auth0.swift on iOS.
Auth0.Android declares a RedirectActivity
along with an intent-filter in its Android Manifest file to handle the Web Auth callback and logout URLs. While this approach prevents the developer from adding an activity declaration to their app's Android Manifest file, it requires the use of manifest placeholders.
Alternatively, you can re-declare the RedirectActivity
in the android/app/src/main/AndroidManifest.xml
file with your own intent-filter so it overrides the library's default one. If you do this, the manifestPlaceholders
don't need to be set as long as the activity contains tools:node="replace"
like in the snippet below.
<!-- android/src/main/AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.company.myapp">
<application android:theme="@style/AppTheme">
<!-- ... -->
<activity
android:name="com.auth0.react.RedirectActivity"
tools:node="replace">
<intent-filter
android:autoVerify="true"
tools:targetApi="m">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- add a data tag for each environment -->
<data
android:host="example.com"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${auth0Scheme}" />
<data
android:host="qa.example.com"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${auth0Scheme}" />
</intent-filter>
</activity>
<!-- ... -->
</application>
</manifest>
Auth0.swift uses ASWebAuthenticationSession
to perform web-based authentication, which is the API provided by Apple for such purpose.
That alert box is displayed and managed by ASWebAuthenticationSession
, not by Auth0.swift, because by default this API will store the session cookie in the shared Safari cookie jar. This makes Single Sign-On (SSO) possible. According to Apple, that requires user consent.
Note See this blog post for a detailed overview of SSO on iOS.
If you don't need SSO, you can disable this behavior by adding useEphemeralSession: true
to the login call. This will configure ASWebAuthenticationSession
to not store the session cookie in the shared cookie jar, as if using an incognito browser window. With no shared cookie, ASWebAuthenticationSession
will not prompt the user for consent.
// No SSO, therefore no alert box
final credentials =
await auth0.webAuthentication().login(useEphemeralSession: true);
Note that with useEphemeralSession: true
you don't need to call logout()
at all. Just clearing the credentials from the app will suffice. What logout()
does is clear the shared session cookie, so that in the next login call the user gets asked to log in again. But with useEphemeralSession: true
there will be no shared cookie to remove.
You still need to call logout()
on Android, though, as useEphemeralSession
is iOS-only.
Warning >
useEphemeralSession
relies on theprefersEphemeralWebBrowserSession
configuration option ofASWebAuthenticationSession
. This option is only available on iOS 13+, souseEphemeralSession
will have no effect on iOS 12. To improve the experience for iOS 12 users, see the approach described below.
An alternative is to use SFSafariViewController
instead of ASWebAuthenticationSession
. You can do so by setting the safariViewController
property during login:
await auth0
.webAuthentication()
.login(safariViewController: const SafariViewController());
Note Since
SFSafariViewController
does not share cookies with the Safari app, SSO will not work either. But it will keep its own cookies, so you can use it to perform SSO between your app and your website as long as you open it inside your app usingSFSafariViewController
. This also means that any feature that relies on the persistence of cookies will work as expected.
If you choose to use SFSafariViewController
, you need to perform an additional bit of setup. Unlike ASWebAuthenticationSession
, SFSafariViewController
will not automatically capture the callback URL when Auth0 redirects back to your app, so it's necessary to manually resume the Web Auth operation.
Using the UIKit app lifecycle
// AppDelegate.swift
override func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool {
WebAuthentication.resume(with: url)
return super.application(application, open: url, options: options);
}
Using the UIKit app lifecycle with Scenes
// SceneDelegate.swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
WebAuthentication.resume(with: url)
}
Since logout()
on iOS also needs to use ASWebAuthenticationSession
to clear the shared session cookie, the same alert box will be displayed.
If you need SSO and/or are willing to tolerate the alert box on the login call, but would prefer to get rid of it when calling logout()
, you can simply not call logout()
and just clear the credentials from the app. This means that the shared session cookie will not be removed, so to get the user to log in again you need to add the 'prompt': 'login'
parameter to the login call.
final credentials = await auth0.webAuthentication().login(
useEphemeralSession: true,
parameters: {
'prompt': 'login'
}); // Ignore the cookie (if present) and show the login page
Otherwise, the browser modal will close right away and the user will be automatically logged in again, as the cookie will still be there.
Warning Keeping the shared session cookie may not be an option if you have strong privacy and/or security requirements, for example in the case of a banking app.
This library has no control whatsoever over the alert box. Its contents cannot be changed. Unfortunately, that's a limitation of ASWebAuthenticationSession
.
This library has no control whatsoever over the alert box. It cannot be closed programmatically. Unfortunately, that's a limitation of ASWebAuthenticationSession
.
This library uses the Auth0 SPA SDK on the web platform.
After logging in, if the page is refreshed and the user appears logged out, it usually means that the silent authentication step has failed to work.
This could be affected by a couple of things:
- When not using refresh tokens, the SPA SDK relies on third-party cookie support to log in silently. If you're not using refresh tokens, you could be using a browser that blocks third-party cookies by default (Safari, Brave, etc)
- You're using the classic login experience, and trying to log in using a social provider that uses Auth0's developer keys (see Limitations of Developer Keys when using Classic Universal Login)
Please try these to see if you can get unblocked:
- Try it in a browser like Chrome which does not block third-party cookies by default (yet)
- Use the new login experience, if possible
- Supply the social connection with your own client ID and secret in the Auth0 dashboard
By default, the SPA SDK uses the prompt=none
and response_mode=web_message
flow for silent auth, which depends on the user's Auth0 session.
If you have Require Multi-factor Auth set to Always
in your Auth0 Dashboard, silent authentication from your SPA will fail unless:
- The user is using a one-time code and selects Remember me for 30 days
allowRememberBrowser
is configured in a Rule andprovider
is set togoogle-authenticator
If silent auth is being used and Auth0 needs interaction from the user to complete the MFA step, then authentication will fail with an mfa_required
error and the user must log in interactively.
To resolve this:
- Use a Rule to configure the MFA step to allow the user to remember the browser for up to 30 days.
- Use refresh tokens + local storage so that the auto-login on page refresh does not depend on the user's session. Please read the docs on storage options and rotating refresh tokens as these change the security profile of your application.
Internally, the SPA SDK uses Web Cryptography API to create SHA-256 digest.
According to the spec (via Github issues), Web Cryptography API requires a secure origin, so that accessing Crypto.subtle
in a not secure context returns undefined
.
In most browsers, secure origins are origins that match at least one of the following (scheme, host, port) patterns:
(https, *, *)
(wss, *, *)
(*, localhost, *)
(*, 127/8, *)
(*, ::1/128, *)
(file, *, —)
If you're running your application from a secure origin, it's possible that your browser doesn't support the Web Crypto API. For a compatibility table, please check https://caniuse.com/#feat=mdn-api_subtlecrypto.