Skip to content

[Mailer] Support OAuth2 for gmail properly #35528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ThomasTr opened this issue Jan 30, 2020 · 35 comments
Closed

[Mailer] Support OAuth2 for gmail properly #35528

ThomasTr opened this issue Jan 30, 2020 · 35 comments
Labels
Feature Help wanted Issues and PRs which are looking for volunteers to complete them. Mailer

Comments

@ThomasTr
Copy link
Contributor

As of February 15, 2021, sending emails with Google G Suite accounts will only be possible with apps that use OAuth.

OAuth2 Authentication is already implemented via the XOAuth2Authenticator. But it uses the password as acces_token. Since its validity is limited to one hour, this is not a practicable way.

At the moment i have written my own custom transport (gmail+oauth), since i have already included google/apiclient and oauth handling/storing in my app.

I think it makes sense to implement oauth token - handling / - renewing / - storage in symfony/google-mailer, otherwise it will make it obsolete after February 15, 2021.

What do you think. Maybe i could help out with this.

@stof
Copy link
Member

stof commented Feb 11, 2020

If this can be implemented easily without external dependency, I think this is a good idea.

If the only practical way to implement this feature is to depend on google/apiclient, I think this should rather be implemented as a community package, as we tend to limit external dependencies in Symfony core packages (our BC and LTS policies are the primary reason for that, as we would then depend on having compatible maintenance policies on these external packages to be able to fulfill our promises)

@frostmaind
Copy link

+1

@fabpot
Copy link
Member

fabpot commented Jun 23, 2020

I agree with @stof. Anyone wanted to have a look?

@millnut
Copy link

millnut commented Oct 2, 2020

Some handy notes that may help based on my experience using Gmail and OAUTH, and to possibly open up discussion on which Gmail transport to support (SMTP or Gmail API or both).

Scopes using google/apiclient

  • For SMTP connections using XOAUTH2 you will need the full Google_Service_Gmail::MAIL_GOOGLE_COM scope to send emails or the connection will fail to authenticate
  • To send emails via the direct Gmail API with OAuth 2.0 you will only need the scope Google_Service_Gmail::GMAIL_SEND

Note: It's not a requirement but Google prefers you to use minimal scope access for the action you need. This is more an integration thing and outside the scope of this.

Cleanup google/apiclient
As mentioned in the docs for google/apiclient it comes with all Google's API but you can limit it to just Gmail by using this in composer.

    "scripts": {
      "post-update-cmd": "Google_Task_Composer::cleanup"
    },
    "extra": {
      "google/apiclient-services": [
        "Gmail"
      ]
    }

Personally I think it should be sending using OAuth 2.0 via SMTP or Gmail API functionality only and the OAuth token generation/refresh/storage should be for the user to implement.

@logosur
Copy link

logosur commented Mar 27, 2021

What finally happened to this? I can't find a way to send emails to gmail with oauth.

@carsonbot
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

@carsonbot
Copy link

Friendly ping? Should this still be open? I will close if I don't hear anything.

@fideloper
Copy link

fideloper commented Oct 12, 2021

This can work with SMTP as well, it doesn't necessarily need the Google (or Microsoft, which will also require XOAUTH2 eventually) client library.

Swiftmailer does it here: https://github.com/swiftmailer/swiftmailer/blob/5.x/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php

In terms of using an SMTP transport, it's essentially just a different way to build up the authentication command:

$email = 'foo@example.com';
$token = 'asdfxxx........';

$authString = base64_encode("user=$email\1auth=Bearer $token\1\1");

$connection->executeCommand("AUTH XOAUTH2 $authString");

@carsonbot carsonbot removed the Stalled label Oct 12, 2021
@stof
Copy link
Member

stof commented Oct 12, 2021

