thephpleague / oauth2-client

Easy integration with OAuth 2.0 service providers.
http://oauth2-client.thephpleague.com
MIT License
3.64k stars 751 forks source link

Is there other way than header to send request to Google authorization Url to get the code? #943

Closed onlyu-bot closed 2 years ago

onlyu-bot commented 2 years ago

I've successfully set up get_token.php to get Google OAuth2 for my website(example.com) for PHPMailer, and I can get access token via browser(by select my google account to log in to access).

Because I have exceed the limit of refresh token via development, even I've tried to use another google account to create api for my website(example.com), revoke from google account, or delete OAuth and create another one to generate a new clientId; but none of them work, and I think that I will never get a refresh token again.

My website is still running and keeping sending emails, so every hour I have to manually access the access token by link to https://example.com/get_token.php through the browser, so the PHPMailer can use the access token to work.

The document sample use header to redirect to the authorization Url, so I have to use browser to execute the code.

But I already click to permit to allow access the google api, so I don't need to redirect to the page again. Is there another way to do it? So that I can execute the code via command line, ex:curl https://example.com/get_token.php and make the cronJob do it every hour? Thank you!

Here is my get_token.php

<?
require 'vendor/autoload.php';

session_start();

$token_file="my-token.json";

$provider = new \League\OAuth2\Client\Provider\Google([
    'clientId'                => 'xxx.apps.googleusercontent.com',
    'clientSecret'            => 'password',
    'redirectUri'             => 'https://example.com/get_token.php',
    'scopes' => ['https://mail.google.com/'],
    'access_type' => 'offline'
]);

if (!isset($_GET['code'])) {

    $authorizationUrl = $provider->getAuthorizationUrl();

    $_SESSION['oauth2state'] = $provider->getState();

    ////Is there another way other than header and still get the 'code'?
    header('Location: ' . $authorizationUrl);
    exit;

} elseif (empty($_GET['state']) || (isset($_SESSION['oauth2state']) && $_GET['state'] !== $_SESSION['oauth2state'])) {

    if (isset($_SESSION['oauth2state'])) {
        unset($_SESSION['oauth2state']);
    }

    exit('Invalid state');

} else {

    try {

        $accessToken = $provider->getAccessToken('authorization_code', [
            'code' => $_GET['code']
        ]);

        $token=json_decode(file_get_contents($token_file));
        $token->access_token=$accessToken->getToken();

        if(!empty($accessToken->getRefreshToken())){
            $token->refresh_token=$accessToken->getRefreshToken();
        }

        file_put_contents($token_file, json_encode($token));

    } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {

        exit($e->getMessage());

    }

}

Here is my Mail.php

$token_file="my-token.json";
$mail = new PHPMailer();

try {

    $mail->IsSMTP();
    $mail->SMTPAuth = true;
    $mail->SMTPSecure = "tls";
    $mail->Host = "smtp.gmail.com";
    $mail->Port = 587;
    $mail->AddAddress($_GET['to']);

    $oauth_token=file_get_contents($token_file);
    $access_token= json_decode($oauth_token)->access_token;

    $mail->AuthType ="XOAUTH2";
    $mail->oauthUserEmail = 'auto-mail@example.com';
    $mail->oauthClientId = "xxx.apps.googleusercontent.com";
    $mail->oauthClientSecret = "password";
    $mail->oauthRefreshToken = $access_token;

    $mail->CharSet = 'utf-8';
    $mail->SMTPDebug = 2;
    $mail->Encoding   = "base64";

    return $mail->Send();

} catch (Exception $e) {
    return false;
}
onlyu-bot commented 2 years ago

Finally, I get the refresh_token, by revoking from google account(aka remove the apps access through account).

Everything goes normal again, and I don't need to solve the problem as the title 'Is there other way than header to send request to Google authorization Url to get the code?'.

For more detail please go to stackoverflow

But why I success this time? Because this time I use curl but not thephpleague/oauth2-client way to request auth. I think there must missing some parms when I request auth via thephpleague/oauth2-client.I'll open another issue to discuss this.