标签:rdp jre sds title 设置密码 mbg pyw DApp path
自定义字段验证函数
class RegisterForm(FlaskForm):
...
def validate_username(self, field):
user = User.query.filter(User.username == field.data).first()
if user:
raise ValidationError(‘该用户名已注册,请选用其他名称注册‘)
def validate_email(self, field):
user = User.query.filter(User.email == field.data).first()
if user:
raise ValidationError(‘该邮箱已注册,请选用其他邮箱注册‘)
加密存储密码
from werkzeug.security import generate_password_hash, check_password_hash
class User(db.Model):
...
@property
def password(self):
raise AttributeError(‘你瞅啥?!密码不可读‘)
@password.setter
def password(self, password):
# 加密保存密码
self.password_hash = generate_password_hash(password)
# 密码校验,True:校验成功,False:校验失败
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
登录校验逻辑
@user.route(‘/login/‘, methods=[‘GET‘, ‘POST‘])
def login():
form = LoginForm()
if form.validate_on_submit():
u = User.query.filter(User.username == form.username.data).first()
if not u:
flash(‘无效的用户名‘)
elif not u.confirmed:
flash(‘账户尚未激活,请激活后再登录‘)
elif not u.verify_password(form.password.data):
flash(‘无效的密码‘)
else:
flash(‘登录成功‘)
return redirect(url_for(‘main.index‘))
return render_template(‘user/login.html‘, form=form)
flask-login扩展
pip install flask-login
# 第一步:添加扩展
from flask_login import LoginManager
login_manager = LoginManager()
def init_extensions(app):
...
login_manager.init_app(app)
# 指定登录端点
login_manager.login_view = ‘user.login‘
# 设置提示信息
login_manager.login_message = ‘登录后才可访问‘
# 第二步:让模型类类基础子UserMixin类,以便拥有状态相关方法
from flask_login import UserMixin
class User(UserMixin, db.Model):
...
# 第三步:实现回调函数(根据用户id返回用户对象)
@login_manager.user_loader
def load_user(uid):
return User.query.get(uid)
状态切换:
login_user # 还可以完成记住我的功能(时间也可以指定)
logout_user
状态查询:
is_authenticated # 登录状态
is_anonymous # 匿名状态
路由保护:
login_required # 保护需要登录才可访问的路由
当前用户:
current_user # 在模板中使用不需要分配
#修改密码
@user.route(‘/modifypassword/‘,methods=[‘GET‘,‘POST‘])
def modify_password():
form = ModifyPasswordForm()
if form.validate_on_submit():
if current_user.verify_password(form.password.data):
current_user.password = form.password_new1.data
flash(‘修改密码成功‘)
return redirect(url_for(‘user.login‘))
else:
flash(‘原始密码错误‘)
return render_template(‘user/modify_password.html‘, form=form)
#修改邮箱
@user.route(‘/modifyemail/‘,methods=[‘GET‘,‘POST‘])
def modify_email():
form = ModifyEmailForm()
if form.validate_on_submit():
if current_user.email == form.email.data:
s = Serializer(current_app.config[‘SECRET_KEY‘],expires_in=3600)
token = s.dumps({‘id‘:current_user.id,‘email‘:form.email_new.data})
send_mail(‘邮箱修改‘,form.email_new.data,‘email/modify_email_activate.html‘,username=current_user.username,token=token)
flash(‘请前往新邮箱确认修改‘)
return redirect(url_for(‘user.profile‘))
else:
flash(‘原始邮箱不正确‘)
return render_template(‘user/modify_email.html‘,form=form)
# 找回密码
@user.route(‘/findpassword/<way>/‘, methods=[‘GET‘, ‘POST‘])
def find_password(way):
form = FindPasswordForm()
s = Serializer(current_app.config[‘SECRET_KEY‘], expires_in=3600)
if form.validate_on_submit():
u = User.query.filter(
or_(User.username == form.username_email.data, User.email == form.username_email.data)).first()
if u:
token = s.dumps({‘id‘: u.id})
# send_mail(‘通过用户名找回密码‘,u.email,‘email/find_password_activate.html‘,username=u.username,token=token)
flash(‘请前往邮箱确认找回密码‘)
else:
flash(‘用户名错误‘)
return redirect(url_for(‘user.login‘))
return render_template(‘user/find_password.html‘, form=form)
@user.route(‘/findpasswordactivate/<token>/‘, methods=[‘GET‘, ‘POST‘])
def find_password_activate(token):
form = NewPasswordForm()
s = Serializer(current_app.config[‘SECRET_KEY‘])
try:
data = s.loads(token)
except SignatureExpired as e:
flash(‘token已过期,找回密码失败‘)
return redirect(url_for(‘user.login‘))
except BadSignature as e:
flash(‘token有误,找回密码失败‘)
return redirect(url_for(‘user.login‘))
u = User.query.get(data[‘id‘])
if form.validate_on_submit():
u.password = form.password2.data
db.session.add(u)
flash(‘找回密码成功‘)
return redirect(url_for(‘user.login‘))
return render_template(‘user/new_password.html‘, form=form)
# 修改头像
@user.route(‘/icon/‘, methods=[‘GET‘, ‘POST‘])
def icon():
form = UploadForm()
if form.validate_on_submit():
# 提取上传文件信息
photo = form.photo.data
# 提取文件后缀带点
suffix = os.path.splitext(photo.filename)[1]
# 生成随机文件名
filename = random_string() + suffix
# 用上传对象保存图片,并指定名字
photos.save(photo, name=filename)
# 拼接完整的图片路径
pathname = os.path.join(current_app.config[‘UPLOADED_PHOTOS_DEST‘], filename)
# 缩略图操作,打开文件
img = Image.open(pathname)
# 设置图片尺寸
img.thumbnail((32, 32))
# 重新保存,指定完整路径
img.save(pathname)
# 如果当前用户用的是默认头像,则不用删除
# 若果用的不是默认头像,为减少存储需要先删除原来的头像
if current_user.icon != ‘default.jpg‘:
# os.remove删除项目本地文件
os.remove(os.path.join(current_app.config[‘UPLOADED_PHOTOS_DEST‘], current_user.icon))
# 新的头像准备好了,添加到model里
current_user.icon = filename
# 手动保存,可有可无
db.session.add(current_user)
# 头像已经保存到了static和model中,为了展示头像,可以把图片的路径传给模板
# 静态文件是固定格式 注:不能直接写图片名,那样就写死了
# 不同用户有独自的头像,所以用current_user.icon进行拼接
img_url = url_for(‘static‘, filename=‘upload/‘ + current_user.icon)
return render_template(‘user/icon.html‘, form=form, img_url=img_url)
标签:rdp jre sds title 设置密码 mbg pyw DApp path
原文地址:https://www.cnblogs.com/swjblog/p/9741794.html