中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

Python的Flask框架中實(shí)現(xiàn)簡單的登錄功能的教程
來源:易賢網(wǎng) 閱讀:7152 次 日期:2015-04-24 10:58:11
溫馨提示:易賢網(wǎng)小編為您整理了“Python的Flask框架中實(shí)現(xiàn)簡單的登錄功能的教程”,方便廣大網(wǎng)友查閱!

Python的Flask框架中實(shí)現(xiàn)簡單的登錄功能的教程,登錄是各個(gè)web框架中的基礎(chǔ)功能,需要的朋友可以參考下

回顧

在前面的系列章節(jié)中,我們創(chuàng)建了一個(gè)數(shù)據(jù)庫并且學(xué)著用用戶和郵件來填充,但是到現(xiàn)在我們還沒能夠植入到我們的程序中。 兩章之前,我們已經(jīng)看到怎么去創(chuàng)建網(wǎng)絡(luò)表單并且留下了一個(gè)實(shí)現(xiàn)完全的登陸表單。

在這篇文章中,我們將基于我門所學(xué)的網(wǎng)絡(luò)表單和數(shù)據(jù)庫來構(gòu)建并實(shí)現(xiàn)我們自己的用戶登錄系統(tǒng)。教程的最后我們小程序會實(shí)現(xiàn)新用戶注冊,登陸和退出的功能。

為了能跟上這章節(jié),你需要前一章節(jié)最后部分,我們留下的微博程序。請確保你的程序已經(jīng)正確安裝和運(yùn)行。

在前面的章節(jié),我們開始配置我們將要用到的Flask擴(kuò)展。為了登錄系統(tǒng),我們將使用兩個(gè)擴(kuò)展,Flask-Login 和 Flask-OpenID. 配置如下所示 (fileapp__init__.py):

import os

from flaskext.login import LoginManager

from flaskext.openid import OpenID

from config import basedir

lm = LoginManager()

lm.setup_app(app)

oid = OpenID(app, os.path.join(basedir, 'tmp'))

Flask-OpenID 擴(kuò)展為了可以存儲臨時(shí)文件,需要一個(gè)臨時(shí)文件夾路徑。為此,我們提供了它的位置。

重訪我們的用戶模型

Flask-Login擴(kuò)展需要在我們的User類里實(shí)現(xiàn)一些方法。除了這些方法以外,類沒有被要求實(shí)現(xiàn)其它方法。

下面是我們的User類 (fileapp/models.py):

class User(db.Model):

id = db.Column(db.Integer, primary_key = True)

nickname = db.Column(db.String(64), unique = True)

email = db.Column(db.String(120), unique = True)

role = db.Column(db.SmallInteger, default = ROLE_USER)

= db.relationship('Post', backref = 'author', lazy = 'dynamic')

def is_authenticated(self):

return True

def is_active(self):

return True

def is_anonymous(self):

return False

def get_id(self):

return unicode(self.id)

def __repr__(self):

return '<User %r>' % (self.name)

is_authenticated方法是一個(gè)誤導(dǎo)性的名字的方法,通常這個(gè)方法應(yīng)該返回True,除非對象代表一個(gè)由于某種原因沒有被認(rèn)證的用戶。

is_active方法應(yīng)該為用戶返回True除非用戶不是激活的,例如,他們已經(jīng)被禁了。

is_anonymous方法應(yīng)該為那些不被獲準(zhǔn)登錄的用戶返回True。

最后,get_id方法為用戶返回唯一的unicode標(biāo)識符。我們用數(shù)據(jù)庫層生成唯一的id。

用戶加載回調(diào)

現(xiàn)在我們通過使用Flask-Login和Flask-OpenID擴(kuò)展來實(shí)現(xiàn)登錄系統(tǒng)

首先,我們需要寫一個(gè)方法從數(shù)據(jù)庫加載到一個(gè)用戶。這個(gè)方法會被Flask-Login使用(fileapp/views.py):

@lm.user_loader

def load_user(id):

return User.query.get(int(id))

記住Flask-Login里的user id一直是unicode類型的,所以在我們把id傳遞給Flask-SQLAlchemy時(shí),有必要把它轉(zhuǎn)化成integer類型。

