Flask用户登录注册

Flask框架 2020-08-29 859

flask的用户管理,借助flask-login第三方库来实现,当然也可以借助其他的库。

用户模型如下:

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash

db = SQLAlchemy()

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(254), unique=True, index=True)
    username = db.Column(db.String(20), unique=True, index=True)
    password_hash = db.Column(db.String(128))
    confirmed = db.Column(db.Boolean, default=False)
    add_time = db.Column(db.DateTime, default=datetime.now)

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)

    def set_password(self, password):
        self.password_hash = generate_password_hash(password)

    def validate_password(self, password):
        return check_password_hash(self.password_hash, password)

    def __str__(self):
        return self.username

flask相关配置

from flask import Flask
from app.config import settings, secure
from app.web import web
from app.auth import auth
from app.models.models import db
from flask_migrate import Migrate
from flask_login import LoginManager

login_manager = LoginManager()

# 必须写
@login_manager.user_loader
def load_user(user_id):
    from app.models.models import User
    user = User.query.get(int(user_id))
    return user


def create_app():
    app = Flask(__name__)
    app.config.from_object(settings)
    app.config.from_object(secure)
    bootstrap.init_app(app)
    db.init_app(app)
    # flask-login 
    login_manager.init_app(app)
    login_manager.login_view = 'auth.login'
    login_manager.login_message = '请先登录或注册'

    app.register_blueprint(web)
    app.register_blueprint(auth)
    Migrate(app, db)
    return app

auth模块,蓝图

# auth/__init__.py
from flask.blueprints import Blueprint

auth = Blueprint('auth', __name__)
from app.auth import user_auth

1.用户注册

# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from wtforms import ValidationError


class RegisterForm(FlaskForm):
    email = StringField('邮箱', validators=[DataRequired(), Length(1, 64), Email()])
    username = StringField('姓名', validators=[DataRequired(), Length(1, 30)])
    password = PasswordField('密码', validators=[DataRequired(), Length(6, 15), EqualTo('password2')])
    password2 = PasswordField('确认密码', validators=[DataRequired(), Length(6, 15)])
    submit = SubmitField('提交')


# auth.py
from app.auth import *
from flask_login import current_user, logout_user, login_required, login_user
from flask import redirect, render_template, url_for, flash
from app.forms.auth import RegisterForm, LoginForm, ResetPwdForm
from app.models.models import User
from app.models.models import db


@auth.route('/register/', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('web.index'))
    form = RegisterForm()
    if form.validate_on_submit():
        email = form.email.data
        username = form.username.data
        password = form.password.data
        user = User(email=email, username=username)
        user.set_password(password)
        db.session.add(user)
        db.session.commit()
        flash('激活邮件发送成功,请您30分钟内验证邮箱', 'info')
        return redirect(url_for('auth.login'))
    return render_template('auth/register.html', form=form)
forms.py

class LoginForm(FlaskForm):
    email = StringField('邮箱', validators=[DataRequired(), Length(1, 64), Email()])
    password = PasswordField('密码', validators=[DataRequired(), Length(6, 15)])
    submit = SubmitField('登录')

auth.py

@auth.route('/login/', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('web.index'))
    form = LoginForm()
    if form.validate_on_submit():
        email = form.email.data
        password = form.password.data
        user = User.query.filter_by(email=email).first()
        if user is None:
            flash('用户名错误')
        if user.validate_password(password):
            login_user(user)
            return redirect(url_for('web.index'))
        flash('密码错误')
    return render_template('auth/login.html', form=form)

重置密码(登录状态下)

class ResetPwdForm(FlaskForm):
    old_password = PasswordField('旧密码', validators=[DataRequired(), Length(6, 15)])
    password = PasswordField('密码', validators=[DataRequired(), Length(6, 15), EqualTo('password2')])
    password2 = PasswordField('确认密码', validators=[DataRequired(), Length(6, 15)])
    submit = SubmitField('提交')

    def validate_password(self, field):
        if self.old_password.data == field.data:
            raise ValidationError('旧密码不能与新密码相同')

auth.py
@auth.route('/reset', methods=['GET', 'POST'])
@login_required
def reset_pwd():
    user = current_user
    form = ResetPwdForm()
    if form.validate_on_submit():
        old_pwd = form.old_password.data
        password = form.password.data
        if user.validate_password(old_pwd):
            user.set_password(password)
            db.session.add(user)
            db.session.commit()
            flash('重置成功', 'info')
            logout_user()  # 登出
            return redirect(url_for('auth.login'))
        flash('密码错误', 'waring')
    return render_template('auth/reset_pwd.html', form=form)

登出功能:

@auth.route('/logout')
@login_required
def logout():
    logout_user()
    flash('登出成功', 'info')
    return redirect(url_for('web.index'))

flask相对于django来说轻,但是很多东西需要你来配置,如果配置出点错,你懂的。

如果你写中大型项目,我更推荐使用django,因为django的配置相对来说更友好,且数据库方面,django比SQLAlchemy要更简单,也更容易理解。

标签:Flask框架

文章评论

评论列表

已有0条评论