Update OAuth2-Backend-Approach.md

This commit is contained in:
Ste Vaidis 2025-01-07 16:38:45 +02:00
parent 17fad574ff
commit 4457e53ff1

View File

@ -1,6 +1,6 @@
### OAuth2 purpose
A way for the `user` to tell `google` to give an access to `xorismesiti.gr` app
A way for the `user` to tell `google` to give an access to `myapp` app
<br>
@ -12,25 +12,25 @@ A way for the `user` to tell `google` to give an access to `xorismesiti.gr` app
| 2 | Exchange Code with Token | ` Back ⇢ Google ⇢ Back ⇢ Front `|
| 4 | Use Token | ` Front ⇢ Back ⇢ Google ⇢ Back ⇢ Front `|
<br>
<br><br>
### Details:
1. Get Code
1. Get Authorization Code
1. Frontend **GET** to Google `https://accounts.google.com/o/oauth2` with callback url
2. Google **302** to Backend `https://xorismesiti.gr/api/auth/callback` with authorization code
1. Frontend **Navigate** to Google URL with a callback url
2. Google **Redirect** to Backend's callback url with the authorization code
2. Exchange Code with Token
1. Backend **POST** the `code` to Google `https://oauth2.googleapis.com/token`
2. Google **response** to Backend with an `access_token` and a `refresh token`
3. Backend **response** to Frontend with the `access_token` in a `cookie`
3. Backend **redirect** to Frontend `https://myapp/auth/success` with the `access_token` in a `cookie`
3. Use Token
1. Frontend **GET** profile data from Backend `https://xorismesiti.gr/api/auth/profile` using the `cookie`
1. Frontend **GET** profile data from Backend `https://myapp/api/auth/profile` using the `cookie`
2. Backend **GET** profile data from Google `https://www.googleapis.com/oauth2/v3/userinfo` using the `access_token` from Frontend `cookie`
3. Google **response** to Backend with profile data
4. Backend **response** to Frontend with profile data
@ -42,24 +42,24 @@ A way for the `user` to tell `google` to give an access to `xorismesiti.gr` app
# 1. Get Code
1. Frontend **GET** to Google `https://accounts.google.com/o/oauth2` with callback url
2. Google **302** to Backend `https://xorismesiti.gr/api/auth/callback` with authorization code
2. Google **302** to Backend `https://myapp/api/auth/callback` with authorization code
### 1. Front **GET** to Google
```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/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.
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://myapp/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.
```
### 2. Google **302** to Back
```bash
HTTP/1.1 302 Found
Location: https://xorismesiti.gr/api/auth/callback?code=4/0AX4XfWgyVyz-uT8k7WiyLg0Q&state=xyz123
Location: https://myapp/api/auth/callback?code=4/0AX4XfWgyVyz-uT8k7WiyLg0Q&state=xyz123
Content-Type: text/html; charset=UTF-8
Content-Length: 0
```
@ -86,7 +86,7 @@ grant_type=authorization_code&
code=AAAABCX4XfWgyVyziyLg0QHHHHH&
client_id=ABC34JHS9D&
client_secret=PASS1234&
redirect_uri=https://xorismesiti.gr/callback
redirect_uri=https://myapp/callback
```
### 2. Google **response** to Backend
@ -129,33 +129,43 @@ redirect_uri=https://xorismesiti.gr/callback
<br><br>
```js
// 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
app.get('/callback', async (req, res) => {
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, // Same as in Step 1
grant_type: 'authorization_code',
// 1. Get the authorization code from Google's redirect
const { code } = req.query;
// 2. Exchange the code for tokens
const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code,
client_id: process.env.GOOGLE_CLIENT_ID,
client_secret: process.env.GOOGLE_CLIENT_SECRET,
redirect_uri: 'https://myapp/callback',
grant_type: 'authorization_code',
}),
});
const { access_token, refresh_token, expires_in } = response.data;
// 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 });
// Respond to frontend or redirect as needed
res.send('Authentication successful! You can now use the app.');
const { access_token, refresh_token } = await tokenResponse.json();
// 3. Set the HTTP-only cookie with the access token
res.cookie('access', access_token, {
httpOnly: true, // Cannot be accessed by client-side JavaScript
secure: true, // Only sent over HTTPS
sameSite: 'strict', // CSRF protection
maxAge: 24 * 60 * 60 * 1000, // 24 hours
});
// 4. Store refresh token securely in database (recommended)
// await db.storeRefreshToken(user_id, refresh_token);
// 5. Redirect back to frontend
res.redirect('https://myapp/authentication-success');
} catch (error) {
console.error('Error exchanging code for tokens:', error);
res.status(500).send('Error during authentication');
res.redirect('https://myapp/authentication-error');
}
});
```
@ -173,7 +183,7 @@ app.get('/auth/google/callback', async (req, res) => {
### 1. Frontend **GET** profile data from Backend
```bash
curl -X GET https://xorismesiti.gr/api/auth/profile \
curl -X GET https://myapp/api/auth/profile \
-H "Cookie: access_token=ya29.a0AfH6SMC8Op6zXZkHi2XITkDoOVzYXt3hTY6sny54UlWlxrnKlX5Xv78is7BEHekVX-VoA" \
-H "Accept: application/json"
```
@ -282,7 +292,7 @@ export default App;
-------------------------
```bash
GET https://xorismesiti.gr/api/user-profile
GET https://myapp/api/user-profile
Authorization: Bearer access-token-from-backend
```