登錄視圖函數(shù)

接下來我們要更新登錄視圖函數(shù)(fileapp/views.py):

from flask import render_template, flash, redirect, session, url_for, request, g

from flaskext.login import login_user, logout_user, current_user, login_required

from app import app, db, lm, oid

from forms import LoginForm

from models import User, ROLE_USER, ROLE_ADMIN

@app.route('/login', methods = ['GET', 'POST'])

@oid.loginhandler

def login():

if g.user is not None and g.user.is_authenticated():

return redirect(url_for('index'))

form = LoginForm()

if form.validate_on_submit():

session['remember_me'] = form.remember_me.data

return oid.try_login(form.openid.data, ask_for = ['nickname', 'email'])

return render_template('login.html',

title = 'Sign In',

form = form,

providers = app.config['OPENID_PROVIDERS'])

注意到我們導(dǎo)入了一些新的模塊,其中有些后面會用到。

跟上個(gè)版本的變化很小。我們給視圖函數(shù)添加了一個(gè)新的裝飾器:oid.loginhandler。它告訴Flask-OpenID這是我們的登錄視圖函數(shù)。

在方法體的開頭,我們檢測是是否用戶是已經(jīng)經(jīng)過登錄認(rèn)證的,如果是就重定向到index頁面。這兒的思路是如果一個(gè)用戶已經(jīng)登錄了,那么我們不會讓它做二次登錄。

全局變量g是Flask設(shè)置的,在一個(gè)request生命周期中,用來存儲和共享數(shù)據(jù)的變量。所以我猜你已經(jīng)想到了,我們將把已經(jīng)登錄的用戶放到g變量里。

我們在調(diào)用redirect()時(shí)使用的url_for()方法是Flask定義的從給定的view方法獲取url。如果你想重定向到index頁面,你h很可能使用redirect('/index'),但是我們有很好的理由讓Flask為你構(gòu)造url。

當(dāng)我們從登錄表單得到返回?cái)?shù)據(jù),接下來要運(yùn)行的代碼也是新寫的。這兒我們做兩件事。首先我們保存remember_me的布爾值到Flask的session中,別和Flask-SQLAlchemy的db.session混淆了。我們已經(jīng)知道在一個(gè)request的生命周期中用Flask的g對象來保存和共享數(shù)據(jù)。沿著這條線路Flask的session提供了更多,更復(fù)雜的服務(wù)。一旦數(shù)據(jù)被保存到session中,它將在同一客戶端發(fā)起的這次請求和這次以后的請求中永存而不會消亡。數(shù)據(jù)將保持在session中直到被明確的移除。為了做到這些,F(xiàn)lask為每個(gè)客戶端建立各自的session。

下面的oid.try_login是通過Flask-OpenID來執(zhí)行用戶認(rèn)證。這個(gè)方法有兩個(gè)參數(shù),web表單提供的openid和OpenID provider提供的我們想要的list數(shù)據(jù)項(xiàng)。由于我們定義了包含nickname和email的User類,所以我們要從找nickname和email這些項(xiàng)。

基于OpenID的認(rèn)證是異步的。如果認(rèn)證成功,F(xiàn)lask-OpenID將調(diào)用有由oid.after_login裝飾器注冊的方法。如果認(rèn)證失敗那么用戶會被重定向到login頁面。

Flask-OpenID登錄回調(diào)

這是我們實(shí)現(xiàn)的after_login方法(app/views.py)

@oid.after_login

def after_login(resp):

if resp.email is None or resp.email == "":

flash('Invalid login. Please try again.')

redirect(url_for('login'))

user = User.query.filter_by(email = resp.email).first()

if user is None:

nickname = resp.nickname

if nickname is None or nickname == "":

nickname = resp.email.split(]

user = User(nickname = nickname, email = resp.email, role = ROLE_USER)

db.session.add(user)

db.session.commit()

remember_me = False

if 'remember_me' in session:

remember_me = session['remember_me']

session.pop('remember_me', None)

login_user(user, remember = remember_me)

return redirect(request.args.get('next') or url_for('index'))

傳給after_login方法的resp參數(shù)包含了OpenID provider返回的一些信息。

