前言
在规划一个web的时候,肯定会遇到这种情况,有一些页面不能让未登入的用户访问,这个时候那些页面就要进行视图保护。
编写示例代码
现在就以登陆和登出为例子
在登出视图函数上做视图保护,就和前言中的解释类似,登陆了的用户可以访问登出视图,未登录的用户要先登陆才能登出
初始化app
from flask import Flask, url_for, render_template, flash
from flask_login import LoginManager, current_user, login_user, login_required, logout_user
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length
app = Flask(__name__)
login_manager = LoginManager(app)
bootstrap = Bootstrap(app)
'''
当然也可以利用init_app
login_manager = LoginManager()
login_manager.init_app(app)
Bootstrap()同理
'''
class LoginForm(FlaskForm):
username = StringField('Username',validators=[DataRequired(),Length(1,20)])
password = PasswordField('Password',validators=[DataRequired(),Length(8,128)])
remember = BooleanField('Remember me')
submit = SubmitField('Sign in')
def redirect_back(default='blog.index', **kwargs):
'''函数功能: 放回上一页'''
for target in request.args.get('next'), request.referrer:
if not target:
continue
if is_safe_url(target):
return redirect(target)
return redirect(url_for(default, **kwargs))
登录视图函数
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return 'success login, you can enjoy it'
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
remember = form.remember.data
admin = Admin.query.first()
if admin:
# 验证用户名和密码
if username == admin.name and admin.password:
login_user(admin, remember)
return "success login"
else:
return "账号或者密码错误"
return render_template('login.html', form=form)
login.html
{% from 'bootstrap/form.html' import render_form %}
<div>
<div>
<h1>Log in</h1>
</div>
<div>
{{ render_form(form, extra_classes='col-6') }}
</div>
</div>
登出函数
@app.route("/logout")
@login_required
def logout():
logout_user()
flash("Logout success.", 'info')
return redirect_back()
登出函数既要实现登出功能也要对其视图保护
其中
@login_required就是用于标明需要视图保护的视图
所以只要实现了flask_login的初始化,就可以可插拔的进行添加视图保护,十分方便。
例如
@app.route('/hello_1')
@login_required
def hello_1():
return "hello_1"
@app.route('/hello_2')
def hello_2():
return "hello_2"
当访问http://localhost/hello_1的时候 只有登入了才能看到hello_1,
访问/hello_2的时候 就直接可以看到hello_2
添加视图保护内容
......
login_manager = LoginManager(app)
login_manager.login_view = 'login'# 指定视图保护的视图函数
login_manager.login_message_category = 'warning'
# login_manager.login_message = u'请先登录!'
# 当用户没有登陆 却要访问需要登陆的url 就会跳转到视图保护的页面
login_manager.login_view 即是指定视图保护所跳转的视图函数,在这里是登入视图函数
login_manager.login_message 可以指定f消息内容,默认为"Please log in to access this."
login_manager.login_message_category 指定消息的类别,默认为"message"
整理代码
.
├── app.py
└── templates
└── login.html
app.py
from flask import Flask, url_for, render_template, flash
from flask_login import LoginManager, current_user, login_user, login_required, logout_user, UserMixin
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length
import os
basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
app = Flask(__name__)
# SECRET_KEY =
app.config['SECRET_KEY'] = "hello flask login"
app.config['SQLALCHEMY_DATABASE_URI']= 'sqlite:///' + os.path.join(basedir, 'data-dev.db')
login_manager = LoginManager(app)
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)
login_manager.login_view = 'login'# 指定视图保护的视图函数
login_manager.login_message_category = 'warning'
'''
当然也可以利用init_app
login_manager = LoginManager()
login_manager.init_app(app)
Bootstrap()同理
'''
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(1, 20)])
password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)])
remember = BooleanField('Remember me')
submit = SubmitField('Sign in')
class Admin(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
password = db.Column(db.String(50))
def init():
'''building, kiesblog, just for you '''
db.drop_all()
db.create_all()
admin = Admin.query.first()
admin = Admin(name="admin",
password="password")
db.session.add(admin)
db.session.commit()
init()
@login_manager.user_loader
def load_user(userid):
return User.get(userid)
@app.route('/')
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return 'success login, you can enjoy it'
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
remember = form.remember.data
admin = Admin.query.first()
if admin:
# 验证用户名和密码
if username == admin.name and admin.password:
login_user(admin, remember)
return "success login"
else:
return "账号或者密码错误"
return render_template('login.html', form=form)
@app.route("/logout")
@login_required
def logout():
logout_user()
return "logout success"
@app.route('/hello_1')
@login_required
def hello_1():
return "hello_1"
@app.route('/hello_2')
def hello_2():
return "hello_2"
if __name__ == '__main__':
app.run(host="0.0.0.0", port=80)
login.html
{% from 'bootstrap/form.html' import render_form %}
<div>
<div>
<h1>Log in</h1>
</div>
<div>
{{ render_form(form, extra_classes='col-6') }}
</div>
</div>
账号密码分别为 admin password
ps: 此为示例代码,未对password进行hash加密,如有需要请自行添加!
好了,可以开始你的测试了????
关于作者