kootenpv / yagmail

Send email in Python conveniently for gmail using yagmail
MIT License
2.64k stars 263 forks source link

Fix OAuth authorization expiring #252

Closed xnumad closed 2 years ago

xnumad commented 2 years ago

Google OAuth authorizations expire after 7 days if issued while the project was in "Testing" mode. [1]

Maybe the authorization itself expires, i.e. every token associated with it. So you can't just fix it by refreshing earlier (using the refresh token earlier to get a new auth token). [2] It would anyway be a more complicated setup since refreshing would need to be scheduled.

=> (Google Cloud Console) projects shall use "In Production" status If your project is in status “in production”, the refresh token will last longer (indefinitely, as I understand). [3]


Yagmail currently uses OOB auth which will not be supported in projects with "In Production" status. => Switch to a localhost redirect_uri. (which is still allowed for Desktop type clients) [4]


Fixes #244, fixes #247


[1] https://stackoverflow.com/a/68776672 [2] https://stackoverflow.com/a/67966982 [3] https://stackoverflow.com/questions/8953983/do-google-refresh-tokens-expire [4] https://developers.google.com/identity/protocols/oauth2/resources/oob-migration#desktop-client

xnumad commented 2 years ago

Although I am certain, I have not yet confirmed that it works as expected (i.e. the token won't expire after 7 days) (period not over yet). Will write again once 7 days are over.

kootenpv commented 2 years ago

Thanks so much for diving into this!

Code lgtm, let me know if it solves your problem after the 7 days then we can merge and update yagmail on pypi

xnumad commented 2 years ago

Still works after 7 days as expected! :+1:

kootenpv commented 2 years ago

Awesome thanks for checking

kootenpv commented 2 years ago

You can find the new version on pypi:

pip install -U --no-cache yagmail>=0.15.293
yekibud commented 1 year ago

@xnumad Thanks for this feature! Do you know if there are any security concerns around changing to "In Production" status? According to Google

Your app will be available to anyone with a Google account

But, IIUC, this would only happen if you exposed an oauth flow with your client credentials.

image

kootenpv commented 1 year ago

I have never seen this option so probably somewhere you selected a wrong option...

yekibud commented 1 year ago

This is the only way to convert an oauth app to production so you refresh token doesn't expire. The message is under the "In Production" tooltip, so you maybe you didn't mouse over it.

image

xnumad commented 1 year ago

tl;dr: 👍 This is no problem.


But, IIUC, this would only happen if you exposed an oauth flow with your client credentials.

Yes, that's mandatory anyway (there's no way around it). There's no such thing like a public listing of Google Cloud projects so that your project would be listed in there.


"In production" status:

Your app will be available to anyone with a Google account

I think it's clearer when reading this in contrast to the description for "testing" publishing status:

Your app will only be available to users you add to the list of test users.

Documentation for more details

So in testing mode, you have to explicitly allow people (Google accounts) before they can authorize your application.

This should not matter for yagmail when the Google account you are authorizing yagmail to is also the one that owns the Google Cloud project (i.e. authorizing to your own app).

yekibud commented 1 year ago

Makes sense @xnumad ! Thanks for the peace of mind. And, once again, thanks for the feature. Wound up switching to app password credentials, because I couldn't determine whether the oauth feature was really more "secure" via this method of fetching a permanent refresh token. But if someone with better security chops than me comes along, it's good to know we can switch back to oauth with yagmail.