Django社交網(wǎng)絡(luò)

使用Django認(rèn)證(authentication)框架

Django擁有一個內(nèi)置的認(rèn)證(authentication)框架用來操作用戶認(rèn)證(authentication)聊浅,會話(sessions)饼灿,權(quán)限(permissions)以及用戶組涉馅。

這個認(rèn)證(authentication)系統(tǒng)包含了一些普通用戶操作視圖(views)湃鹊,例如:登錄瘸恼,登出,修改密碼以及重置密碼讲逛。


這個認(rèn)證(authentication)系統(tǒng)還包含了以下模型(models):

User:一個包含了基礎(chǔ)字段的用戶模型(model)匣摘;這個模型(model)的主要字段有:username店诗, password, email, first_name, last_name, is_active。

Group:一個組模型(model)用來分類用戶

Permission:執(zhí)行特定操作的標(biāo)識


這個框架還包含默認(rèn)的認(rèn)證(authentication)視圖(views)和表單(forms)音榜,我們之后會用到庞瘸。

注:請注意authenticationlogin中的不同點:authenticate()檢查用戶認(rèn)證信息,如果用戶是正確的則返回一個用戶對象赠叼;login()將用戶設(shè)置到當(dāng)前的會話(session)中擦囊。


使用Django認(rèn)證(authentication)視圖(views)

Django在認(rèn)證(authentication)框架中包含了一些開箱即用的:表單(forms)和視圖(views)。

你之前創(chuàng)建的登錄視圖(view)是一個非常好的練習(xí)用來理解Django中的用戶認(rèn)證(authentication)過程梅割。無論如何霜第,你可以在大部分的案例中使用默認(rèn)的Django認(rèn)證(authentication)視圖(views)葛家。


Django提供以下視圖(views)來處理認(rèn)證(authentication)

login:操作表單(form)中的登錄然后登錄一個用戶

logout:登出一個用戶

logout_then_login:登出一個用戶然后重定向這個用戶到登錄頁面


Django提供以下視圖(views)來操作密碼修改

password_change:操作一個表單(form)來修改用戶密碼

password_change_done:當(dāng)用戶成功修改他的密碼后提供一個成功提示頁面


Django還包含了以下視圖(views)允許用戶重置他們的密碼:

password_reset:允許用戶重置他的密碼户辞。它會生成一條帶有一個token的一次性使用鏈接然后發(fā)送到用戶的郵箱中

password_reset_done:告知用戶已經(jīng)發(fā)送了一封可以用來重置密碼的郵件到他的郵箱中癞谒。

password_reset_complete:當(dāng)用戶重置完成他的密碼后提供一個成功提示頁面底燎。


? ? ? ? 在你的account應(yīng)用中的template目錄下創(chuàng)建一個新的目錄命名為registration。這個路徑是Django認(rèn)證(authentication)視圖(view)期望你的認(rèn)證(authentication)模塊(template)默認(rèn)的存放路徑弹砚。


用戶登錄

<div>

????????<form action={% url "login" %} method="post">

????????????????{{ form.as_p }}

? ? ? ? ? ? ? ? {% csrf_token %}

? ? ? ? ? ? ? ? <input type="hidden" name="next" value="{{ next }}"/>

? ? ? ? ? ? ? ? <p><input type="submit" value="登錄"></p>

????????</form>

</div>

Django默認(rèn)使用位于django.contrib.auth.forms中的AuthenticationForm双仍。這個表單(form)會嘗試對用戶進行認(rèn)證,如果登錄不成功就會拋出一個驗證錯誤桌吃。如果提供了錯誤的認(rèn)證信息朱沃,我們可以在模板(template)中使用{% if form.errors %}來找到錯誤。

注意:

