diff --git a/OAuth2.md b/OAuth2.md index b971a01..e557f82 100644 --- a/OAuth2.md +++ b/OAuth2.md @@ -14,6 +14,20 @@ A way for the `user` to tell `google` to give an access token to `xorismesiti.gr +### Summary of Tasks Split Across Frontend and Backend: + +***Frontend** +1. Redirect the user to Google's OAuth authorization endpoint. +2. Capture the authorization code after Google redirects back to the frontend. +3. Send the authorization code to the backend for token exchange. + +**Backend** +1. Handle the token exchange (exchange the authorization code for an access token and refresh token). +2. Optionally fetch user profile data from Google (or other resources) using the access token. +3. Store the tokens securely (in session or a database). +4. Provide a way to refresh the access token if it expires. +5. By splitting the OAuth flow this way, the sensitive details (like the client secret and token exchange) remain secure on the backend, while the frontend handles user interaction. + # 1. [Frontend] Request Authorization code @@ -39,6 +53,24 @@ GET https://accounts.google.com/o/oauth2/v2/auth? - `scope`: The permissions you're requesting (e.g., email, profile). - `state`: A random string to protect against CSRF attacks. +
+

Example Frontent Code

+ +```js +// Redirect to Google's OAuth 2.0 endpoint when user clicks login +const loginWithGoogle = () => { + const clientId = 'YOUR_GOOGLE_CLIENT_ID'; // Replace with your actual Google Client ID + const redirectUri = 'https://xorismesiti.gr/api/auth/callback'; // Backend URL where Google will send the user after login + const scope = 'email profile'; // Scopes you're requesting (email, profile, etc.) + const state = 'random-state-value'; // For CSRF protection + + const googleAuthUrl = `https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}&state=${state}`; + + window.location.href = googleAuthUrl; // Redirect user to Google +}; +``` + +
@@ -52,7 +84,7 @@ GET https://accounts.google.com/o/oauth2/v2/auth? The frontend must not directly exchange the `code` for an `access_token`. Instead, it sends the `code` to the backend via an API request.
-

Frontend Code:

+

Example Frontend Code

```js // On the backend callback URL, the frontend receives the authorization code @@ -92,6 +124,10 @@ export default Callback;
+ + + + # 3. Backend (Node.js): Handle Token Exchange 1. The backend receives the authorization `code` from the frontend, @@ -122,7 +158,7 @@ client_secret=YOUR_GOOGLE_CLIENT_SECRET ```
-

Backend Code:

+

Example Backend Code:

```js const express = require('express'); @@ -172,6 +208,78 @@ app.listen(3000, () => { + + + +# 5. [Backend] Fetch User Data (Optional) + +If you want to fetch the user profile data (e.g., from Google), your backend can use the `access_token` to request it from Google’s user info endpoint. + + +
+

Example Backend Code:

+ +```js +app.get('/api/user-profile', async (req, res) => { + const accessToken = req.headers['authorization'].split(' ')[1]; // Extract token from Authorization header + + try { + const response = await axios.get('https://www.googleapis.com/oauth2/v3/userinfo', { + headers: { + Authorization: `Bearer ${accessToken}`, + }, + }); + + // Send the user profile data to the frontend + res.json(response.data); + } catch (error) { + console.error('Error fetching user profile:', error); + res.status(500).json({ error: 'Failed to fetch user profile' }); + } +}); +``` + +
+ + + + + + + + +# 6. [Backend] Token Expiry and Refresh (Optional) + +
+

Example Backend Code:

+ +```js +app.post('/api/auth/refresh-token', async (req, res) => { + const { refresh_token } = req.body; + + try { + const response = await axios.post('https://oauth2.googleapis.com/token', null, { + params: { + refresh_token, + client_id: clientId, + client_secret: clientSecret, + grant_type: 'refresh_token', + }, + }); + + res.json(response.data); // Return new access token and refresh token + } catch (error) { + console.error('Error refreshing access token:', error); + res.status(500).json({ error: 'Failed to refresh access token' }); + } +}); +``` + +
+ + + + ```sh GET https://xorismesiti.gr/callback? code=4/0AX4XfWgNmGZVbV7Kdr8Q9yVyzIYBnbbBdLfX39ZaE8m0w8zT8jKRLl7w-uT8k7WiyLg0Q&