diff --git a/OAuth2-Backend-Approach.md b/OAuth2-Backend-Approach.md
index e8687f1..2c7b36e 100644
--- a/OAuth2-Backend-Approach.md
+++ b/OAuth2-Backend-Approach.md
@@ -24,10 +24,9 @@ A way for the `user` to tell `google` to give an access to `xorismesiti.gr` app
2. Exchange Code with Token
- 1. Front **POST** the `code` to the Back `https://xorismesiti.gr/api/auth/exchange-token`
- 2. Back **POST** the `code` to Google `https://oauth2.googleapis.com/token`
- 3. Google **response** to Back with an `access_token` and a `refresh token`
- 4. Back **response** to Front with the `access_token` in a `cookie`
+ 1. Back **POST** the `code` to Google `https://oauth2.googleapis.com/token`
+ 2. Google **response** to Back with an `access_token` and a `refresh token`
+ 3. Back **response** to Front with the `access_token` in a `cookie`
3. Use Token
@@ -46,14 +45,14 @@ A way for the `user` to tell `google` to give an access to `xorismesiti.gr` app
```sh
GET https://accounts.google.com/o/oauth2/v2/auth?
- response_type=code& # This indicates you're using the "authorization code" flow.
- client_id=ABC34JHS9D& # Your Google API client ID created on the google API console.
- redirect_uri=https://xorismesiti.gr/callback& # The URI Google will redirect to after the user consents.
- scope=email%20profile& # The permissions you're requesting (e.g., email, profile).
- state=xyz123 # A random string to protect against CSRF attacks.
+ response_type=code& # This indicates you're using the "authorization code" flow.
+ client_id=ABC34JHS9D& # Your Google API client ID created on the google API console.
+ redirect_uri=https://xorismesiti.gr/api/auth/callback& # The URI Google will redirect to after the user consents.
+ scope=email%20profile& # The permissions you're requesting (e.g., email, profile).
+ state=xyz123 # A random string to protect against CSRF attacks.
```
-### Google **302** to Front
+### Google **302** to Back
```bash
HTTP/1.1 302 Found
@@ -64,145 +63,11 @@ Content-Length: 0
*Security: the state string should be validated upon receiving the response from Google, as it ensures that the response corresponds to the request.*
-2. Exchange Code with Token
+# 2. Exchange Code with Token
+### 1. Back **POST** the `code` to Google
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Frontend Code
-
-```js
-// Redirect to Google's OAuth 2.0 endpoint when user clicks login
-const loginWithGoogle = () => {
- const clientId = 'ABC34JHS9D'; // 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
-};
-```
-
-
-
-
-
-
-
-
-
-# 2. [Frontend] Receive Authorization Code
-
-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`
-
-
-Frontend HTTP POST Request to Backend
-
-```bash
-POST https://xorismesiti.gr/api/auth/exchange-token
-Content-Type: application/json
-
-{
- "code": "AAAABCX4XfWgyVyziyLg0QHHHHH"
-}
-```
-
-
-
-#### Step 3 takes place here, Backend exchanges the Code with the Tokens
-
-
-Backend HTTP Response to Frontend
-
-```json
-{
- "access_token": "ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5Xv78is7BEHekVX-VoA",
- "token_type": "Bearer",
- "expires_in": 3600,
- "refresh_token": "1//04d5XHqmn6Hdy3wTf5OYDP1SyBa74zEFURjddQ2A1cFw78PY13pQyWhlD2A6XhDQtKlrjAqU4kS3vGdMvckw",
- "scope": "email profile"
-}
-```
-
-
-
-
-Frontend Code
-
-```js
-// On the backend callback URL, the frontend receives the authorization code
-import { useEffect } from 'react';
-import { useRouter } from 'next/router';
-
-const Callback = () => {
- const router = useRouter();
-
- useEffect(() => {
- const { code, state } = router.query;
-
- // Send the authorization code to the backend for token exchange
- fetch('/api/auth/exchange-token', {
- method: 'POST',
- body: JSON.stringify({ code }),
- headers: {
- 'Content-Type': 'application/json',
- },
- })
- .then(response => response.json())
- .then(data => {
- // Handle success (store token, update UI, etc.)
- console.log(data); // Typically, you'll store the access token here or manage the user session.
- router.push('/dashboard'); // Redirect the user to their dashboard or home page.
- })
- .catch(error => {
- console.error('Error exchanging token:', error);
- });
- }, []);
-
- return Loading...
;
-};
-
-export default Callback;
-```
-
-
-
-
-
-
-
-
-
-# 3. [Backend] Exchange Code with Token
-
-1. The backend **receives** the authorization `code` form frontend (Frontend POST at `xorismesiti.gr/api/auth/exchange-token`)
-2. The backend **POST** Authorization `code` to Google API
-3. The Google API respond to backend POST with the tokens `access_token` and `refresh_token`
-4. The backend **respond** to frontend with the tokens (respond to frontend POST at `xorismesiti.gr/api/auth/exchange-token`)
-
-*Security: The backend never expose the client_secret to the frontend. This step should always be handled on the backend.*
-
-
-Backend HTTP POST Request to Google
+The Backend **POST** to Google
```sh
POST https://oauth2.googleapis.com/token
@@ -215,88 +80,71 @@ client_id=ABC34JHS9D&
client_secret=PASS1234
```
-- `HTTP Method`: POST
-- `URL`: https://oauth2.googleapis.com/token
-- Headers
- - `Content-Type`: application/x-www-form-urlencoded
-- Body
- - `grant_type`=authorization_code: This specifies the grant type.
- - `code`: The authorization code you received in the previous step.
- - `redirect_uri`: The same redirect URI used in the authorization request.
- - `client_id`: Your Google API client ID.
- - `client_secret`: Your Google API client secret (which should be kept secure).
-
-
-
-
-Google HTTP Response Backend
+The **response** from Google
```json
{
- "access_token": "ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5Xv78is7BEHekVX-VoA",
- "token_type": "Bearer",
- "expires_in": 3600,
- "refresh_token": "1//04d5XHqmn6Hdy3wTf5OYDP1SyBa74zEFURjddQ2A1cFw78PY13pQyWhlD2A6XhDQtKlrjAqU4kS3vGdMvckw",
- "scope": "email profile"
+ "access_token": "ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5Xv78is7BEHekVX-VoA",
+ "token_type": "Bearer",
+ "expires_in": 3600,
+ "refresh_token": "1//04d5XHqmn6Hdy3wTf5OYDP1SyBa74zEFURjddQ2A1cFw78PY13pQyWhlD2A6XhDQtKlrjAqU4kS3vGdMvckw",
+ "scope": "email profile"
}
```
-
-
-
-Backend Code:
+The Backend Code
```js
-const express = require('express');
-const axios = require('axios');
-
-const app = express();
-app.use(express.json()); // To parse JSON bodies
-
-const clientId = 'YOUR_GOOGLE_CLIENT_ID'; // Google Client ID
-const clientSecret = 'YOUR_GOOGLE_CLIENT_SECRET'; // Google Client Secret
-const redirectUri = 'https://xorismesiti.gr/api/auth/callback'; // Must match the one used in frontend
-
-// Handle token exchange
-app.post('/api/auth/exchange-token', async (req, res) => {
- const { code } = req.body;
+// Backend callback URL: http://localhost:3000/auth/google/callback
+app.get('/auth/google/callback', async (req, res) => {
+ const { code } = req.query; // Extract the code from the query string
try {
+ // Exchange the authorization code for access token and refresh token
const response = await axios.post('https://oauth2.googleapis.com/token', null, {
params: {
code,
client_id: clientId,
client_secret: clientSecret,
- redirect_uri: redirectUri,
+ redirect_uri: redirectUri, // Same as in Step 1
grant_type: 'authorization_code',
},
});
-
+
const { access_token, refresh_token, expires_in } = response.data;
- // Optionally, store the tokens in a secure location (e.g., session, database)
- // For now, send them back to the frontend (not recommended for production)
- res.json({ access_token, refresh_token, expires_in });
- } catch (error) {
- console.error('Error exchanging authorization code for token:', error);
- res.status(500).json({ error: 'Failed to exchange authorization code for access token' });
- }
-});
+ // Store tokens in session or cookies
+ res.cookie('access_token', access_token, { httpOnly: true, secure: true, maxAge: expires_in * 1000 });
+ res.cookie('refresh_token', refresh_token, { httpOnly: true, secure: true });
-// Start the server
-app.listen(3000, () => {
- console.log('Server running on http://localhost:3000');
+ // Respond to frontend or redirect as needed
+ res.send('Authentication successful! You can now use the app.');
+ } catch (error) {
+ console.error('Error exchanging code for tokens:', error);
+ res.status(500).send('Error during authentication');
+ }
});
```
-
-
-
+
+
+
+
+
+
+
+
+
+
+-------------------------
+
+
+
# 4. [Frontend] Use the Token
1. The frontend receives the tokens from the Backend response,