To me, it might make sense to support XOAUTH2 authentication in the SMTP transport, and leaving the generation/refreshing of the token to the caller (as that's the part that may need to use an SDK)

@stof stof added the Help wanted Issues and PRs which are looking for volunteers to complete them. label Oct 12, 2021
@logosur
Copy link

logosur commented Oct 12, 2021

Gmail justy only supports oauth It would be great to have native oauth libraries.

@carsonbot
Copy link

Thank you for this suggestion.
There has not been a lot of activity here for a while. Would you still like to see this feature?

@carsonbot
Copy link

Could I get an answer? If I do not hear anything I will assume this issue is resolved or abandoned. Please get back to me <3

@stof
Copy link
Member

stof commented Apr 27, 2022

This has been re-requested as a duplicate a few days ago at #46033

@carsonbot carsonbot removed the Stalled label Apr 27, 2022
@mchojrin
Copy link

I'd like to see this implemented

@derrabus
Copy link
Member

To see this implemented, someone has to implement it.

@mchojrin
Copy link

@derrabus: clearly. I was replying to #35528 (comment).

Anyway, I'll give it a try. I never got in this code so I'm not sure I'll be able to pull it off but still, I'll try my best.

@wehostadm
Copy link

I hope someone will implement this, the support for "less secure application" for connecting to Gmail dropped yesterday :(

Thanks !

@stof
Copy link
Member

stof commented Jun 1, 2022

Well, "hoping" does not help finding someone to do the work...

@lukepass
Copy link

lukepass commented Jun 1, 2022

For the short term a working solution is to use the App Passwords. This requires you to enable the Two-Factor Authentication but then it should work with the same configuration as before, just with the App password instead of the account password. You can find more info here:

https://wpmailsmtp.com/gmail-less-secure-apps/
https://support.google.com/accounts/answer/185833?hl=en

@davidromani
Copy link
Contributor

davidromani commented Jun 29, 2022

Hi everybody! I would like to add some "thoughts" to this discussion because can help us.

Looking information about XOAUTH2 Gmail protocol I ended in this page https://github.com/PHPMailer/PHPMailer/wiki/Using-Gmail-with-XOAUTH2.

After looking all the steps of how PHPMailer resolve this authentication, maybe it's possible to use a similar workarround with symfony/mailer.

If Symfony mailer transport it's mandatory to be not coupled to google/apiclient then we only need a mechanism (external script) to fetch the Google token.

With this token fetched maybe can be accepted to add a XOAuth2Authenticator class in Symfony\Component\Mailer\Bridge\Google\Transport to properly send via Gmail.

@fabpot
Copy link
Member

fabpot commented Jun 29, 2022

@davidromani For reference, we already have such an authenticator for SMTP here: src/Symfony/Component/Mailer/Transport/Smtp/Auth/XOAuth2Authenticator.php

@davidromani
Copy link
Contributor

@fabpot thanks for your hint!

Is there any example or documentation related on how to use this authentication method with symfony/mailer or symfony/google-mailer?

@ThomasTr
Copy link
Contributor Author

I have written for me a custom GmailOAuthTransportFactory which extends AbstractTransportFactory and an GmailOAuthSmtpTransport which extends SmtpTransport but i already use the google apiclient in my app and therefore already have the token.

Then you can use this GmailOAuthTransportFactory via config in your services.yaml:

    App\Service\Gmail\Transport\GmailOAuthTransportFactory:
        tags: ['mailer.transport_factory']

The authentication is pretty much the same as @fabpot mentioned in the XOAuth2Authenticator class:

$data = sprintf("user=%s\1auth=Bearer %s\1\1", $this->getUsername(), $token['access_token']);
$this->executeCommand(sprintf("AUTH XOAUTH2 %s\r\n", base64_encode($data)), [235]);

@fabpot: Any idea, what helps the project to provide a solution for google mail without adding dependencies?

@hwarmelink
Copy link

Just wanted to voice my support for this work. Wish I could help with the coding, but I'm out of my depth for that. I wrote some Google authentication and Gmail API custom code in a Mediawiki extension a year ago roughly, but I'm still too new to Symfony to be able to carry that over somehow.

@bobonov
Copy link

bobonov commented Aug 31, 2022

oauth2 authentication for gmail is a must since google disable the less secure app feature since 30/05/2022 therefore it is not possible anymore to send email via "classic" user/password
https://support.google.com/accounts/answer/6010255?hl=en
https://support.google.com/mail/thread/166681329/use-smtp-gmail-com-as-email-client-for-outgoing-emails-getting-username-and-password-not-accepted?hl=en

Actually gmail transport is unusable

@stof
Copy link
Member

stof commented Aug 31, 2022

@bobonov adding more comments saying this is wanted does not help. What we need is someone working on an implementation.

@ThomasTr
Copy link
Contributor Author

@stof @fabpot some ideas how to tackle this without adding dependencies would be helpful

@bobonov
Copy link

bobonov commented Aug 31, 2022

@stof I didn't just write I want it (actually, I'm doing a new implementation and I just dropped the hypothesis of using gmail smtp). I simply wrote that since 30/05/2022 this driver without oauth2 is dead code.

@ThomasTr "...provide a solution for google mail without adding dependencies?"
In my experience, it is not possible to write such authentication without adding an oauth2 client, it can be useful also in other transport eg office365

I would love to help but my experience with aouth2 client is just to use client that other have wrote.

In a project a while ago, I was sending email via gmail using oauth2.
I was using PHPMailer to compose the email, but I was sending the email using google api.
It is important that when doing the authentication you must specify in the scope
https://www.googleapis.com/auth/gmail.send
otherwise you can't send

        try {
            $mail = new PHPMailer();
            // setting email from, to etc etc
            $mail->preSend();
            $mime = $mail->getSentMIMEMessage();
            /** @var $access_token string holds the access token */
            $client = new \Google_Client();
            $client->setAccessToken($access_token);
            $objGMail = new \Google_Service_Gmail($client);
            // The message needs to be encoded in Base64URL
            $mime = rtrim(strtr(base64_encode($mime), '+/', '-_'), '=');
            $msg = new \Google_Service_Gmail_Message();
            $msg->setRaw($mime);
            $objGMail->users_messages->send("me", $msg);
        } catch (Exception $e) {
            print_r($e->getMessage());
        }

Maybe a similar approach can be used.

@fabpot
Copy link
Member

fabpot commented Oct 22, 2022

I'm going to close here as there is a solution that is simple enough: using app passwords (as mentioned in one comment above: #35528 (comment)). It needs 2FA to be enabled on your account though (but I suppose everybody should do it anyway).

I've just tested it and it works fine.

@boonkerz
Copy link

Currently App Password disabled on 30.09.2024 so gmail will no longer work.

https://workspaceupdates.googleblog.com/2023/09/winding-down-google-sync-and-less-secure-apps-support.html

@stof
Copy link
Member

stof commented Sep 24, 2024

@boonkerz the article you link does not talk about disabling app passwords. It actually even mentions them as one of the alternatives.

@EvilKarter
Copy link

@stof i think this is the correct article form google https://support.google.com/a/answer/14114704?hl=en&fl=1&sjid=14336799637165458190-NA

@stof
Copy link
Member

stof commented Oct 1, 2024

@EvilKarter here is a quote from the introduction of that post:

you will no longer use a password for access (with the exception of app passwords).

App passwords are not removed by Google.

@wayneljw
Copy link

wayneljw commented May 1, 2025

Unfortunately, Google has turned off App Passwords today:
https://workspaceupdates.googleblog.com/2023/09/winding-down-google-sync-and-less-secure-apps-support.html

@ThomasTr
Copy link
Contributor Author

ThomasTr commented May 1, 2025

Nope, app passwords still working. Using it at the moment via imapsync to migrate my google workspace accounts to selfhosted mailserver.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Help wanted Issues and PRs which are looking for volunteers to complete them. Mailer
Projects
None yet
Development

No branches or pull requests