from flask_login import LoginManager
login_manager=LoginManager()
def create_app():
app = Flask(__name__)
app.config.from_object("setting")
app.config.from_object("secure")
app.config['JSON_AS_ASCII'] = False
#登錄插件
login_manager.init_app(app)
login_manager.login_view='web.login' #訪問要cookie的url 沒有登陸態度要重定向的視圖,下面閃現的信息會出現在這個登錄頁面上
login_manager.login_message='請先登錄或注冊' # 沒有身份態訪問 提示信息設置 原理,當訪問沒有權限訪問的頁面,flask會自動閃現一條文本提示
return app
數據庫模型
#coding=utf-8
from sqlalchemy import Column,Integer,String,Boolean,Float
from models.base import db
from werkzeug.security import generate_password_hash,check_password_hash
from models.base import Base
from flask_login import UserMixin
from app import login_manager
#book模型,傳入db核心對象把Book插入db
class User(UserMixin,Base): #UserMixin這個類是flask_login里面需要定義的東西,導入后就執行是默認定義
__tablename__ = 'user'
id = Column(Integer,primary_key=True)
nickname = Column(String(24), nullable=False)
email = Column(String(50), unique=True, nullable=False)
@property
def password(self):
return self._password
@password.setter
def password(self,raw):
self._password=generate_password_hash(raw)
def check_password(self,raw):
return check_password_hash(self._password,raw)
# # 定義用戶唯一標示id如果id不是用戶唯一標示,這里需要更改,如果id是,那么不需要寫
#def get_id(self):
# return self.id
@login_manager.user_loader #不加這個會寫入cookie異常,注意他是一個獨立的函數
def get_user(uid):
return User.query.get(int(uid))
視圖
from flask_login import login_user
@web.route('/login', methods=['GET', 'POST'])
def login():
form=LoginForm(request.form)
if request.method =="POST" and form.validate():
user= User.query.filter_by(email=form.email.data).first()
if user and user.check_password(form.password.data):
login_user(user,remember=True) #remember為登錄態是否要記住,關閉瀏覽器后還記住為Ture,記住的時間可以在falsk配置文件中設置 默認為365天
flash("登錄成功")
else:
flash("賬號不存在或密碼錯誤")
return render_template("auth/login.html",form=form)
更改登錄態記住的時長,在flask配置文件里面增加一個值去設置
讓視圖函數 沒有登錄態不能訪問的方法 加上插件的裝飾器
from flask_login import login_required
@web.route('/my/gifts')
@login_required
def my_gifts():
return "訪問成功"
當訪問了沒有權限的頁面,跳轉到登錄頁面后,用戶登錄后跳轉回原來頁面的方法:
訪問沒有權限的頁面跳轉到登錄頁面 url 自動帶上原來訪問的uri http://000:5000/login?next=/mygift 我們獲取next后面的uri進行跳轉
@web.route('/login', methods=['GET', 'POST'])
def login():
form=LoginForm(request.form)
if request.method =="POST" and form.validate():
user= User.query.filter_by(email=form.email.data).first()
if user or user.check_password(form.password.data):
login_user(user)
flash("登錄成功")
next=request.args.get('next')
if not next and not next.startswith("/"): #這里加個邏輯uri要/開頭的,防止重定向攻擊 如別人在后面輸出http://baidu.com 別人登錄后就跳百度去了
next=url_for("web.index")
return redirect(next)
else:
flash("賬號不存在或密碼錯誤")
return render_template("auth/login.html",form=form)
用戶登出
from flask_login import logout_user
@web.route('/logout')
def logout():
logout_user() #刪除cookie
return redirect(url_for("web.index"))
獲取當前訪問用戶的id 寫入數據庫的方法:
from flask_login import login_required,current_user
from flask import current_app
from app.models.gift import Gift
from models.base import db
@web.route('/gifts/book/<isbn>')
@login_required
def save_to_gifts(isbn):
gift = Gift()
gift.isbn=isbn
#獲取當前用戶的id
gift.uid=current_user.id #current_user 實際就是 User表的類
#獲取配置文件 BEANS_UPLOAD_ONE_BOOK 數值的方法 參考:https://www.cnblogs.com/kaibindirver/p/12643665.html
current_user.beans += current_app.config["BEANS_UPLOAD_ONE_BOOK"] #獲取當前這個用戶 user表里面的魚豆 beans,這里去配置文件獲取 魚豆默認變量 2
db.session.add(gift)
db.session.commit()
return "完成"
判斷用戶是否登錄
if current_user.is_authenticated: #登錄了返回ture
注冊視圖
@web.route('/register', methods=['GET', 'POST'])
def register():
form=RegisterForm(request.form)
if request.method =="POST" and form.validate():
user=User()
user.set_attrs(form.data)
db.session.add(user)
db.session.commit()
return redirect(url_for("web.login"))
return render_template("auth/register.html",form=form)