|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* Get an OAuth2 token from Google. |
|
4
|
|
|
* * Install this script on your server so that it's accessible |
|
5
|
|
|
* as [https/http]://<yourdomain>/<folder>/get_oauth_token.php |
|
6
|
|
|
* e.g.: http://localhost/phpmail/get_oauth_token.php |
|
7
|
|
|
* * Ensure dependencies are installed with 'composer install' |
|
8
|
|
|
* * Set up an app in your Google developer console |
|
9
|
|
|
* * Set the script address as the app's redirect URL |
|
10
|
|
|
* If no refresh token is obtained when running this file, revoke access to your app |
|
11
|
|
|
* using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again. |
|
12
|
|
|
* This script requires PHP 5.4 or later |
|
13
|
|
|
* PHP Version 5.4 |
|
14
|
|
|
*/ |
|
15
|
|
|
|
|
16
|
|
|
namespace League\OAuth2\Client\Provider; |
|
17
|
|
|
|
|
18
|
|
|
require 'vendor/autoload.php'; |
|
19
|
|
|
|
|
20
|
|
|
use League\OAuth2\Client\Provider\Exception\IdentityProviderException; |
|
21
|
|
|
use League\OAuth2\Client\Token\AccessToken; |
|
22
|
|
|
use League\OAuth2\Client\Tool\BearerAuthorizationTrait; |
|
23
|
|
|
use Psr\Http\Message\ResponseInterface; |
|
24
|
|
|
|
|
25
|
|
|
session_start(); |
|
26
|
|
|
|
|
27
|
|
|
//If this automatic URL doesn't work, set it yourself manually |
|
28
|
|
|
$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; |
|
29
|
|
|
//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php'; |
|
30
|
|
|
|
|
31
|
|
|
//These details obtained are by setting up app in Google developer console. |
|
32
|
|
|
$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com'; |
|
33
|
|
|
$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP'; |
|
34
|
|
|
|
|
35
|
|
|
class Google extends AbstractProvider |
|
36
|
|
|
{ |
|
37
|
|
|
use BearerAuthorizationTrait; |
|
38
|
|
|
|
|
39
|
|
|
const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id'; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var string If set, this will be sent to google as the "access_type" parameter. |
|
43
|
|
|
* @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline |
|
44
|
|
|
*/ |
|
45
|
|
|
protected $accessType; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @var string If set, this will be sent to google as the "hd" parameter. |
|
49
|
|
|
* @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param |
|
50
|
|
|
*/ |
|
51
|
|
|
protected $hostedDomain; |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* @var string If set, this will be sent to google as the "scope" parameter. |
|
55
|
|
|
* @link https://developers.google.com/gmail/api/auth/scopes |
|
56
|
|
|
*/ |
|
57
|
|
|
protected $scope; |
|
58
|
|
|
|
|
59
|
|
|
public function getBaseAuthorizationUrl() |
|
60
|
|
|
{ |
|
61
|
|
|
return 'https://accounts.google.com/o/oauth2/auth'; |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
public function getBaseAccessTokenUrl(array $params) |
|
65
|
|
|
{ |
|
66
|
|
|
return 'https://accounts.google.com/o/oauth2/token'; |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
public function getResourceOwnerDetailsUrl(AccessToken $token) |
|
70
|
|
|
{ |
|
71
|
|
|
return ' '; |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
protected function getAuthorizationParameters(array $options) |
|
75
|
|
|
{ |
|
76
|
|
|
if (is_array($this->scope)) { |
|
77
|
|
|
$separator = $this->getScopeSeparator(); |
|
78
|
|
|
$this->scope = implode($separator, $this->scope); |
|
79
|
|
|
} |
|
80
|
|
|
|
|
81
|
|
|
$params = array_merge( |
|
82
|
|
|
parent::getAuthorizationParameters($options), |
|
83
|
|
|
array_filter([ |
|
84
|
|
|
'hd' => $this->hostedDomain, |
|
85
|
|
|
'access_type' => $this->accessType, |
|
86
|
|
|
'scope' => $this->scope, |
|
87
|
|
|
// if the user is logged in with more than one account ask which one to use for the login! |
|
88
|
|
|
'authuser' => '-1' |
|
89
|
|
|
]) |
|
90
|
|
|
); |
|
91
|
|
|
return $params; |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
protected function getDefaultScopes() |
|
95
|
|
|
{ |
|
96
|
|
|
return [ |
|
97
|
|
|
'email', |
|
98
|
|
|
'openid', |
|
99
|
|
|
'profile', |
|
100
|
|
|
]; |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
protected function getScopeSeparator() |
|
104
|
|
|
{ |
|
105
|
|
|
return ' '; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
protected function checkResponse(ResponseInterface $response, $data) |
|
109
|
|
|
{ |
|
110
|
|
|
if (!empty($data['error'])) { |
|
111
|
|
|
$code = 0; |
|
112
|
|
|
$error = $data['error']; |
|
113
|
|
|
|
|
114
|
|
|
if (is_array($error)) { |
|
115
|
|
|
$code = $error['code']; |
|
116
|
|
|
$error = $error['message']; |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
throw new IdentityProviderException($error, $code, $data); |
|
120
|
|
|
} |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
protected function createResourceOwner(array $response, AccessToken $token) |
|
124
|
|
|
{ |
|
125
|
|
|
return new GoogleUser($response); |
|
126
|
|
|
} |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
|
|
130
|
|
|
//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php |
|
131
|
|
|
$provider = new Google( |
|
132
|
|
|
array( |
|
133
|
|
|
'clientId' => $clientId, |
|
134
|
|
|
'clientSecret' => $clientSecret, |
|
135
|
|
|
'redirectUri' => $redirectUri, |
|
136
|
|
|
'scope' => array('https://mail.google.com/'), |
|
137
|
|
|
'accessType' => 'offline' |
|
138
|
|
|
) |
|
139
|
|
|
); |
|
140
|
|
|
|
|
141
|
|
|
if (!isset($_GET['code'])) { |
|
142
|
|
|
// If we don't have an authorization code then get one |
|
143
|
|
|
$authUrl = $provider->getAuthorizationUrl(); |
|
144
|
|
|
$_SESSION['oauth2state'] = $provider->getState(); |
|
145
|
|
|
header('Location: ' . $authUrl); |
|
146
|
|
|
exit; |
|
147
|
|
|
// Check given state against previously stored one to mitigate CSRF attack |
|
148
|
|
|
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) { |
|
149
|
|
|
unset($_SESSION['oauth2state']); |
|
150
|
|
|
exit('Invalid state'); |
|
151
|
|
|
} else { |
|
152
|
|
|
// Try to get an access token (using the authorization code grant) |
|
153
|
|
|
$token = $provider->getAccessToken( |
|
154
|
|
|
'authorization_code', |
|
155
|
|
|
array( |
|
156
|
|
|
'code' => $_GET['code'] |
|
157
|
|
|
) |
|
158
|
|
|
); |
|
159
|
|
|
|
|
160
|
|
|
// Use this to get a new access token if the old one expires |
|
161
|
|
|
echo 'Refresh Token: ' . $token->getRefreshToken(); |
|
162
|
|
|
} |
|
163
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.