Update OAuth2.md
This commit is contained in:
parent
d930c66c53
commit
c5b29972c1
152
OAuth2.md
152
OAuth2.md
@ -15,7 +15,9 @@ A way for the `user` to tell `google` to give an access token to `xorismesiti.gr
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 1. [Frontend] Authorization Request: Redirect the user to Google's OAuth Authorization Endpoint
|
# 1. [Frontend] Request Authorization code
|
||||||
|
|
||||||
|
### Redirect the user to Google's OAuth Authorization Endpoint
|
||||||
|
|
||||||
1. Action: The frontend provides a "Login with Google" button.
|
1. Action: The frontend provides a "Login with Google" button.
|
||||||
2. When the user clicks it, the frontend constructs a URL to Google's OAuth 2.0 authorization endpoint and redirects the user there.
|
2. When the user clicks it, the frontend constructs a URL to Google's OAuth 2.0 authorization endpoint and redirects the user there.
|
||||||
@ -40,22 +42,135 @@ GET https://accounts.google.com/o/oauth2/v2/auth?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 2. Frontend (Next.js): Receive the Authorization Code and Send it to the Backend
|
# 2. [Frontend] Receive Authorization Code
|
||||||
|
|
||||||
|
### And send it to the Backend
|
||||||
|
|
||||||
1. Once the user grants permission,
|
1. Once the user grants permission,
|
||||||
2. Google will redirect the user to the `redirect_uri` you specified in the previous step (e.g., https://xorismesiti.gr/api/auth/callback)
|
2. Google will redirect the user to the `redirect_uri` you specified in the previous step (`https://xorismesiti.gr/api/auth/callback`)
|
||||||
|
|
||||||
The frontend must not directly exchange the `code` for an `access_token`.
|
The frontend must not directly exchange the `code` for an `access_token`. Instead, it sends the `code` to the backend via an API request.
|
||||||
|
|
||||||
Instead, it sends the `code` to the backend via an API request.
|
<details>
|
||||||
|
<summary>Code:</summary>
|
||||||
|
|
||||||
|
```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 <div>Loading...</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Callback;
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
# 3. Backend (Node.js): Handle Token Exchange
|
# 3. Backend (Node.js): Handle Token Exchange
|
||||||
|
|
||||||
1. The backend makes a `POST` request to Google token endpoint, to exchange the authorization `code` for the `access_token` and optionally a `refresh token`
|
1. The backend receives the authorization `code` from the frontend,
|
||||||
2. Ensure you never expose the client_secret to the frontend. This step should always be handled on the backend.
|
2. The backend makes a `POST` request to Google token endpoint, to exchange the authorization `code` for the `access_token` and optionally a `refresh token`
|
||||||
3. The backend will exchange the `code` for an `access_token` and `refresh_token`, which are sent back to the frontend or stored securely for subsequent API calls.
|
3. The backend ensures to never expose the client_secret to the frontend. This step should always be handled on the backend.
|
||||||
|
4. The backend will exchange the `code` for an `access_token` and `refresh_token`, which are sent back to the frontend or stored securely for subsequent API calls.
|
||||||
|
|
||||||
|
- `HTTP` Method: POST
|
||||||
|
- `URL`: https://oauth2.googleapis.com/token
|
||||||
|
- `Headers`:
|
||||||
|
- `Content`-Type: application/x-www-form-urlencoded
|
||||||
|
- `Body` Parameters:
|
||||||
|
- `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).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
POST https://oauth2.googleapis.com/token
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
grant_type=authorization_code&
|
||||||
|
code=4/0AX4XfWgNmGZVbV7Kdr8Q9yVyzIYBnbbBdLfX39ZaE8m0w8zT8jKRLl7w-uT8k7WiyLg0Q&
|
||||||
|
redirect_uri=https://xorismesiti.gr/callback&
|
||||||
|
client_id=YOUR_GOOGLE_CLIENT_ID&
|
||||||
|
client_secret=YOUR_GOOGLE_CLIENT_SECRET
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Code:</summary>
|
||||||
|
|
||||||
|
```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;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post('https://oauth2.googleapis.com/token', null, {
|
||||||
|
params: {
|
||||||
|
code,
|
||||||
|
client_id: clientId,
|
||||||
|
client_secret: clientSecret,
|
||||||
|
redirect_uri: redirectUri,
|
||||||
|
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' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start the server
|
||||||
|
app.listen(3000, () => {
|
||||||
|
console.log('Server running on http://localhost:3000');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
GET https://xorismesiti.gr/callback?
|
GET https://xorismesiti.gr/callback?
|
||||||
@ -74,30 +189,9 @@ GET https://xorismesiti.gr/callback?
|
|||||||
|
|
||||||
Now your platform can use exchange the authorization code for an access token and refresh token.
|
Now your platform can use exchange the authorization code for an access token and refresh token.
|
||||||
|
|
||||||
1. it sends a POST request to Google's token endpoint
|
|
||||||
|
|
||||||
- `HTTP` Method: POST
|
|
||||||
- `URL`: https://oauth2.googleapis.com/token
|
|
||||||
- `Headers`:
|
|
||||||
- `Content`-Type: application/x-www-form-urlencoded
|
|
||||||
- `Body` Parameters:
|
|
||||||
- `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).
|
|
||||||
|
|
||||||
|
|
||||||
```sh
|
|
||||||
POST https://oauth2.googleapis.com/token
|
|
||||||
Content-Type: application/x-www-form-urlencoded
|
|
||||||
|
|
||||||
grant_type=authorization_code&
|
|
||||||
code=4/0AX4XfWgNmGZVbV7Kdr8Q9yVyzIYBnbbBdLfX39ZaE8m0w8zT8jKRLl7w-uT8k7WiyLg0Q&
|
|
||||||
redirect_uri=https://xorismesiti.gr/callback&
|
|
||||||
client_id=YOUR_GOOGLE_CLIENT_ID&
|
|
||||||
client_secret=YOUR_GOOGLE_CLIENT_SECRET
|
|
||||||
```
|
|
||||||
|
|
||||||
# 5. Access Token Response (Google Returns Tokens)
|
# 5. Access Token Response (Google Returns Tokens)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user