-
Hi, I am trying to understand if this is possible with phpmailer (or at all). My app allows people to send emails with invoices using their own emails / smtp. To do that with gmail, a user has to set up an app-specific password in their google settings. Which is too complicated for an average user. Is it possible to do that in a more streamlined way using google oauth? I want this functionality: In my app settings enters his gmail credentials, and on saving them is redirected to his google account for the oauth2 token. The returned token is then saved in the user settings in my app, and voila, the app can then send emails with invoices for the user using his own email. Is that possible? Would be really grateful for your input on that. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 5 replies
-
This is entirely possible, however, it's going to be a little tricky. While PHPMailer does provide a simple example for how to fetch an OAuth token from Google, it's outside PHPMailer's remit, and you probably need something a bit better than that; there are libraries that can do a much better job than the rudimentary scripts that PHPMailer provides. PHPMailer doesn't care how you get the token, but will happily use one to authenticate if you get it using other code. |
Beta Was this translation helpful? Give feedback.
-
To elaborate @Synchro’s reply: a. If each user will use his/her own gmail account, there is no way to bypass Google’s OAuth2 setup process. Were there an easy way to bypass it, it would likely be equally insecure. You could obviously do the setup for each user if you were given their Gmail credentials, but this would not be a tenable way of working in practice for more than a handful of users. b. If each user were given access to a central (i.e. your) gmail account and used SMTP from there to send invoices, in a similar manner to the way many website Contact pages operate, mail could indeed be sent - but not from the user’s own gmail address. Gmail will check that the logged-in sender (you) is the From: sender, and this is partly to forestall having an open mail relay. You may (may…) then find it workable to add the users’ email addresses as additional addresses to your own to create a ‘sent on behalf of’ email. Your user’s email address will appear in the recipient’s From: box, but the email header (which is not overtly visible to users) will contain your own email address (the ‘Mail from’ address). This is to try to prevent email being marked as spam by the recipient mail server. Further, if your email DNS uses DMARC, a mismatch between ‘Mail from’ address (which, since it your own address, would satisfy an SPF check) and ‘From’ (which is not checked by SPF) would be flagged as fail by DMARC; such a fail would result in the recipient’s email server either bouncing the message, quarantining it as spam, or ignoring the failure, depending on the DMARC settings in your DNS. Hardly wonderful solutions but, perhaps, food for thought! |
Beta Was this translation helpful? Give feedback.
-
@Synchro , @decomplexity , thanks. I was hoping I can set up my app to behave like the non-online email clients do: that, after enrering their own credentials the user would be forwarded to confirm connection on gmail website, which would then return the necessary credentials to my app, and the app would be allowed to use the users gmail via smtp. I realize now it will not be as simple. Thanks for helping to figure it out. |
Beta Was this translation helpful? Give feedback.
-
Your step 1 - Configure an OAuth2 app – is typically a registration process per gmail user who, in OAuth2 jargon, then delegates permissions to his/her app. In practice, you sign in to a Google account at https://console.cloud.google.com/ and then register the ‘app’. This registration gives you your ‘client credentials’: client ID and client secret. This is nothing to do with PHPMailer per se, and Google doesn’t need to know details of the client. You configure your app and PHPMailer’s own settings separately. Your step 2 – ‘fetch the token’ – involves your code:
So, to cut a long story short, if (if…) you want to store refresh tokens and/or access tokens for each of your users, they – or you on their behalf – first need to go through the registration process for each user. To your final two points: you either have app registrations for each gmail user or just yourself. If just yourself – with one access token and one refresh token – then you probably need to manage this though the ‘on behalf of’ process I mentioned in my previous reply or gmail will bounce your SMTP Send on the basis that the From: gmail address does not match that associated with the registration. Or perhaps I misunderstand what you wish to do. *don’t stretch this analogy to far! The refresh token is an affirmation that the user principal did previously sign in with his/her credentials and presented correct previously registered client ID and client secret (or certificate) to the authorization server. Its purpose is to obviate the need for the user principal to sign in again to get an authorization code. |
Beta Was this translation helpful? Give feedback.
-
So I have followed through the guide at https://github.com/PHPMailer/PHPMailer/wiki/Using-Gmail-with-XOAUTH2 I have found out that it is entirely possible to achieve what I want (provide my app users a way to send emails to their own clients using their own gmail smtp credentials directly from my app). I have successfully sent emails from my web page using different Google accounts after setting up only one app on Google Cloud. And the authorization of my app to send email on behalf of the users can be programmed to be performed by the users themselves, without my intervention. What was confusing me previously was the not entirely clear gmail_xoauth.php file and documentation in wiki. It is obvious in documentation (and gmail_xoauth.php) that parameters $clientId and $clientSecret should belong strictly to the app the developer sets up on Google Cloud during the steps described under the heading "Configure an OAuth2 app" (lets say they the account used by developer was developer@gmail.com). But it is not clear at all that the $email and $refreshToken parameter pair can be completely unrelated to the developer@gmail.com account. The email could be user1@gmail.com, user100@gmail.com or whatever, and each of those users of the developer's app can generate their own corresponding $refreshToken when starting to use the app (in documentation, that is done in the step "fetch the token"). @decomplexity , here you also were wrong when you wrote above, that at this step the Google server will "present a screen asking for the credentials (name and password) of the user (‘user principal’) who registered the app" – it can be any Gmail user, not the one who registered the app. Were it not so, it would be a step best completed at the same time the app itself is registered in Google Cloud. Now, in documentation the user case is not the use case I have. The documentation describes how to get the token displayed in web page so that it is copied into some configuration file by the developer manually. In my use case it would be saved, along with the email of the user, to the database, and used with other google smtp credentials, whenever the user wants to send an invoice to his/her client. It does not have to be a manual process at all - it can be completely automatic. Now the only problem is, that it is hardly feasible that such a feature will be popular. The warning message Google gives for those who would want to get that convenience is too scary I guess for it to be used widely enough. Google asks if the person agrees that my app "reads, creates sends and completely deletes all emails from Gmail mail box" - who in their right mind would agree to that? It would be a different story if it only exposed the smtp service, without providing total access to the user inbox. Also it is scary to hold those kinds of data in my app database; it can be encrypted, but it cannot be hashed, so, it is not really safe. |
Beta Was this translation helpful? Give feedback.
So I have followed through the guide at https://github.com/PHPMailer/PHPMailer/wiki/Using-Gmail-with-XOAUTH2
I have found out that it is entirely possible to achieve what I want (provide my app users a way to send emails to their own clients using their own gmail smtp credentials directly from my app). I have successfully sent emails from my web page using different Google accounts after setting up only one app on Google Cloud. And the authorization of my app to send email on behalf of the users can be programmed to be performed by the users themselves, without my intervention.
What was confusing me previously was the not entirely clear gmail_xoauth.php file and documentation in wiki.
It …