第一個(gè)if聲明僅僅是為了驗(yàn)證。我們要求一個(gè)有效的email,所以一個(gè)沒有沒提供的email我們是沒法讓他登錄的。

接下來,我們將根據(jù)email查找數(shù)據(jù)庫。如果email沒有被找到我們就認(rèn)為這是一個(gè)新的用戶,所以我們將在數(shù)據(jù)庫中增加一個(gè)新用戶,做法就像我們從之前章節(jié)學(xué)到的一樣。注意我們沒有處理nickname,因?yàn)橐恍㎡penID provider并沒有包含這個(gè)信息。

做完這些我們將從Flask session中獲取remember_me的值,如果它存在,那它是我們之前在login view方法中保存到session中的boolean類型的值。

然后我們調(diào)用Flask-Login的login_user方法,來注冊這個(gè)有效的登錄。

最后,在最后一行我們重定向到下一個(gè)頁面,或者如果在request請求中沒有提供下個(gè)頁面時(shí),我們將重定向到index頁面。

跳轉(zhuǎn)到下一頁的這個(gè)概念很簡單。比方說我們需要你登錄才能導(dǎo)航到一個(gè)頁面,但你現(xiàn)在并未登錄。在Flask-Login中你可以通過login_required裝飾器來限定未登錄用戶。如果一個(gè)用戶想連接到一個(gè)限定的url,那么他將被自動的重定向到login頁面。Flask-Login將保存最初的url作為下一個(gè)頁面,一旦登錄完成我們便跳轉(zhuǎn)到這個(gè)頁面。

做這個(gè)工作Flask-Login需要知道用戶當(dāng)前在那個(gè)頁面。我們可以在app的初始化組件里配置它(app/__init__.py):

lm = LoginManager()

lm.setup_app(app)

lm.login_view = 'login'

全局變量g.user

如果你注意力很集中,那么你應(yīng)該記得在login view方法中我們通過檢查g.user來判斷一個(gè)用戶是否登錄了。為了實(shí)現(xiàn)這個(gè)我們將使用Flask提供的before_request事件。任何一個(gè)被before_request裝飾器裝飾的方法將會在每次request請求被收到時(shí)提前與view方法執(zhí)行。所以在這兒來設(shè)置我們的g.user變量(app/views.py):

@app.before_request

def before_request():

g.user = current_user

這就是它要做的一切,current_user全局變量是被Flask-Login設(shè)定的,所以我們只需要把它拷貝到更容易被訪問的g變量就OK了。這樣,所有的請求都能訪問這個(gè)登錄的用戶,甚至于內(nèi)部的模板。

index視圖

在之前的章節(jié)中我們用假代碼遺留了我們的index視圖,因?yàn)槟莻€(gè)時(shí)候我們系統(tǒng)里并沒有用戶和博客文章。現(xiàn)在我們有用戶了,所以,讓我們來完成它吧:

@app.route('/')

@app.route('/index')

@login_required

def index():

user = g.user

= [

{

'author': { 'nickname': 'John' },

'body': 'Beautiful day in Portland!'

},

{

'author': { 'nickname': 'Susan' },

'body': 'The Avengers movie was so cool!'

}

]

return render_template('index.html',

title = 'Home',

user = user,

= )

在這個(gè)方法中只有兩處變動。首先,我們增加了login_required裝飾器。這樣表明了這個(gè)頁面只有登錄用戶才能訪問。

另一個(gè)改動是把g.user傳給了模板,替換了之間的假對象。

現(xiàn)在可以運(yùn)行我們的應(yīng)用了。

當(dāng)我們連接到你將會看到登陸頁面。記著如果你通過OpenID登錄那么你必須使用你的提供者提供的OpenID URL。你可以下面URL中的任何一個(gè)OpenID provider來為你產(chǎn)生一個(gè)正確的URL。

作為登錄進(jìn)程的一部分,你將會被重定向到OpenID提供商的網(wǎng)站,你將在那兒認(rèn)證和授權(quán)你共享給我們應(yīng)用的一些信息(我們只需要email和nickname,放心,不會有任何密碼或者其他個(gè)人信息被曝光)。

一旦登錄完成你將作為已登錄用戶被帶到index頁面。

