Update OAuth2.md

This commit is contained in:
Ste Vaidis 2024-12-15 15:10:30 +02:00
parent 128d95b6c6
commit f374f492ac

View File

@ -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 havent already).
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>
<summary><h3>Frontend HTTP GET Request to Google</h3></summary>
@ -100,7 +102,7 @@ const loginWithGoogle = () => {
# 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>
<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>
```js
// After receiving the token, store it in the frontend (e.g., localStorage or context)
localStorage.setItem('access_token', response.access_token);
// Store tokens and expiration time after receiving them from the backend
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
fetch('/api/user-profile', {
headers: {
'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
},
})
.then(response => response.json())
.then(data => {
// Handle user data
})
.catch(error => {
// Function to check if the access token has expired
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: {
'Content-Type': 'application/json',
},
});
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>