1

I have a flask app using Flask-Security's registration to send Flask Mail upon registration. I've pointed the flask mail config at smtp.gmail.com port 464 using SSL. However, when the app tries to send mail it gets an smtplib.SMTPAuthenticationError. If I go to the google admin page and allow "less secure apps" through then the send works.

Here is the stack trace that I get when the send fails with the aforementioned error:

File "~/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
  return self.wsgi_app(environ, start_response)
File "~/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
  response = self.make_response(self.handle_exception(e))
File "~/lib/python3.5/site-packages/flask_restful/__init__.py", line 271, in error_router
  return original_handler(e)
File "~/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
  reraise(exc_type, exc_value, tb)
File "~/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
  raise value
File "~/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
  response = self.full_dispatch_request()
File "~/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
  rv = self.handle_user_exception(e)
File "~/lib/python3.5/site-packages/flask_restful/__init__.py", line 271, in error_router
  return original_handler(e)
File "~/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
  reraise(exc_type, exc_value, tb)
File "~/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
  raise value
File "~/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
  rv = self.dispatch_request()
File "~/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
  return self.view_functions[rule.endpoint](**req.view_args)
File "~/lib/python3.5/site-packages/flask_security/decorators.py", line 225, in wrapper
  return f(*args, **kwargs)
File "~/lib/python3.5/site-packages/flask_security/views.py", line 117, in register
  user = register_user(**form.to_dict())
File "~/lib/python3.5/site-packages/flask_security/registerable.py", line 41, in register_user
  user=user, confirmation_link=confirmation_link)
File "~/lib/python3.5/site-packages/flask_security/utils.py", line 341, in send_mail
  mail.send(msg)
File "~/lib/python3.5/site-packages/flask_mail.py", line 491, in send
  with self.connect() as connection:
File "~/lib/python3.5/site-packages/flask_mail.py", line 144, in __enter__
  self.host = self.configure_host()
File "~/lib/python3.5/site-packages/flask_mail.py", line 165, in configure_host
  host.login(self.mail.username, self.mail.password)
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/smtplib.py", line 729, in login
  raise last_exception
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/smtplib.py", line 720, in login
  initial_response_ok=initial_response_ok)
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/smtplib.py", line 641, in auth
  raise SMTPAuthenticationError(code, resp)

My mail config is:

app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True

This is what happens when I goto google admin to enable TLS for my app:

Not available for your account

What do I have to do to tell Flask Mail to comply with google's security standard?

David Watson
  • 3,394
  • 2
  • 36
  • 51

3 Answers3

3

You can send email with google smtp server you just need a app specific password you can get from here: https://security.google.com/settings/security/apppasswords

enter image description here

On the above page select other app and enter a name for it then you will get a app password.

This app is working and send email:

# Try to send a mail using

from flask import Flask
from flask.ext.mail import Mail
from flask.ext.mail import Message


app = Flask(__name__)


app.config['MAIL_SERVER'] = 'smtp.googlemail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = "your gmail username"
app.config['MAIL_PASSWORD'] = "Your app spesfic password"
app.config['MAIL_DEFAULT_SENDER'] = 'Default sender name'

mail = Mail(app)

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/send')
def send_mail():
    msg = Message("Hello",
                  sender="test@test.com",
                  recipients=["test@test.com"])
    mail.send(msg)
    return ""

if __name__ == '__main__':
    app.run(debug=True)
rezakamalifard
  • 1,289
  • 13
  • 24
  • I was about to mark this answer accepted, but see the original post for a screenshot of what happened when I went to my google apps account to enable TLS for the app. – David Watson Jan 22 '16 at 01:48
  • go to that url with your browser and try to add new app password – rezakamalifard Jan 22 '16 at 02:41
  • We're clearly not understanding one another. Did you look at the screenshot? That's what happens when I click the link you posted. – David Watson Jan 22 '16 at 03:18
  • Find my screenshot and comment in the my answer. – rezakamalifard Jan 22 '16 at 03:25
  • 1
    I clicked the link and got the error "The setting you are looking for is not available for your account." This is what the poster also encountered. – m1yag1 Jan 22 '16 at 15:37
  • This is because of your Google account setting and is not related to this issue and question. You need to get a google app spesific password to solve the problem in your question here. – rezakamalifard Jan 22 '16 at 15:40
  • Above answer works. First turn on the `double authentication` in your google account and then proceed with setting up an appPassword. – Deke Dec 30 '18 at 02:55
3

Go to https://accounts.google.com/DisplayUnlockCaptcha and enable this. Worked for me.

Edit: After doing so when I used the app on phone. The error was still there. It seems that I have to go every time to unlock it. I used @rezakamalifard method.

First we have to enable two step verification then only we can use the app password. After enabling the 2-step verification, go to app password and select app as mail and device (I selected windows computer) and try sending the mail again. It will work.

charchit
  • 1,492
  • 2
  • 6
  • 17
  • I can't comment. I think you have not seen my reputation yet. – charchit May 22 '21 at 11:04
  • You know about the commenting privilege which you do not have, so well that you can even put it into words. [You are aware about the rule](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). In that situation please do not decide to misuse a different mechanism (an answer) for something it is not meant for and which you are not allowed yet to do. – 4b0 May 24 '21 at 00:35
2

That is because Google wants your application to use OAuth2.

To better protect your users, we recommend you upgrade all of your applications to OAuth 2.0. If you choose not to do so, your users will be required to take extra steps in order to keep accessing your applications.

If you want to send email via smtp using Flask-Mail you will need to take that extra step and enable "less secure apps" in your Google admin page.

Source: https://googleonlinesecurity.blogspot.com/2014/04/new-security-measures-will-affect-older.html

m1yag1
  • 819
  • 7
  • 11