Skip to content

Commit 1f88157

Browse files
feat: Add usage examples for React Native Auth0 on Web and update migration guide for v5
1 parent e5200e2 commit 1f88157

3 files changed

Lines changed: 294 additions & 44 deletions

File tree

EXAMPLES-WEB.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# React Native Auth0 for Web: Examples
2+
3+
This guide provides usage examples specifically for developers targeting **React Native Web**. The web platform uses the underlying `@auth0/auth0-spa-js` library, and its features are aligned with browser security best practices.
4+
5+
## Setup: The `Auth0Provider`
6+
7+
All web-based authentication starts with wrapping your application in the `Auth0Provider`. You can also pass `auth0-spa-js` specific options.
8+
9+
```jsx
10+
// App.js
11+
import { Auth0Provider } from 'react-native-auth0';
12+
13+
const App = () => {
14+
return (
15+
<Auth0Provider
16+
domain="YOUR_AUTH0_DOMAIN"
17+
clientId="YOUR_AUTH0_CLIENT_ID"
18+
// Optional spa-js specific settings
19+
cacheLocation="localstorage"
20+
useRefreshTokens={true}
21+
>
22+
<YourAppRoot />
23+
</Auth0Provider>
24+
);
25+
};
26+
27+
export default App;
28+
```
29+
30+
## Basic Login and Logout
31+
32+
Use the `useAuth0` hook to access authentication methods and state. The primary flow involves redirecting the user to the Auth0 Universal Login page.
33+
34+
```jsx
35+
import { useAuth0 } from 'react-native-auth0';
36+
import { View, Button, Text } from 'react-native';
37+
38+
const LoginProfile = () => {
39+
const { authorize, clearSession, user, error, isLoading } = useAuth0();
40+
41+
const onLogin = async () => {
42+
try {
43+
// This will redirect the user to the login page.
44+
// The promise does not resolve as the page context is lost.
45+
await authorize({ scope: 'openid profile email' });
46+
} catch (e) {
47+
console.log('Login cancelled or failed', e);
48+
}
49+
};
50+
51+
const onLogout = async () => {
52+
try {
53+
// This will redirect the user to the logout page.
54+
await clearSession();
55+
} catch (e) {
56+
console.log('Logout error', e);
57+
}
58+
};
59+
60+
if (isLoading) {
61+
return (
62+
<View>
63+
<Text>Loading...</Text>
64+
</View>
65+
);
66+
}
67+
68+
return (
69+
<View>
70+
{user && (
71+
<>
72+
<Text>Logged in as {user.name}</Text>
73+
<Button onPress={onLogout} title="Log Out" />
74+
</>
75+
)}
76+
{!user && <Button onPress={onLogin} title="Log In" />}
77+
{error && <Text style={{ color: 'red' }}>{error.message}</Text>}
78+
</View>
79+
);
80+
};
81+
```
82+
83+
## Accessing User Information and Tokens
84+
85+
After a user is logged in, you can access their profile from the `user` object. To get a fresh access token for calling a protected API, use `getCredentials`.
86+
87+
```jsx
88+
import { useAuth0 } from 'react-native-auth0';
89+
90+
const Profile = () => {
91+
const { user } = useAuth0();
92+
return user ? <Text>Welcome, {user.name}!</Text> : null;
93+
};
94+
95+
const ApiButton = () => {
96+
const { getCredentials } = useAuth0();
97+
98+
const callApi = async () => {
99+
try {
100+
// getCredentials uses getTokenSilently() from auth0-spa-js
101+
// to get a valid token, refreshing it if necessary.
102+
const credentials = await getCredentials();
103+
const accessToken = credentials.accessToken;
104+
105+
const response = await fetch('https://api.example.com/data', {
106+
headers: {
107+
Authorization: `Bearer ${accessToken}`,
108+
},
109+
});
110+
const data = await response.json();
111+
console.log('API Data:', data);
112+
} catch (e) {
113+
console.error('Failed to get token or call API', e);
114+
}
115+
};
116+
117+
return <Button onPress={callApi} title="Call Protected API" />;
118+
};
119+
```
120+
121+
## Unsupported Web Features
122+
123+
For security reasons, the web platform **does not support** direct authentication grants. The following methods from the `auth` provider will throw a `NotImplemented` error:
124+
125+
- `auth.passwordRealm()`
126+
- `auth.loginWithOTP()`
127+
- `auth.loginWithSMS()`
128+
- `auth.loginWithEmail()`
129+
- `auth.refreshToken()`
130+
131+
All these flows should be configured in your [Auth0 Universal Login](https://auth0.com/docs/universal-login) page and initiated via the `authorize()` method.
132+
133+
```
134+
135+
```

MIGRATION_GUIDE.md

Lines changed: 133 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,159 @@
22

33
## Upgrading from v4 -> v5
44

5-
### Compatibility Requirements
5+
Version 5.0 of `react-native-auth0` is a significant update featuring a complete architectural overhaul. This new foundation improves performance, maintainability, and provides a more consistent API across all platforms.
66

7-
- **React**: v5 requires React 19 or higher
8-
- **React Native**: v5 requires React Native 0.78.0 or higher
9-
- **Expo**: v5 requires Expo 53 or higher
7+
Upgrading from v4.x requires addressing several breaking changes. Please follow this guide carefully.
108

11-
### Breaking Changes
9+
## 1. Compatibility & Installation
1210

13-
- **Platform Compatibility**: The minimum iOS deployment target is now 14.0. Update your iOS/Podfile with:
11+
Before updating the library, ensure your project meets the new minimum requirements.
1412

15-
```
16-
platform :ios, '14.0'
17-
```
13+
### Environment Requirements
1814

19-
- **Android Requirements**: Android SDK API level 35 or higher is now required
15+
- **React:** `19.0.0` or higher
16+
- **React Native:** `0.78.0` or higher
17+
- **Expo:** SDK `53` or higher
18+
- **iOS:** Deployment Target `14.0`
19+
- **Android:** Target SDK `35` or higher
2020

21-
### Migration Steps
21+
### Updating Your Project
2222

23-
#### For Regular React Native Projects
23+
#### For Standard React Native Projects:
2424

25-
1. First, ensure your project uses React 19 and React Native 0.78.0 or higher:
25+
1. **Upgrade React Native:**
26+
```bash
27+
npm install react@^19.0.0 react-native@^0.78.0
28+
```
29+
2. **Update this Library:**
30+
```bash
31+
npm install react-native-auth0@beta
32+
```
33+
3. **Update iOS Target:** In your `ios/Podfile`, set the platform version:
34+
```ruby
35+
platform :ios, '14.0'
36+
```
37+
4. **Install Pods:**
38+
```bash
39+
cd ios && pod install && cd ..
40+
```
2641

27-
```bash
28-
npm install react@^19.0.0
29-
npm install react-native@^0.78.0
30-
```
42+
#### For Expo Projects:
3143

32-
2. Update the react-native-auth0 package:
44+
1. **Upgrade Expo SDK:**
45+
```bash
46+
npx expo upgrade
47+
```
48+
2. **Update this Library:**
49+
```bash
50+
npm install react-native-auth0@beta
51+
```
52+
3. **Rebuild Native Code:**
53+
```bash
54+
npx expo prebuild --clean
55+
```
56+
> **Warning:** This will overwrite any manual changes in your `ios` and `android` directories.
3357

34-
```bash
35-
npm install react-native-auth0@beta
36-
```
58+
## 2. Breaking API Changes
3759

38-
3. Update your iOS minimum deployment target in your Podfile:
60+
The following API changes require code modifications in your application.
3961

40-
```ruby
41-
platform :ios, '14.0'
42-
```
62+
### Change #1: User Profile Properties are now `camelCase`
4363

44-
4. Install the updated pods:
45-
```bash
46-
cd ios && pod install && cd ..
47-
```
64+
To align with modern JavaScript standards, all properties on the `user` object are now `camelCase`.
4865

49-
#### For Expo Projects
66+
**✅ Action Required:** Update all references to `user` properties.
5067

51-
1. Update to Expo 53 or higher:
68+
| Before (snake_case) | After (camelCase) |
69+
| :-------------------- | :------------------- |
70+
| `user.given_name` | `user.givenName` |
71+
| `user.family_name` | `user.familyName` |
72+
| `user.email_verified` | `user.emailVerified` |
73+
| `user.phone_number` | `user.phoneNumber` |
74+
| ...and so on. | |
5275

53-
```bash
54-
npx expo upgrade
55-
```
76+
### Change #2: Credentials Object uses `expiresAt`
5677

57-
2. Update the react-native-auth0 package:
78+
The `Credentials` object no longer includes `expiresIn` (a duration). It now provides `expiresAt`, an absolute **UNIX timestamp** (in seconds), making expiration checks simpler and less error-prone.
5879

59-
```bash
60-
npm install react-native-auth0@beta
61-
```
80+
**✅ Action Required:** Replace all logic using `expiresIn` with `expiresAt`.
6281

63-
3. Rebuild your app:
64-
```bash
65-
npx expo prebuild --clean
66-
```
67-
Note: This will reset any manual changes to your native code.
82+
**Before:**
83+
84+
```javascript
85+
const expiresAt = Date.now() / 1000 + credentials.expiresIn;
86+
if (isExpired(expiresAt)) {
87+
// ...
88+
}
89+
```
90+
91+
**After:**
92+
93+
```javascript
94+
// Direct comparison is now possible
95+
if (credentials.expiresAt < Date.now() / 1000) {
96+
// ...
97+
}
98+
99+
// Or, use the new helper method (if you have an instance of the Credentials model):
100+
if (credentials.isExpired()) {
101+
// ...
102+
}
103+
```
104+
105+
### Change #3: Standardized `AuthError` Object
106+
107+
All errors thrown by the library are now instances of a single, consistent `AuthError` class. This replaces multiple error types like `CredentialsManagerError`.
108+
109+
**✅ Action Required:** Update your `try...catch` blocks to handle the new unified error object.
110+
111+
**Before:**
112+
113+
```javascript
114+
catch (e) {
115+
// Inconsistent properties like e.error, e.error_description
116+
console.error(e.message);
117+
}
118+
```
119+
120+
**After:**
121+
122+
```javascript
123+
import { AuthError } from 'react-native-auth0';
124+
125+
catch (e) {
126+
if (e instanceof AuthError) {
127+
// Consistent properties are now available
128+
console.error(e.name, e.message); // e.g., 'invalid_grant', 'The refresh token is invalid.'
129+
}
130+
}
131+
```
132+
133+
### Change #4: Updated `authorize` and `clearSession` Signatures
134+
135+
For improved clarity, SDK-specific options (like `ephemeralSession`) have been moved into a separate, second `options` object.
136+
137+
**✅ Action Required:** Restructure calls to `authorize` and `clearSession`.
138+
139+
**Before:**
140+
141+
```javascript
142+
// Mixed parameters and options
143+
await authorize({
144+
scope: 'openid profile',
145+
ephemeralSession: true,
146+
});
147+
```
148+
149+
**After:**
150+
151+
```javascript
152+
// Parameters and options are now separate arguments
153+
await authorize(
154+
{ scope: 'openid profile' }, // 1. OIDC / Auth0 Parameters
155+
{ ephemeralSession: true } // 2. SDK-Specific Options
156+
);
157+
```
68158
69159
## Upgrading from v3 -> v4
70160

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,31 @@ _Note_ : We have platform agnostic error codes available only for `CredentialsMa
664664
| `NO_NETWORK` | `NO_NETWORK` | |
665665
| `API_ERROR` | `API_ERROR` | |
666666

667+
## Features and Platform Support
668+
669+
This library provides a unified API across Native (iOS/Android) and Web platforms. However, due to security models and underlying technology, not all features are available on every platform.
670+
671+
| Feature / Method Category | Native (iOS/Android) | Web (Browser) | Notes & Rationale |
672+
| ------------------------------------------ | :------------------: | :-----------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
673+
| **Web Authentication** | | | --- |
674+
| `webAuth.authorize()` ||| **Primary login method.** Uses `ASWebAuthenticationSession`/`Custom Tabs` on Native and `loginWithRedirect` on Web. |
675+
| `webAuth.clearSession()` ||| **Primary logout method.** Clears the session cookie on the server via a browser redirect. |
676+
| **Credential Management** | | | --- |
677+
| `credentialsManager.getCredentials()` ||| Retrieves stored tokens. On Native, it uses the secure Keychain/Keystore. On Web, it uses the `@auth0/auth0-spa-js` cache and `getTokenSilently`. |
678+
| `credentialsManager.hasValidCredentials()` ||| Checks for a valid local session. |
679+
| `credentialsManager.saveCredentials()` ||| **Native-only.** Manually saving credentials is required on Native. On Web, this is handled automatically by the underlying SPA SDK and is a no-op. |
680+
| `credentialsManager.clearCredentials()` ||| Clears locally stored tokens. On Web, this performs a "local-only" logout. |
681+
| **Direct Authentication Grants** | | | --- |
682+
| `auth.passwordRealm()` ||| **Not supported on Web for security reasons.** The Resource Owner Password Grant exposes credentials to the browser and is not recommended for Single Page Applications. |
683+
| `auth.passwordless...()` ||| **Not supported on Web.** Passwordless flows on the web should be configured via Universal Login and initiated with `webAuth.authorize()`. |
684+
| `auth.loginWith...()` (OTP/SMS etc) ||| **Not supported on Web.** These direct grant flows are not secure for public clients like browsers. |
685+
| **Token & User Management** | | | --- |
686+
| `auth.refreshToken()` ||| **Not supported on Web.** Token refresh is handled automatically by `getCredentials()` via `getTokenSilently()` on the web. |
687+
| `auth.userInfo()` ||| Fetches the user's profile from the `/userinfo` endpoint using an access token. |
688+
| `auth.createUser()` ||| Calls the `/dbconnections/signup` endpoint. Works on both platforms. |
689+
| `auth.resetPassword()` ||| Calls the `/dbconnections/change_password` endpoint. Works on both platforms. |
690+
| `users(token).patchUser()` ||| Calls the Management API. Works on any platform with a valid token, but use with caution in the browser. |
691+
667692
## Troubleshooting
668693

669694
### Swift 6 Compatibility Issues on iOS
@@ -698,7 +723,7 @@ We appreciate feedback and contribution to this repo! Before you get started, pl
698723

699724
- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
700725
- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
701-
- [This repo's development guide](DEVELOPMENT.md)
726+
- [This repo's development guide](CONTRIBUTING.md)
702727

703728
### Raise an issue
704729

0 commit comments

Comments
 (0)