Skip to content

Commit 7d9a929

Browse files
refactor: Enhance web authentication flow with hooks and class-based examples, update documentation, and add redirect handling
1 parent f07a79f commit 7d9a929

7 files changed

Lines changed: 377 additions & 127 deletions

File tree

EXAMPLES-WEB.md

Lines changed: 99 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,119 +2,159 @@
22

33
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.
44

5-
## Setup: The `Auth0Provider`
5+
## 1. The Hooks-Based Approach (Recommended)
66

7-
All web-based authentication starts with wrapping your application in the `Auth0Provider`. You can also pass `auth0-spa-js` specific options.
7+
This is the simplest and recommended way to integrate Auth0. The `Auth0Provider` handles all the complexity of the redirect flow automatically.
8+
9+
### Step 1: Wrap Your App in the `Auth0Provider`
10+
11+
In your main application entry point (e.g., `App.tsx`), wrap your application with the provider.
812

913
```jsx
10-
// App.js
14+
// src/App.tsx
15+
import React from 'react';
1116
import { Auth0Provider } from 'react-native-auth0';
17+
import config from './auth0-configuration';
18+
import MainComponent from './MainComponent'; // Your main app UI
1219

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-
};
20+
const App = () => (
21+
<Auth0Provider domain={config.domain} clientId={config.clientId}>
22+
<MainComponent />
23+
</Auth0Provider>
24+
);
2625

2726
export default App;
2827
```
2928

30-
## Basic Login and Logout
29+
### Step 2: Use the `useAuth0` Hook in Your Components
3130

32-
Use the `useAuth0` hook to access authentication methods and state. The primary flow involves redirecting the user to the Auth0 Universal Login page.
31+
The `Auth0Provider` will automatically handle the redirect callback when your app loads. The `useAuth0` hook will then provide the authentication state.
3332

3433
```jsx
34+
// src/MainComponent.tsx
35+
import React from 'react';
3536
import { useAuth0 } from 'react-native-auth0';
36-
import { View, Button, Text } from 'react-native';
37+
import { View, Button, Text, ActivityIndicator } from 'react-native';
3738

38-
const LoginProfile = () => {
39-
const { authorize, clearSession, user, error, isLoading } = useAuth0();
39+
const MainComponent = () => {
40+
const { authorize, clearSession, user, isLoading, error } = useAuth0();
4041

4142
const onLogin = async () => {
4243
try {
43-
// This will redirect the user to the login page.
44-
// The promise does not resolve as the page context is lost.
44+
// This triggers a redirect to the Auth0 Universal Login page.
4545
await authorize({ scope: 'openid profile email' });
4646
} catch (e) {
47-
console.log('Login cancelled or failed', e);
47+
console.error('Login error:', e);
4848
}
4949
};
5050

5151
const onLogout = async () => {
5252
try {
53-
// This will redirect the user to the logout page.
5453
await clearSession();
5554
} catch (e) {
56-
console.log('Logout error', e);
55+
console.error('Logout error:', e);
5756
}
5857
};
5958

6059
if (isLoading) {
6160
return (
6261
<View>
63-
<Text>Loading...</Text>
62+
<ActivityIndicator size="large" />
6463
</View>
6564
);
6665
}
6766

6867
return (
6968
<View>
70-
{user && (
69+
{error && <Text>Error: {error.message}</Text>}
70+
{user ? (
7171
<>
72-
<Text>Logged in as {user.name}</Text>
73-
<Button onPress={onLogout} title="Log Out" />
72+
<Text>Welcome, {user.name}!</Text>
73+
<Button title="Log Out" onPress={onLogout} />
7474
</>
75+
) : (
76+
<Button title="Log In" onPress={onLogin} />
7577
)}
76-
{!user && <Button onPress={onLogin} title="Log In" />}
77-
{error && <Text style={{ color: 'red' }}>{error.message}</Text>}
7878
</View>
7979
);
8080
};
8181
```
8282

