Django 的登錄登出功能

CSRF跨域請(qǐng)求保護(hù)

A站為正常網(wǎng)站,B站為病毒網(wǎng)站,當(dāng)我先訪問(wèn)A站,本地瀏覽器會(huì)記錄cookies在本地,之后訪問(wèn)B站,B站會(huì)竊取我的cookies,然后通過(guò)我的cookies就可以冒名訪問(wèn)A站中我的賬戶。這就是CSRF跨站請(qǐng)求偽造攻擊。

Djangoform表單提交時(shí),如果是POST方法提交,會(huì)引發(fā)CSRF跨域請(qǐng)求保護(hù),解決方法為:在form表單中添加{% csrf_token %},打開網(wǎng)站就會(huì)在頁(yè)面生成token(令牌)來(lái)進(jìn)行認(rèn)證,當(dāng)別人登錄會(huì),頁(yè)面會(huì)生成完全不一樣的token,登錄時(shí)抓包會(huì)發(fā)現(xiàn)提交的form表單中會(huì)有csrfmiddlewaretoken這么一項(xiàng)。

HTML 的登錄表單

<!-- html中的登錄表單-->
<form class="form-signin" role="form" method="post" action="{% url 'login' %}">
    {% csrf_token %}
    <h2 class="form-signin-heading">Please sign in</h2>
    <input name="username" type="email" class="form-control" placeholder="Email address" required="" autofocus="">
    <input name="password" type="password" class="form-control" placeholder="Password" required="">
    
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    <span style="color: red" >{{ login_err }}</span>
</form>

登錄功能的實(shí)現(xiàn)

當(dāng)點(diǎn)擊登錄時(shí),會(huì)將表單提交到urls.py中的別名為loginurl來(lái)處理,如:

...
urlpatterns = [
    ...
    url(r'^login/', views.login_site, name='login'),
    url(r'^logout/', views.logout_site, name='logout'),
]

處理邏輯為:如果方式為Post,獲取到提交的usernamepassword,然后通過(guò)djangoauthenticate方法來(lái)驗(yàn)證。

# 導(dǎo)入的login 和 logout 用來(lái)實(shí)現(xiàn)保持session
from django.contrib.auth import authenticate, login, logout

def login_site(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)   # 使用 Django 的 authenticate 方法來(lái)驗(yàn)證
        if user:
            login(request, user)    # <==
            return HttpResponseRedirect('/')
        else:
            return render(request, 'login.html', {
                'login_err': 'Please recheck your username or password !'
            })
    return render(request, 'login.html')

登出功能

def logout_site(request):
    logout(request)     # <==
    return HttpResponseRedirect('/')

HTML 頁(yè)面驗(yàn)證是否登錄

頁(yè)面中需要根據(jù)是否登錄來(lái)顯示登錄狀態(tài),登錄顯示登錄的用戶名,未登錄顯示login

...
<ul class="nav navbar-nav navbar-right">
    <!-- 驗(yàn)證是否已經(jīng)登錄-->
    <!-- 如果沒(méi)有登錄,則展示登錄鏈接-->
    {% if not request.user.is_authenticated %}
    <li>
        <a href="{% url 'login' %}">Login</a>
    </li>
    {% else %}  
    <!-- 如果已經(jīng)登錄,則展示用戶名和下拉菜單-->
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">{{ request.user.name }}<span class="caret"></span></a>
        <ul class="dropdown-menu" role="menu">
            <li><a href="#">個(gè)人信息</a></li>
            <li class="divider"></li>
            <li><a href="{% url 'logout' %}">Logout</a></li>
        </ul>
    </li>
    {% endif %}
</ul>
...

強(qiáng)制登錄

網(wǎng)站很多頁(yè)面我們需要用戶登錄才能展示,或者說(shuō)打開網(wǎng)站時(shí),必須先登錄。可以進(jìn)行如下兩步設(shè)置:

第一步:在settings.py文件中寫明當(dāng)用戶未登錄就訪問(wèn)網(wǎng)站時(shí)的跳轉(zhuǎn)路徑。

# settings.py 文件中
LOGIN_URL = '/login/'

第二步:在需要登錄才能打開的頁(yè)面中使用login_required裝飾器

from django.contrib.auth.decorators import login_required

@login_required
def dashboard(request):
    return render(request, 'dashboard.html')
...
...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容