試試勾選remember_me復(fù)選框。有了這個(gè)選項(xiàng)當(dāng)你在瀏覽器關(guān)閉應(yīng)用后重新打開時(shí),你還是已登錄狀態(tài)。

注銷登錄

我們已經(jīng)實(shí)現(xiàn)了登錄,現(xiàn)在是時(shí)候來實(shí)現(xiàn)注銷登錄了。

注銷登錄的方法灰常簡單(file app/views.py):

@app.route('/logout')

def logout():

logout_user()

return redirect(url_for('index'))

但我們在模板中還沒有注銷登錄的鏈接。我們將在base.html中的頂部導(dǎo)航欄添加這個(gè)鏈接(file app/templates/base.html):

<html>

<head>

{% if title %}

<title>{{title}} - microblog</title>

{% else %}

<title>microblog</title>

{% endif %}

</head>

<body>

<div>Microblog:

<a href="{{ url_for('index') }}">Home</a>

{% if g.user.is_authenticated() %}

| <a href="{{ url_for('logout') }}">Logout</a>

{% endif %}

</div>

<hr>

{% with messages = get_flashed_messages() %}

{% if messages %}

<ul>

{% for message in messages %}

<li>{{ message }} </li>

{% endfor %}

</ul>

{% endif %}

{% endwith %}

{% block content %}{% endblock %}

</body>

</html>

這是多么多么簡單啊,我們只需要檢查一下g.user中是否有一個(gè)有效的用戶,如果有我們就添加注銷鏈接。在我們的模板中我們再一次使用了url_for方法。

更多信息請查看IT技術(shù)專欄