83-
## Accessing User Information and Tokens
83+
## 2. The Class-Based / Manual Approach
84+
85+
If you are not using React Hooks or need more fine-grained control, you can instantiate the `Auth0` class and handle the redirect callback manually.
86+
87+
### Step 1: Instantiate the `Auth0` Client
88+
89+
Create a singleton instance of the client.
90+
91+
```javascript
92+
// src/api/auth0.ts
93+
import Auth0 from 'react-native-auth0';
94+
import config from '../auth0-configuration';
95+
96+
const auth0 = new Auth0({
97+
domain: config.domain,
98+
clientId: config.clientId,
99+
});
100+
101+
export default auth0;
102+
```
103+
104+
### Step 2: Handle the Redirect Callback
84105

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`.
106+
In your application's root component or entry point, you need to add logic to process the result from Auth0 after the user is redirected back.
86107

87108
```jsx
88-
import { useAuth0 } from 'react-native-auth0';
109+
// src/App.tsx
110+
import React, { useEffect, useState } from 'react';
111+
import { View, Button, Text } from 'react-native';
112+
import auth0 from './api/auth0'; // Import your singleton
113+
import type { User } from 'react-native-auth0';
89114

90-
const Profile = () => {
91-
const { user } = useAuth0();
92-
return user ? <Text>Welcome, {user.name}!</Text> : null;
93-
};
115+
const App = () => {
116+
const [user, setUser] = useState<User | null>(null);
117+
const [isLoading, setIsLoading] = useState(true);
118+
119+
useEffect(() => {
120+
const checkSession = async () => {
121+
// Check if the URL contains redirect parameters
122+
if (window.location.search.includes('code=') && window.location.search.includes('state=')) {
123+
try {
124+
// Process the redirect
125+
await auth0.webAuth.handleRedirectCallback();
126+
} catch (e) {
127+
console.error(e);
128+
}
129+
// Clean the URL
130+
window.history.replaceState({}, document.title, '/');
131+
}
132+
133+
// After handling a potential redirect, check for an existing session
134+
try {
135+
const credentials = await auth0.credentialsManager.getCredentials();
136+
// Assuming you have a way to decode the idToken to get the user
137+
// const decodedUser = jwt_decode(credentials.idToken);
138+
// setUser(decodedUser);
139+
} catch (e) {
140+
// No credentials, user is not logged in
141+
setUser(null);
142+
}
143+
setIsLoading(false);
144+
};
145+
146+
checkSession();
147+
}, []);
94148

95-
const ApiButton = () => {
96-
const { getCredentials } = useAuth0();
149+
const onLogin = async () => {
150+
await auth0.webAuth.authorize({ scope: 'openid profile email' });
151+
};
97152

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-
}
153+
const onLogout = async () => {
154+
await auth0.webAuth.clearSession();
115155
};
116156

117-
return <Button onPress={callApi} title="Call Protected API" />;
157+
// ... Render UI based on isLoading and user state ...
118158
};
119159
```
120160

@@ -129,7 +169,3 @@ For security reasons, the web platform **does not support** direct authenticatio
129169
- `auth.refreshToken()`
130170

131171
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-
```

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ This library provides a unified API across Native (iOS/Android) and Web platform
673673
| **Web Authentication** | | | --- |
674674
| `webAuth.authorize()` ||| **Primary login method.** Uses `ASWebAuthenticationSession`/`Custom Tabs` on Native and `loginWithRedirect` on Web. |
675675
| `webAuth.clearSession()` ||| **Primary logout method.** Clears the session cookie on the server via a browser redirect. |
676+
| `webAuth.handleRedirectCallback()` ||| **Web-only.** Manually processes the callback from Auth0. Handled automatically when using the `Auth0Provider` hook. |
676677
| **Credential Management** | | | --- |
677678
| `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`. |
678679
| `credentialsManager.hasValidCredentials()` ||| Checks for a valid local session. |

0 commit comments

Comments
 (0)