Update OAuth2.md
This commit is contained in:
parent
128d95b6c6
commit
f374f492ac
87
OAuth2.md
87
OAuth2.md
@ -41,6 +41,8 @@ A way for the `user` to tell `google` to give an access token to `xorismesiti.gr
|
|||||||
2. After the redirection, the user will log in to Google and grant permissions (if they haven’t already).
|
2. After the redirection, the user will log in to Google and grant permissions (if they haven’t already).
|
||||||
3. Google will redirect the user back to your redirect_uri `https://xorismesiti.gr/callback` with an authorization code `?code=`
|
3. Google will redirect the user back to your redirect_uri `https://xorismesiti.gr/callback` with an authorization code `?code=`
|
||||||
|
|
||||||
|
*Security: the state string should be validated upon receiving the response from Google, as it ensures that the response corresponds to the request.*
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h3>Frontend HTTP GET Request to Google</h3></summary>
|
<summary><h3>Frontend HTTP GET Request to Google</h3></summary>
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ const loginWithGoogle = () => {
|
|||||||
|
|
||||||
# 2. [Frontend] Receive Authorization Code
|
# 2. [Frontend] Receive Authorization Code
|
||||||
|
|
||||||
Now that the frontend have the Authorization `code` on th callback url https://xorismesiti.gr/api/auth/callback`?code=AAAABCX4XfWgyVyziyLg0QHHHHH` it can send it to the backend with POST to `xorismesiti.gr/api/auth/exchange-token`, in order the backend to exchange the `code` for an `access_token` and optionally an `refresh_token`
|
Now that the frontend has the Authorization `code` on th callback url https://xorismesiti.gr/api/auth/callback`?code=AAAABCX4XfWgyVyziyLg0QHHHHH` it can send it to the backend with POST to `xorismesiti.gr/api/auth/exchange-token`, in order the backend to exchange the `code` for an `access_token` and optionally an `refresh_token`
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h3>Frontend HTTP POST Request to Backend</h3></summary>
|
<summary><h3>Frontend HTTP POST Request to Backend</h3></summary>
|
||||||
@ -324,22 +326,81 @@ Authorization: Bearer access-token-from-backend
|
|||||||
<summary><h3>Frontend Code</h3></summary>
|
<summary><h3>Frontend Code</h3></summary>
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// After receiving the token, store it in the frontend (e.g., localStorage or context)
|
// Store tokens and expiration time after receiving them from the backend
|
||||||
localStorage.setItem('access_token', response.access_token);
|
const storeTokens = (access_token, refresh_token, expires_in) => {
|
||||||
|
const expirationTime = Date.now() + expires_in * 1000; // expires_in is in seconds, so multiply by 1000 to get ms
|
||||||
|
localStorage.setItem('access_token', access_token);
|
||||||
|
localStorage.setItem('refresh_token', refresh_token);
|
||||||
|
localStorage.setItem('token_expiration', expirationTime);
|
||||||
|
};
|
||||||
|
|
||||||
// Use it to make authenticated API requests to the backend
|
// Function to check if the access token has expired
|
||||||
fetch('/api/user-profile', {
|
const isTokenExpired = () => {
|
||||||
|
const expirationTime = localStorage.getItem('token_expiration');
|
||||||
|
return Date.now() > expirationTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to refresh the access token using the refresh token
|
||||||
|
const refreshAccessToken = async () => {
|
||||||
|
const refresh_token = localStorage.getItem('refresh_token');
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/auth/refresh-token', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ refresh_token }),
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
// Handle user data
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error fetching user profile:', error);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.access_token) {
|
||||||
|
// Store the new access token and expiration time
|
||||||
|
storeTokens(data.access_token, data.refresh_token, data.expires_in);
|
||||||
|
return data.access_token;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error refreshing token:', error);
|
||||||
|
return null; // Handle error appropriately (e.g., logout user or prompt to log in again)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to get the access token, either from localStorage or by refreshing it if expired
|
||||||
|
const getAccessToken = async () => {
|
||||||
|
if (isTokenExpired()) {
|
||||||
|
console.log('Access token expired. Refreshing...');
|
||||||
|
const newAccessToken = await refreshAccessToken();
|
||||||
|
return newAccessToken;
|
||||||
|
} else {
|
||||||
|
return localStorage.getItem('access_token');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example usage: Get the access token and use it for an authenticated API request
|
||||||
|
const fetchUserProfile = async () => {
|
||||||
|
const access_token = await getAccessToken();
|
||||||
|
|
||||||
|
if (!access_token) {
|
||||||
|
console.error('No valid access token found. User might need to log in.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now you can use the access token to make an authenticated API request
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/user-profile', {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${access_token}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const userData = await response.json();
|
||||||
|
console.log(userData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching user profile:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example call to fetch user profile
|
||||||
|
fetchUserProfile();
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user