? ? ? (1).我們添加了一個隱藏的HTML元素來提交叫做next的變量值。當(dāng)你在請求(request)中傳遞一個next參數(shù)(舉個例子:http://127.0.0.1:8000/account/login/?next=/account/)逗物,這個變量是登錄視圖(view)首個設(shè)置的參數(shù)搬卒。next參數(shù)必須是一個URL。當(dāng)這個參數(shù)被給予的時候翎卓,Django登錄視圖(view)將會在用戶登錄完成后重定向到給予的URL契邀。

? ? (2).在我們的地址配置中所包含的logtou_then_login視圖(view)不需要任何模板(template),因為它執(zhí)行了一個重定向到登錄視圖(view)失暴。

????(3).login_required裝飾器(decorator)會檢查當(dāng)前用戶是否通過認(rèn)證坯门,如果用戶沒有通過認(rèn)證,它會把用戶重定向到帶有一個名為next的GET參數(shù)的登錄URL逗扒,該GET參數(shù)保存的變量為用戶當(dāng)前嘗試訪問的頁面URL古戴。


from django.core.urlresolvers import reverse_lazy

LOGIN_REDIRECT_URL = reverse_lazy('dashboard')

LOGIN_URL = reverse_lazy('login')

LOGOUT_URL = reverse_lazy('logout')

這些設(shè)置的意義:

LOGIN_REDIRECT_URL:告訴Django用戶登錄成功后如果contrib.auth.views.login視圖(view)沒有獲取到next參數(shù)將會默認(rèn)重定向到哪個URL。

LOGIN_URL:重定向用戶登錄的URL(例如:使用login_required裝飾器(decorator))缴阎。

LOGOUT_URL:重定向用戶登出的URL允瞧。

????????我們使用reverse_lazy()來通過它們的名字動態(tài)構(gòu)建URL。reverse_lazy()方法就像reverse()所做的一樣reverses URLs蛮拔,但是你可以通過使用這種方式在你項目的URL配置被讀取之前進行reverse URLs述暂。


????????通過認(rèn)證(authentication)中間件當(dāng)前的用戶被設(shè)置在HTTP請求(request)對象中。你可以通過使用request.user訪問用戶信息建炫。你會發(fā)現(xiàn)一個用戶對象在請求(request)中畦韭,即便這個用戶并沒有認(rèn)證通過。一個未認(rèn)證的用戶在請求(request)中被設(shè)置成一個AnonymousUser的實例肛跌。一個最好的方法來檢查當(dāng)前的用戶是否通過認(rèn)證是通過調(diào)用request.user.is_authenticated()艺配。

如果在你的登出頁面中看到了Django管理站點的登出頁面,檢查項目settings.py中的INSTALLED_APPS,確保django.contrib.admin在account應(yīng)用的后面


修改密碼視圖(views)

password_change視圖(view)將會操作表單(form)進行修改密碼衍慎,當(dāng)用戶成功的修改他的密碼后password_change_done將會顯示一條成功信息转唉。

password_reset_email.html(渲染發(fā)送給用戶的重置密碼郵件)

Someone asked for password reset for email {{ email }}. Follow the link below:

{{ protocol }}://{{ domain }}{% url "password_reset_confirm" uidb64=uid token=token %}

Your username, in case you've forgotten: {{ user.get_username }}


再創(chuàng)建另一個模板(template)password_reset_confirm.html,為它添加如下代碼:

{% block content %}

????????Reset your password

????????????{% if validlink %}

????????????????????????Please enter your new password twice:

????????????????????????{{ form.as_p }}

????????????????????????{% csrf_token %}

????????????????????????<input type="submit" value="修改密碼">

????????????{% else %}

????????????????????The password reset link was invalid, possibly because it has already been used. Please request a new password reset.

????????????{% endif %}

{% endblock %}

在以上模板中稳捆,我們將會檢查重置鏈接是否有效赠法。Django重置密碼視圖(view)會設(shè)置這個變量然后將它帶入這個模板(template)的上下文環(huán)境中。如果重置鏈接有效乔夯,我們展示用戶密碼重置表單(form)砖织。


用戶注冊

Django還提供一個UserCreationForm表單(form)給你使用,它位于django.contrib.auth.forms非常類似與我們剛才創(chuàng)建的表單(form)末荐。

編輯他們的pfofile:

? ??????user_form = UserEditForm(instance=request.user,data=request.POST)


使用一個定制User模型(model)

????????Django還提供一個方法可以使用你自己定制的模型(model)來替代整個User模型(model)侧纯。你自己的用戶類需要繼承Django的AbstractUser類,這個類提供了一個抽象的模型(model)用來完整執(zhí)行默認(rèn)用戶


使用messages框架

當(dāng)處理用戶的操作時甲脏,你可能想要通知你的用戶關(guān)于他們操作的結(jié)果眶熬。Django有一個內(nèi)置的messages框架允許你給你的用戶顯示一次性的提示妹笆。

messages框架提供了一個簡單的方法添加消息給用戶。消息被存儲在數(shù)據(jù)庫中并且會在用戶的下一次請求中展示娜氏。你可以在你的視圖(views)中導(dǎo)入messages模塊來使用消息messages框架晾浴,用簡單的快捷方式添加新的messages

from django.contrib import messages

messages.error(request, 'Something went wrong')

你可以使用add_message()方法創(chuàng)建新的messages或用以下任意一個快捷方法:

success():當(dāng)操作成功后顯示成功的messages

info():展示messages

warning():某些還沒有達到失敗的程度但已經(jīng)包含有失敗的風(fēng)險,警報用

error():操作沒有成功或者某些事情失敗

debug():在生產(chǎn)環(huán)境中這種messages會移除或者忽略


創(chuàng)建一個定制的認(rèn)證(authentication)后臺

Django允許你通過不同的來源進行認(rèn)證(authentication)牍白。AUTHENTICATION_BACKENDS設(shè)置包含了所有的給你的項目的認(rèn)證(authentication)后臺脊凰。

1.('django.contrib.auth.backends.ModelBackend',)---默認(rèn)的ModelBackend通過數(shù)據(jù)庫使用django.contrib.auth中的User模型(model)來認(rèn)證(authentication)用戶。

2.當(dāng)你使用django.contrib.auth的authenticate()函數(shù)茂腥,Django會通過每一個定義在AUTHENTICATION_BACKENDS中的后臺一個接一個地嘗試認(rèn)證(authentication)用戶狸涌,直到其中有一個后臺成功的認(rèn)證該用戶才會停止進行認(rèn)證。只有所有的后臺都無法進行用戶認(rèn)證(authentication)最岗,他或她才不會在你的站點中通過認(rèn)證(authentication)帕胆。


Django提供了一個簡單的方法來定義你自己的認(rèn)證(authentication)后臺。一個認(rèn)證(authentication)后臺就是提供了如下兩種方法的一個類:

authenticate():將用戶信息當(dāng)成參數(shù)般渡,如果用戶成功的認(rèn)證(authentication)就需要返回True懒豹,反之,需要返回False驯用。

get_user():將用戶的ID當(dāng)成參數(shù)然后需要返回一個用戶對象

創(chuàng)建一個定制認(rèn)證(authentication)后臺非常容易,就是編寫一個Python類實現(xiàn)上面兩個方法。我們要創(chuàng)建一個認(rèn)證(authentication)后臺讓用戶在我們的站點中使用他們e-mail替代他們的用戶名來進行認(rèn)證(authentication)固惯。

class EmailAuthBackend(object):

????????def authenticate(self, username=None, password=None):

????????????????try:

????????????????????????user = User.objects.get(email=username)

????????????????????????if user.check_password(password):

????????????????????????????????return user

????????????????????????return None

????????????????except User.DoesNotExist:

????????????????????????return None

????????def get_user(self, user_id):

????????????????try:

????????????????????????return User.objects.get(pk=user_id)

????????????????except User.DoesNotExist:

????????????????????????return None

authenticate():我們嘗試通過給予的e-mail地址獲取一個用戶和使用User模型(model)中內(nèi)置的check_password()方法來檢查密碼。這個方法會對給予密碼進行哈系裱兀化來和數(shù)據(jù)庫中存儲的加密密碼進行匹配审轮。

get_user():我們通過user_id參數(shù)獲取一個用戶断国。Django使用這個后臺來認(rèn)證用戶之后取回User對象放置到持續(xù)的用戶會話中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坐漏,一起剝皮案震驚了整個濱河市赊琳,隨后出現(xiàn)的幾起案子躏筏,更是在濱河造成了極大的恐慌,老刑警劉巖埃碱,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酥泞,死亡現(xiàn)場離奇詭異芝囤,居然都是意外死亡,警方通過查閱死者的電腦和手機羡藐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門传睹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欧啤,“玉大人邢隧,你說我怎么就攤上這事倒慧∪伊拢” “怎么了溅固?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵侍郭,是天一觀的道長。 經(jīng)常有香客問我猛计,道長唠摹,這世上最難降的妖魔是什么奉瘤? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮盗温,結(jié)果婚禮上望艺,老公的妹妹穿的比我還像新娘肌访。我一直安慰自己找默,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布吼驶。 她就那樣靜靜地躺著,像睡著了一般蟹演。 火紅的嫁衣襯著肌膚如雪酒请。 梳的紋絲不亂的頭發(fā)上羞反,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天昼窗,我揣著相機與錄音,去河邊找鬼。 笑死掸驱,一個胖子當(dāng)著我的面吹牛肛搬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毕贼,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼温赔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了帅刀?” 一聲冷哼從身側(cè)響起让腹,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扣溺,沒想到半個月后骇窍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡锥余,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年腹纳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驱犹。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘲恍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雄驹,到底是詐尸還是另有隱情佃牛,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布医舆,位于F島的核電站俘侠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蔬将。R本人自食惡果不足惜爷速,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望霞怀。 院中可真熱鬧惫东,春花似錦、人聲如沸毙石。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徐矩。三九已至废封,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丧蘸,已是汗流浹背漂洋。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留力喷,地道東北人刽漂。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像弟孟,于是被迫代替她去往敵國和親贝咙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容