Skip to content

Commit 09d0f8d

Browse files
authored
Modernize Google OAuth flow (#8)
* Modernize Google OAuth flow * Require secure Google OAuth dependencies
1 parent c0f15aa commit 09d0f8d

5 files changed

Lines changed: 90 additions & 21 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Compatibility
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
composer:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
php: ['8.1', '8.5']
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: shivammathur/setup-php@v2
18+
with:
19+
php-version: ${{ matrix.php }}
20+
coverage: none
21+
- run: composer update --prefer-dist --no-interaction
22+
- run: find src -name '*.php' -print0 | xargs -0 -n1 php -l

README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,28 @@ the packages that make use of this handler.
2121

2222
## Setup
2323

24-
*TODO*
24+
Create OAuth client credentials in Google Cloud and register a redirect URI. Then run:
25+
26+
```bash
27+
php vendor/rapidwebltd/php-google-oauth-2-handler/src/setup.php
28+
```
29+
30+
The retired out-of-band OAuth flow is not used. After authorizing, copy the
31+
`code` query parameter from the registered redirect URL back into the setup
32+
command.
2533

2634
## Usage
2735

28-
*TODO*
36+
```php
37+
use RapidWeb\GoogleOAuth2Handler\GoogleOAuth2Handler;
38+
39+
$handler = new GoogleOAuth2Handler(
40+
$clientId,
41+
$clientSecret,
42+
$scopes,
43+
$refreshToken,
44+
$redirectUri
45+
);
46+
47+
$response = $handler->performRequest('GET', 'https://people.googleapis.com/v1/people/me');
48+
```

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
}
1111
],
1212
"require": {
13-
"google/apiclient": "^2.2",
14-
"guzzlehttp/guzzle": "^6.3"
13+
"php": "^8.1",
14+
"google/apiclient": "^2.19",
15+
"guzzlehttp/guzzle": "^7.4.5"
1516
},
1617
"autoload": {
1718
"psr-4": {

src/GoogleOAuth2Handler.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,31 @@
22

33
namespace RapidWeb\GoogleOAuth2Handler;
44

5-
use GuzzleHttp\Psr7\Request;
5+
use InvalidArgumentException;
6+
use RuntimeException;
67

78
class GoogleOAuth2Handler
89
{
910
private $clientId;
1011
private $clientSecret;
1112
private $scopes;
1213
private $refreshToken;
14+
private $redirectUri;
1315
private $client;
1416

1517
public $authUrl;
1618

17-
public function __construct($clientId, $clientSecret, $scopes, $refreshToken = '')
19+
public function __construct($clientId, $clientSecret, $scopes, $refreshToken = '', $redirectUri = null)
1820
{
1921
$this->clientId = $clientId;
2022
$this->clientSecret = $clientSecret;
2123
$this->scopes = $scopes;
2224
$this->refreshToken = $refreshToken;
25+
$this->redirectUri = $redirectUri;
26+
27+
if (!$this->refreshToken && !$this->redirectUri) {
28+
throw new InvalidArgumentException('A redirect URI is required when requesting a new Google authorization code.');
29+
}
2330

2431
$this->setupClient();
2532
}
@@ -30,11 +37,17 @@ private function setupClient()
3037

3138
$this->client->setClientId($this->clientId);
3239
$this->client->setClientSecret($this->clientSecret);
33-
$this->client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
40+
if ($this->redirectUri) {
41+
$this->client->setRedirectUri($this->redirectUri);
42+
}
3443
$this->client->setAccessType('offline');
35-
$this->client->setApprovalPrompt('force');
44+
if (method_exists($this->client, 'setPrompt')) {
45+
$this->client->setPrompt('consent');
46+
} else {
47+
$this->client->setApprovalPrompt('force');
48+
}
3649

37-
foreach($this->scopes as $scope) {
50+
foreach ($this->scopes as $scope) {
3851
$this->client->addScope($scope);
3952
}
4053

@@ -47,17 +60,27 @@ private function setupClient()
4760

4861
public function getRefreshToken($authCode)
4962
{
50-
$this->client->authenticate($authCode);
51-
$accessToken = $this->client->getAccessToken();
63+
$accessToken = $this->client->fetchAccessTokenWithAuthCode($authCode);
64+
65+
if (isset($accessToken['error'])) {
66+
throw new RuntimeException('Google rejected the authorization code: '.($accessToken['error_description'] ?? $accessToken['error']));
67+
}
68+
69+
if (empty($accessToken['refresh_token'])) {
70+
throw new RuntimeException('Google did not return a refresh token. Revoke the existing grant and authorize again with consent.');
71+
}
72+
5273
return $accessToken['refresh_token'];
5374
}
5475

55-
public function performRequest($method, $url, $body = null)
76+
public function performRequest($method, $url, $body = null, array $options = [])
5677
{
5778
$httpClient = $this->client->authorize();
58-
$request = new Request($method, $url, [], $body);
59-
$response = $httpClient->send($request);
60-
return $response;
61-
}
6279

63-
}
80+
if ($body !== null && !array_key_exists('body', $options)) {
81+
$options['body'] = $body;
82+
}
83+
84+
return $httpClient->request($method, $url, $options);
85+
}
86+
}

src/setup.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
$clientId = trim(readline('Google Client ID: '));
2727
$clientSecret = trim(readline('Google Client Secret: '));
28+
$redirectUri = trim(readline('Authorized redirect URI: '));
2829
echo PHP_EOL;
2930

3031
echo 'You need to select the scopes you need access to. Go to the';
@@ -48,19 +49,19 @@
4849
}
4950
}
5051

51-
$googleOAuth2Handler = new GoogleOAuth2Handler($clientId, $clientSecret, $scopes);
52+
$googleOAuth2Handler = new GoogleOAuth2Handler($clientId, $clientSecret, $scopes, '', $redirectUri);
5253

5354
echo PHP_EOL;
5455
echo 'Now, go to the following URL, sign in to your Google Account,';
5556
echo PHP_EOL;
56-
echo 'and copy-paste the auth code you receive below.';
57+
echo 'and copy the `code` query parameter from the redirect URL below.';
5758
echo PHP_EOL.PHP_EOL;
5859

5960
echo $googleOAuth2Handler->authUrl;
6061
echo PHP_EOL.PHP_EOL;
6162

6263
$authCode = trim(readline('Auth Code: '));
63-
echo PHP_EOL;PHP_EOL;
64+
echo PHP_EOL.PHP_EOL;
6465

6566
$refreshToken = $googleOAuth2Handler->getRefreshToken($authCode);
6667

@@ -83,7 +84,9 @@
8384
echo PHP_EOL;
8485
echo '$refreshToken = \''.$refreshToken.'\';';
8586
echo PHP_EOL;
87+
echo '$redirectUri = \''.$redirectUri.'\';';
88+
echo PHP_EOL;
8689
echo '$scopes = [\''.implode('\', \'', $scopes).'\'];';
8790
echo PHP_EOL.PHP_EOL;
88-
echo '$googleOAuth2Handler = new GoogleOAuth2Handler($clientId, $clientSecret, $scopes, $refreshToken);';
91+
echo '$googleOAuth2Handler = new GoogleOAuth2Handler($clientId, $clientSecret, $scopes, $refreshToken, $redirectUri);';
8992
echo PHP_EOL.PHP_EOL;

0 commit comments

Comments
 (0)