-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.js
189 lines (176 loc) · 5.51 KB
/
App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import React, {useState, useCallback, useMemo} from 'react';
import {Alert} from 'react-native';
import {
authorize,
refresh,
revoke,
prefetchConfiguration,
} from 'react-native-app-auth';
import {
Page,
Button,
ButtonContainer,
Form,
FormLabel,
FormValue,
Heading,
} from './components';
const configs = {
custom: {
issuer: 'http://localhost:8001',
clientId: 'wOzvSUDj4oWKOVJbiapZsZSEj6eqWjwhRFAtTBm1',
// The syntax for this is: <Android redirect url>:/<actual URL redirect path>
// redirect uri is from our mobile consumer tutorial
// ref: https://django-oauth-toolkit.readthedocs.io/en/latest/tutorial/tutorial_01.html#create-an-oauth2-client-application
redirectUrl: 'com.oauthlogin.auth://custom/login/callback/',
additionalParameters: {},
scopes: [
'openid' /* The additional scopes you set in the provider: 'profile', 'email'*/,
],
// You can find these endpoints in oauth2_provider.urls
serviceConfiguration: {
authorizationEndpoint: 'http://localhost:8001/o/authorize/',
tokenEndpoint: 'http://localhost:8001/o/token/',
revocationEndpoint: 'http://localhost:8001/o/revoke_token/',
},
},
};
const defaultAuthState = {
hasLoggedInOnce: false,
provider: '',
accessToken: '',
accessTokenExpirationDate: '',
// Refresh tokens don't expire for OAuth providers
// since we don't save username password here
refreshToken: '',
// These tokens are for your actual backend/consumer, not the provider's
appAccessToken: '',
appRefreshToken: '',
};
const App = () => {
const [authState, setAuthState] = useState(defaultAuthState);
React.useEffect(() => {
// noinspection JSIgnoredPromiseFromCall
prefetchConfiguration({
warmAndPrefetchChrome: true,
...configs.custom,
});
}, []);
const handleAuthorize = useCallback(async provider => {
try {
const config = configs[provider];
const newAuthState = await authorize(config);
fetch('http://localhost:8000/api/token/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
access_token: newAuthState.accessToken,
refresh_token: newAuthState.refreshToken,
}),
})
.then(response => {
console.log(response);
return response.json();
})
.then(json => {
setAuthState({
hasLoggedInOnce: true,
provider: provider,
appAccessToken: json.access_token,
appRefreshToken: json.refresh_token,
...newAuthState,
});
})
.catch(error => console.error(error));
} catch (error) {
Alert.alert('Failed to log in', error.message);
}
}, []);
const handleRefresh = useCallback(async () => {
try {
const config = configs[authState.provider];
const newAuthState = await refresh(config, {
refreshToken: authState.refreshToken,
});
setAuthState(current => ({
...current,
...newAuthState,
refreshToken: newAuthState.refreshToken || current.refreshToken,
}));
} catch (error) {
Alert.alert('Failed to refresh token', error.message);
}
}, [authState]);
const handleRevoke = useCallback(async () => {
try {
const config = configs[authState.provider];
await revoke(config, {
tokenToRevoke: authState.accessToken,
sendClientId: true,
});
setAuthState({
provider: '',
accessToken: '',
accessTokenExpirationDate: '',
refreshToken: '',
});
} catch (error) {
Alert.alert('Failed to revoke token', error.message);
}
}, [authState]);
const showRevoke = useMemo(() => {
if (authState.accessToken) {
const config = configs[authState.provider];
if (config.issuer || config.serviceConfiguration.revocationEndpoint) {
return true;
}
}
return false;
}, [authState]);
return (
<Page>
{authState.accessToken ? (
<Form>
<FormLabel>Provider Access Token</FormLabel>
<FormValue>{authState.accessToken}</FormValue>
<FormLabel>accessTokenExpirationDate</FormLabel>
<FormValue>{authState.accessTokenExpirationDate}</FormValue>
<FormLabel>Provider Refresh Token</FormLabel>
<FormValue>{authState.refreshToken}</FormValue>
<FormLabel>Consumer Access Token</FormLabel>
<FormValue>{authState.appAccessToken}</FormValue>
<FormLabel>Consumer Refresh Token</FormLabel>
<FormValue>{authState.appRefreshToken}</FormValue>
<FormLabel>scopes</FormLabel>
<FormValue>{authState.scopes.join(', ')}</FormValue>
</Form>
) : (
<Heading>
{authState.hasLoggedInOnce ? 'Goodbye.' : 'Hello, stranger.'}
</Heading>
)}
<ButtonContainer>
{!authState.accessToken ? (
<>
{/* If you copy this Button tag, you can add more OAuth apps */}
<Button
onPress={() => handleAuthorize('custom')}
text="Authorize Custom OAuth"
color="#DA2536"
/>
</>
) : null}
{authState.refreshToken ? (
<Button onPress={handleRefresh} text="Refresh" color="#24C2CB" />
) : null}
{showRevoke ? (
<Button onPress={handleRevoke} text="Revoke" color="#EF525B" />
) : null}
</ButtonContainer>
</Page>
);
};
export default App;