更多信息請查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機(jī)網(wǎng)站地址:Python的Flask框架中實(shí)現(xiàn)簡單的登錄功能的教程
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2026上岸·考公考編培訓(xùn)報(bào)班

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
欧美精品国产精品日韩精品| 欧美高清视频在线 | 欧美肥婆在线| 欧美日韩视频| 国产精品一区二区三区乱码| 一区二区在线视频| 亚洲视频 欧洲视频| 久久av一区二区三区| 欧美+亚洲+精品+三区| 欧美日韩中文另类| 影音先锋久久| 亚洲午夜一区二区| 麻豆成人在线| 国产精品视频xxx| 亚洲美女诱惑| 久久久精品五月天| 欧美日韩系列| 精品二区视频| 亚洲欧美色婷婷| 欧美区视频在线观看| 国产一区二区三区在线免费观看| 亚洲精品日韩欧美| 久久久青草婷婷精品综合日韩| 欧美日韩视频在线第一区| 国内外成人免费激情在线视频| 一区二区欧美日韩视频| 欧美69视频| 国内成人精品一区| 午夜精品电影| 欧美色视频一区| 亚洲国产天堂久久综合网| 久久高清免费观看| 国产精品成人观看视频免费| 亚洲激情在线观看| 久久一区中文字幕| 国产欧美在线观看一区| 亚洲午夜一区二区| 欧美片在线观看| 亚洲精品欧美日韩| 蜜臀久久久99精品久久久久久| 国产综合自拍| 久久精品30| 国产婷婷成人久久av免费高清| 亚洲一区国产精品| 国产精品chinese| 宅男在线国产精品| 国产精品久久久久9999吃药| 在线视频亚洲欧美| 欧美视频一区二区三区| 一区二区三区视频观看| 欧美日韩日本网| 中日韩美女免费视频网址在线观看 | 欧美成人日韩| 亚洲高清不卡| 欧美国产91| 日韩视频在线播放| 欧美日韩卡一卡二| 亚洲视频欧美视频| 国产精品第一区| 亚洲主播在线观看| 国产精品一级久久久| 性色一区二区| 国产在线精品二区| 久久亚洲风情| 最新中文字幕一区二区三区| 欧美精品亚洲二区| 亚洲一区二区伦理| 国产日本欧美一区二区| 久久精品亚洲一区| 91久久亚洲| 欧美亚一区二区| 欧美一级久久久| 尤物精品国产第一福利三区| 欧美成人综合网站| 中文国产成人精品| 国产主播一区二区| 欧美激情视频在线免费观看 欧美视频免费一 | 欧美日韩精品国产| 日韩亚洲欧美成人一区| 国产精品视频一| 久久精品理论片| 亚洲国产高潮在线观看| 欧美日韩另类综合| 欧美一区视频在线| 在线观看国产精品网站| 欧美精品久久久久久久免费观看| 夜夜嗨av一区二区三区网站四季av| 欧美亚日韩国产aⅴ精品中极品| 午夜精品福利一区二区蜜股av| 国内久久视频| 欧美日韩国产精品一区| 午夜国产不卡在线观看视频| 黄色日韩网站| 欧美日精品一区视频| 久久视频在线看| 一区二区三区高清视频在线观看| 国产色婷婷国产综合在线理论片a| 免费久久精品视频| 亚洲欧美清纯在线制服| 亚洲欧洲日产国码二区| 国产欧美日韩精品专区| 欧美精品亚洲精品| 久久精品国产91精品亚洲| 亚洲免费av电影| 影音先锋欧美精品| 国产精品网站视频| 欧美女人交a| 久久野战av| 亚洲制服av| 亚洲毛片在线看| 国产主播精品在线| 国产精品美女在线| 欧美精选在线| 久热这里只精品99re8久| 亚洲欧美国产制服动漫| 亚洲精品免费网站| 亚洲高清不卡| 国产伦精品一区二区三区视频孕妇 | 国产欧美大片| 欧美日本免费| 免费观看亚洲视频大全| 午夜精品亚洲一区二区三区嫩草| 91久久国产精品91久久性色| 国内精品久久久| 国产精品日韩欧美| 欧美日韩视频在线一区二区观看视频 | 国产精品久久久久久模特| 免费不卡欧美自拍视频| 欧美在线播放高清精品| 亚洲私拍自拍| 日韩一级在线| 亚洲激情电影在线| 国产日产欧产精品推荐色 | 欧美精品一区二区三区在线播放| 久久精品99久久香蕉国产色戒| 亚洲欧美国产视频| 亚洲性色视频| aa成人免费视频| 99国产精品久久| 亚洲毛片网站| 亚洲精品日产精品乱码不卡| 亚洲国产精选| 91久久极品少妇xxxxⅹ软件| 影音先锋久久精品| 亚洲电影免费观看高清| 亚洲高清久久网| 亚洲丰满在线| 亚洲国产精品一区二区久| 蜜臀av性久久久久蜜臀aⅴ四虎| 久久久午夜视频| 久久久久国产成人精品亚洲午夜| 久久狠狠一本精品综合网| 欧美在线看片| 久久免费精品日本久久中文字幕| 久久精品一二三| 久久综合狠狠综合久久激情| 欧美aⅴ99久久黑人专区| 欧美大片在线观看| 欧美精品一区二区三区久久久竹菊| 欧美巨乳波霸| 国产精品久久久久影院色老大 | 欧美日韩一区二区三区免费看| 欧美视频手机在线| 国产精品亚洲成人| 国产一区二区精品久久99| 一区二区亚洲精品国产| 亚洲精品久久久久久下一站 | 欧美电影电视剧在线观看| 欧美freesex交免费视频| 欧美久久久久久| 国产精品久久久久久久午夜 | 欧美性猛交99久久久久99按摩| 国产精品露脸自拍| 国产欧美日韩另类一区| 亚洲第一页自拍| 中文无字幕一区二区三区| 欧美一区二区免费视频| 麻豆精品在线视频| 欧美日韩你懂的| 国产亚洲高清视频| 亚洲日本激情| 欧美在线网站| 欧美日韩亚洲综合一区| 国产综合欧美在线看| 日韩一区二区精品| 久久精品国产欧美亚洲人人爽| 欧美大片免费观看| 国产日韩欧美一区二区三区四区| 亚洲激情黄色| 先锋a资源在线看亚洲| 欧美国产欧美亚洲国产日韩mv天天看完整 | 一区二区在线视频播放| 一区二区三区免费观看| 久久国产精品一区二区三区四区| 欧美精品日日鲁夜夜添| 黑人巨大精品欧美一区二区 | 亚洲精选中文字幕| 久久av资源网站| 欧美午夜激情在线| 亚洲精品视频在线观看网站 |