Flask-Security 邮件确认(Flask-Mail) 未修改flask_security/utils.py 发送失败
Flask-Security email confirmation (Flask-Mail) Fails to send without modifying flask_security/utils.py
我正在试验 Flask-Security,但在发送确认电子邮件时遇到了一些问题。我最终通过删除 flask_security/utils.py 中的一行来修复它。我删除了第 387 行,强制 flask-mail 使用 app.config 的邮件发件人。
386: msg = Message(subject,
387: sender=_security.email_sender,
388: recipients=[recipient])
在删除之前,代码会在 flask_mail.py、@第 105 行(在 sanatize_address 方法内)失败,因为传入的地址只是一个字符串,而不是元组。
102: def sanitize_address(addr, encoding='utf-8'):
103: if isinstance(addr, string_types):
104: addr = parseaddr(force_text(addr))
105: nm, addr = addr
我希望能够 运行 我的代码,而不必在每次安装时都修改 flask_security/utils.py。有什么建议么?这可能是我配置中遗漏的一个步骤,但我无法从 flask-security 的文档中看出(它们有点受限)。
感谢您的帮助,下面是我的示例应用程序。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security, SQLAlchemyUserDatastore, \
UserMixin, RoleMixin, login_required
import flask_security.utils
import flask_mail
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
# Flask-Security Config
app.config['SECURITY_PASSWORD_SALT'] = 'super_secret'
app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_TRACKABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = True
app.config['SECURITY_RECOVERABLE'] = True
# Mail Config
app.config['MAIL_SERVER'] = 'smtp.googlemail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'example@gmail.com'
app.config['MAIL_PASSWORD'] = 'password'
app.config['MAIL_DEFAULT_SENDER'] = app.config['MAIL_USERNAME']
mail = flask_mail.Mail(app)
# Create database connection object
db = SQLAlchemy(app)
# Define models
roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
username = db.Column(db.String(255))
password = db.Column(db.String(255))
last_login_at = db.Column(db.DateTime())
current_login_at = db.Column(db.DateTime())
last_login_ip = db.Column(db.String(100))
current_login_ip = db.Column(db.String(100))
login_count = db.Column(db.Integer)
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary='roles_users',
backref=db.backref('users', lazy='dynamic'))
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():
db.create_all()
user_datastore.create_user(email='user@website.com', password=flask_security.utils.hash_password('password'))
db.session.commit()
# Views
@app.route('/')
@login_required
def home():
return('Here you go!')
if __name__ == '__main__':
app.run()
我最近也发现了这个。查看源代码后,我找到了原因。 ps: 我是python新手,所以可能ps,以下是错误的。
在您的代码中,app.config['MAIL_DEFAULT_SENDER'] = app.config['MAIL_USERNAME']
。因此,让我们检查源代码以了解 flask-security 如何使用此配置。
在flask-security/core.py 中:
41: _default_config = {
...
87: 'EMAIL_SENDER': LocalProxy(lambda: current_app.config.get(
88: 'MAIL_DEFAULT_SENDER', 'no-reply@localhost.com'
89: )),
如果没有设置SECURITY_EMAIL_SENDER
配置,flask-security使用lambda: current_app.config.get('MAIL_DEFAULT_SENDER', 'no-reply@localhost.com')
的代理来设置SECURITY_EMAIL_SENDER
。注意:SECURITY_EMAIL_SENDER
目前是一个 LocalProxy
实例。
386: msg = Message(subject,
387: sender=_security.email_sender,
388: recipients=[recipient])
_security.email_sender
是一个 LocalProxy
实例。
102: def sanitize_address(addr, encoding='utf-8'):
103: if isinstance(addr, string_types):
104: addr = parseaddr(force_text(addr))
105: nm, addr = addr
addr
是一个 LocalProxy
实例。所以isinstance(addr, string_types)
就是False
,nm, addr = addr
就出错了
因此,如果使用 flask-security,请设置 SECURITY_EMAIL_SENDER
配置以避免此错误。
我正在试验 Flask-Security,但在发送确认电子邮件时遇到了一些问题。我最终通过删除 flask_security/utils.py 中的一行来修复它。我删除了第 387 行,强制 flask-mail 使用 app.config 的邮件发件人。
386: msg = Message(subject,
387: sender=_security.email_sender,
388: recipients=[recipient])
在删除之前,代码会在 flask_mail.py、@第 105 行(在 sanatize_address 方法内)失败,因为传入的地址只是一个字符串,而不是元组。
102: def sanitize_address(addr, encoding='utf-8'):
103: if isinstance(addr, string_types):
104: addr = parseaddr(force_text(addr))
105: nm, addr = addr
我希望能够 运行 我的代码,而不必在每次安装时都修改 flask_security/utils.py。有什么建议么?这可能是我配置中遗漏的一个步骤,但我无法从 flask-security 的文档中看出(它们有点受限)。
感谢您的帮助,下面是我的示例应用程序。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_security import Security, SQLAlchemyUserDatastore, \
UserMixin, RoleMixin, login_required
import flask_security.utils
import flask_mail
# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
# Flask-Security Config
app.config['SECURITY_PASSWORD_SALT'] = 'super_secret'
app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_TRACKABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = True
app.config['SECURITY_RECOVERABLE'] = True
# Mail Config
app.config['MAIL_SERVER'] = 'smtp.googlemail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'example@gmail.com'
app.config['MAIL_PASSWORD'] = 'password'
app.config['MAIL_DEFAULT_SENDER'] = app.config['MAIL_USERNAME']
mail = flask_mail.Mail(app)
# Create database connection object
db = SQLAlchemy(app)
# Define models
roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
username = db.Column(db.String(255))
password = db.Column(db.String(255))
last_login_at = db.Column(db.DateTime())
current_login_at = db.Column(db.DateTime())
last_login_ip = db.Column(db.String(100))
current_login_ip = db.Column(db.String(100))
login_count = db.Column(db.Integer)
active = db.Column(db.Boolean())
confirmed_at = db.Column(db.DateTime())
roles = db.relationship('Role', secondary='roles_users',
backref=db.backref('users', lazy='dynamic'))
# Setup Flask-Security
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
# Create a user to test with
@app.before_first_request
def create_user():
db.create_all()
user_datastore.create_user(email='user@website.com', password=flask_security.utils.hash_password('password'))
db.session.commit()
# Views
@app.route('/')
@login_required
def home():
return('Here you go!')
if __name__ == '__main__':
app.run()
我最近也发现了这个。查看源代码后,我找到了原因。 ps: 我是python新手,所以可能ps,以下是错误的。
在您的代码中,app.config['MAIL_DEFAULT_SENDER'] = app.config['MAIL_USERNAME']
。因此,让我们检查源代码以了解 flask-security 如何使用此配置。
在flask-security/core.py 中:
41: _default_config = {
...
87: 'EMAIL_SENDER': LocalProxy(lambda: current_app.config.get(
88: 'MAIL_DEFAULT_SENDER', 'no-reply@localhost.com'
89: )),
如果没有设置SECURITY_EMAIL_SENDER
配置,flask-security使用lambda: current_app.config.get('MAIL_DEFAULT_SENDER', 'no-reply@localhost.com')
的代理来设置SECURITY_EMAIL_SENDER
。注意:SECURITY_EMAIL_SENDER
目前是一个 LocalProxy
实例。
386: msg = Message(subject,
387: sender=_security.email_sender,
388: recipients=[recipient])
_security.email_sender
是一个 LocalProxy
实例。
102: def sanitize_address(addr, encoding='utf-8'):
103: if isinstance(addr, string_types):
104: addr = parseaddr(force_text(addr))
105: nm, addr = addr
addr
是一个 LocalProxy
实例。所以isinstance(addr, string_types)
就是False
,nm, addr = addr
就出错了
因此,如果使用 flask-security,请设置 SECURITY_EMAIL_SENDER
配置以避免此错误。