diff --git a/OAuth2-Backend-Approach.md b/OAuth2-Backend-Approach.md
index ea82a2a..f5d1e07 100644
--- a/OAuth2-Backend-Approach.md
+++ b/OAuth2-Backend-Approach.md
@@ -134,8 +134,51 @@ app.get('/auth/google/callback', async (req, res) => {
});
```
+
+
+
+
+
+
+
# 3. Use Token
+1. Front **GET** profile data from Back `https://xorismesiti.gr/api/auth/profile` using the `cookie`
+2. Back **GET** profile data from Google `https://www.googleapis.com/oauth2/v3/userinfo` using the `access_token` from Front `cookie`
+3. Google **response** to Back with profile data
+4. Back **response** to Front with profile data
+
+
+3. Google **response** to Back with profile data
+
+```
+{
+ "sub": "1234567890",
+ "name": "John Doe",
+ "given_name": "John",
+ "family_name": "Doe",
+ "profile": "https://plus.google.com/1234567890",
+ "picture": "https://lh3.googleusercontent.com/a-/AOh14GgIXXl5JXzW0c1Szbl-e1Jch1vhl5rHhH65vlK6J5g5PqkGjj1O0p3t8bgVEOykQ6ykFSQ=s96",
+ "email": "john.doe@example.com",
+ "email_verified": true,
+ "locale": "en"
+}
+```
+
+
+
+4. Back **response** to Front with profile data
+
+```
+{
+ "sub": "1234567890",
+ "name": "John Doe",
+ "picture": "https://lh3.googleusercontent.com/8bgVEOykQ6ykFSQ=s96",
+ "email": "john.doe@example.com",
+}
+```
+
+
```js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
@@ -202,30 +245,11 @@ export default App;
-------------------------
-
-
-
-# 4. [Frontend] Use the Token
-
-1. The frontend receives the tokens from the Backend response,
-2. Store them in the localStorage of the browser
-3. Make authenticated requests directly to Google API
-
-
-Frontend HTTP GET Request to Backend
-
```bash
GET https://xorismesiti.gr/api/user-profile
Authorization: Bearer access-token-from-backend
```
-
-
-**↴** Step 5 takes place here: The Backend request the user data from Google using the Tokens
-
-
-Backedn HTTP Response to Frontend
-
```json
{
"sub": "1234567890",
@@ -240,127 +264,11 @@ Authorization: Bearer access-token-from-backend
}
```
-
-
-
-Frontend Code
-
-```js
-// 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);
-};
-
-// 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();
-```
-
-
-
-
-
-
-
-
-
-
-
-
-
-# 5. [Backend] Fetch User Data
-
-With the access token obtained in the previous step,
-
-your platform can now use it to fetch the user's Google profile and email information.
-
-The token is included in the Authorization header of the request.
-
-
-HTTP GET Request
-
```sh
GET https://www.googleapis.com/oauth2/v3/userinfo
Authorization: Bearer ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5Xv78is7BEHekVX-VoA
```
-- URL: https://www.googleapis.com/oauth2/v3/userinfo
-- HTTP Method: GET
-- Headers:
-- Authorization: Bearer {access_token}: The access token obtained in step 5.
-
-
-
-
-HTTP Response
-
```json
{
"sub": "1234567890",
@@ -377,179 +285,10 @@ Authorization: Bearer ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5
-
-
-
-Backend GET 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
-
-// Function to validate the access token by making a request to the Google user info endpoint
-const validateAccessToken = async (accessToken) => {
- try {
- const response = await axios.get('https://www.googleapis.com/oauth2/v3/userinfo', {
- headers: {
- Authorization: `Bearer ${accessToken}`,
- },
- });
-
- // If this succeeds, the token is valid
- return response.data; // Return the user data
- } catch (error) {
- // If the request fails (token is invalid or expired), throw an error
- throw new Error('Invalid or expired access token');
- }
-};
-
-// Example route for fetching the user profile
-app.get('/api/user-profile', async (req, res) => {
- const accessToken = req.headers['authorization']?.split(' ')[1]; // Extract token from Authorization header
-
- if (!accessToken) {
- return res.status(400).json({ error: 'No access token provided' });
- }
-
- try {
- // Validate the access token by fetching user info from Google
- const userData = await validateAccessToken(accessToken);
-
- // Send the user profile data to the frontend
- res.json(userData);
- } catch (error) {
- // Handle invalid or expired token
- console.error('Error validating access token:', error);
- res.status(401).json({ error: 'Invalid or expired access token' });
- }
-});
-
-// Start the server
-app.listen(3000, () => {
- console.log('Server running on http://localhost:3000');
-});
-```
-
-
-
-
-Front GET Code
-
-```js
-// After receiving the token, store it in the frontend (e.g., localStorage or context)
-localStorage.setItem('access_token', response.access_token);
-
-// Use it to make authenticated API requests to the backend
-fetch('/api/user-profile', {
- headers: {
- 'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
- },
-})
- .then(response => {
- if (response.status === 401) {
- // Handle token expiration or invalid token
- console.error('Access token expired or invalid. Please log in again.');
- // Optionally, redirect to login page or refresh token
- } else {
- return response.json();
- }
- })
- .then(data => {
- // Handle user data
- console.log(data);
- })
- .catch(error => {
- console.error('Error fetching user profile:', error);
- });
-```
-
-
-
-
-
-
-
-
-
-
-# 6. [Backend] Token Expiry and Refresh (Optional)
-
-If the access token expires,
-
-your platform can use the refresh token (if provided) to obtain a new access token without requiring the user to log in again.
-
-
-
-HTTP POST Request
-
-```bash
-POST https://oauth2.googleapis.com/token
-Content-Type: application/x-www-form-urlencoded
-
-grant_type=refresh_token&
-refresh_token=refresh-token-from-backend&
-client_id=YOUR_GOOGLE_CLIENT_ID&
-client_secret=YOUR_GOOGLE_CLIENT_SECRET
-```
-
-- `URL`: https://oauth2.googleapis.com/token
-- `HTTP` Method: POST
-- `Headers`:
-- `Content`-Type: application/x-www-form-urlencoded
-- `Body` Parameters:
-- `grant_type`=refresh_token: This indicates the refresh token flow.
-- `refresh_token`: The refresh token obtained in step 5.
-- `client_id`: Your Google API client ID.
-- `client_secret`: Your Google API client secret.
-
-
-
-
-HTTP Response
-
```json
{
"access_token": "ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5Xv78is7BEHekVX-VoA",
"token_type": "Bearer",
"expires_in": 3600
}
-```
-
-
-
-
-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' });
- }
-});
-```
-
-
-
-
-
+```
\ No newline at end of file