Python:使用 Django 身份驗證系統(tǒng)構(gòu)建身份驗證應(yīng)用程序

我們可以使用 Django 身份驗證系統(tǒng)為我們的項目構(gòu)建身份驗證。

先決條件:

  • Python
  • OOP
  • Django 基礎(chǔ)知識(Django 模板拍摇、視圖亮钦、URL、設(shè)置)

這是 Django文檔中關(guān)于其身份驗證系統(tǒng)的說明:

Django 在其默認(rèn)配置中的身份驗證系統(tǒng)充活。這種配置已經(jīng)發(fā)展到滿足最常見的項目需求蜂莉,處理相當(dāng)廣泛的任務(wù),并仔細(xì)實現(xiàn)了密碼和權(quán)限混卵。對于身份驗證需求與默認(rèn)不同的項目映穗,Django 支持廣泛的身份驗證擴(kuò)展和自定義。

Django 身份驗證同時提供身份驗證和授權(quán)幕随,通常稱為身份驗證系統(tǒng)蚁滋,因為這些功能有些耦合。

我們將使用身份驗證視圖和內(nèi)置表單來創(chuàng)建這個應(yīng)用程序合陵。該應(yīng)用程序?qū)?zhí)行的操作是:

  • 用戶注冊
  • 登錄
  • 登出
  • 密碼更改

設(shè)置

讓我們開始為我們的項目創(chuàng)建一個文件夾,然后我們創(chuàng)建一個虛擬環(huán)境澄阳,并激活它:

mkdir django_authentication
cd django auth
py -m venv venv

cd venv/Scripts
activate

現(xiàn)在我們安裝 Django:

pip install django

我們創(chuàng)建一個 django 項目:

django_admin startproject django_authentication
cd django_authentication

現(xiàn)在我們創(chuàng)建我們的應(yīng)用程序:

py manage.py startapp user_auth

我們必須添加我們的應(yīng)用程序拥知,django_authentication/settings.py并且我們的應(yīng)用程序?qū)⒃谟脩舻卿浕蜃N時重定向用戶的 URL:

settings.py

LOGIN_REDIRECT_URL = '/home'
LOGOUT_REDIRECT_URL = '/home'

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'user_auth',
]

將應(yīng)用添加到 后INSTALLED_APPS,我們在終端中使用以下命令運(yùn)行遷移:

py manage.py migrate

根據(jù)文檔:

當(dāng) django.contrib.auth 在您的 INSTALLED_APPS 設(shè)置中列出時碎赢,它將確保為您安裝的應(yīng)用程序之一中定義的每個 Django 模型創(chuàng)建四個默認(rèn)權(quán)限 - 添加低剔、更改、刪除和查看肮塞。

這些權(quán)限將在您運(yùn)行manage.py migrate 時創(chuàng)建襟齿;在將 django.contrib.auth 添加到 INSTALLED_APPS 后第一次運(yùn)行 migrate 時,將為所有以前安裝的模型以及當(dāng)時正在安裝的任何新模型創(chuàng)建默認(rèn)權(quán)限枕赵。之后猜欺,它會在每次運(yùn)行manage.py migrate 時為新模型創(chuàng)建默認(rèn)權(quán)限(創(chuàng)建權(quán)限的函數(shù)連接到 post_migrate 信號)。

我們將實現(xiàn) Authentication Views 來處理登錄拷窜、注銷和密碼管理开皿,我們需要django.contrib.auth.urls添加django_authentication/urls.py

django_authentication/ urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users', include('django.contrib.auth.urls')),
]

這將包括以下 URL 模式:

users/login/ [name='login']
users/logout/ [name='logout']
users/password_change/ [name='password_change']
users/password_change/done/ [name='password_change_done']
users/password_reset/ [name='password_reset']
users/password_reset/done/ [name='password_reset_done']
users/reset/<uidb64>/<token>/ [name='password_reset_confirm']
users/reset/done/ [name='password_reset_complete']

我們運(yùn)行以下命令來運(yùn)行服務(wù)器:

py manage.py runserver

user_auth目錄中涧黄,我們創(chuàng)建一個文件夾來存儲我們應(yīng)用的模板。

user_auth/
    __init__.py
    admin.py
    apps.py
    migrations/
    models.py
    templates/
        user_auth/
            home.html
            base.html
    tests.py
    urls.py
    views.py

Home

views.py

from django.shortcuts import render

# Create your views here.

def home_page(request):
    return render (request,"user_auth/home.html")

這里我們只寫一個函數(shù)來渲染home.html

我們必須urls.py在我們的應(yīng)用程序目錄中創(chuàng)建一個文件來添加我們將創(chuàng)建的視圖的 URL赋荆。

user_auth/ urls.py

from django.contrib import admin
from django.urls import path, include
from . import views

urlpatterns = [
    path('', views.home_page, name="home"),

]

urls.py現(xiàn)在我們必須在項目文件中包含 user_auth 應(yīng)用程序 URL 笋妥。

django_authentication/ urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users', include('django.contrib.auth.urls')),
    path('home/', include('user_auth.urls')),

]

我們創(chuàng)建了兩個模板。base.html我們將在其中添加將被其他 HTML 文件繼承的 HTML 和 CSS 代碼窄潭。這home.html將是主頁的模板春宣。

base.html


<!doctype html>
<html lang="en">

<div class="topnav">
    <a href="{% url 'home' %}">Home</a>
     {% if user.is_authenticated %}
        <a href="{% url 'logout' %}">Logout</a>
      {% else %}
            <a href="{% url 'login' %}">Login</a>
      {% endif %}  
    <a href="{% url 'signup' %}">SingUp</a>
  </div>

    <div class="container">
        {% block content %}
        {% endblock content %}

    </div>

</body>

<html>

<style type="text/css">

.topnav {
  background-color: #333;
  overflow: hidden;
  position: fixed; 
  top: 0; 
  width: 100%; 
}

.topnav a {
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
  font-family: sans-serif;
}

/* Change the color of links on hover */
.topnav a:hover {
  background-color: #ddd;
  color: black;
}

.topnav a.active {
  background-color: #04AA6D;
  color: white;
}

body {
    background-color: #DEB887;
}
</style>

home.html

{% extends 'user_auth/base.html' %}

{% block content %}

  <body>
      <div class= "greeting">
          <h1>Hello</h1>

        <p> Welcome {{ user.username|default:'' }}, to the Our site</p>
      </div>

  </body>

<style>

 .greeting {
  color: #F0FFFF;
  text-align: center;
  font-family: sans-serif;
 } 

</style>

{% endblock content %}

在 templates/user_auth 中,我們創(chuàng)建了一個名為“registration”的文件夾嫉你。我們在其中創(chuàng)建了一個用于登錄月帝、注冊的模板和一個 form_base 模板。在 form_base 模板中均抽,我們添加了登錄和注冊模板將繼承的 HTML 和 CSS嫁赏。

form_base.html

HTML 和 CSS 是從Dennis Ivy的教程中復(fù)制而來的。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>Django Auth</title>
    <link rel="preconnect" >
    <link rel="preconnect"  crossorigin>
    <link  rel="stylesheet">

    <style>
        body {
            background-color: #DEB887;
            font-family: 'Poppins', sans-serif;
            padding-top: 50px;

        }
        h1,
        h2,
        h3,
        h4,
        h5,
        h6,
            {
            font-family:'Raleway', sans-serif;
        }

        a,
        p {
            color: #4b5156
        }

        .container{
            max-width: 550px;
            margin: auto;
            background-color: #FFEBCD;
            -webkit-box-shadow: 2px 2px 13px -4px rgba(0,0,0,0.21);
            box-shadow: 2px 2px 13px -4px rgba(0,0,0,0.21);

        }
        input {
            outline: none;
            border: none;
        }

        .header-bar {
            display:flex;
            justify-content:space-between;
            color:#fff;
            padding:10px;
            border-radius:5px 5px 0 0;
            background: #5F9EA0;
        }

        .header-bar a {
            color: rgb(247,247,247);
            text-decoration:none;

       }

        input[type=text],
        input[type=password],
        textarea {
            border: 1px solid #757575;
            border-radius: 5px;
            padding: 10px;
            width: 90%;
        }

        label {
            padding-top: 10px !important;
            display: block;
        }

        ::placeholder {
            font-weight: 300;
            opacity: 0.5;
        }

        .button {
            border: 1px solid #757575;
            background-color: #FFF;
            color: #EB796F;
            padding: 10px;
            font-size: 14px;
            border-radius: 5px;
            cursor: pointer;
            text-decoration: none;
        }

        .card-body {
            padding: 20px;
        }

        .topnav {
          background-color: #333;
          overflow: hidden;
          position: fixed; /* Set the navbar to fixed position */
          top: 0; /* Position the navbar at the top of the page */
          width: 100%; /* Full width */
        }

/* Style the links inside the navigation bar */
        .topnav a {
          float: left;
          color: #f2f2f2;
          text-align: center;
          padding: 14px 16px;
          text-decoration: none;
          font-size: 17px;
          font-family: sans-serif;
        }

/* Change the color of links on hover */
.topnav a:hover {
  background-color: #ddd;
  color: black;
}

    </style>

</head>
<body>
    <div class="topnav">
      <a href="{% url 'home' %}">Home</a>
       {% if user.is_authenticated %}
          <a href="{% url 'logout' %}">Logout</a>
        {% else %}
              <a href="{% url 'login' %}">Login</a>
        {% endif %}  
      <a href="{% url 'signup' %}">SingUp</a>
    </div>

    <div class="container">
        {% block content %}
        {% endblock content %}

    </div>

</body>
</html>

報名

Views.py

from django.shortcuts import render
from django.urls import reverse_lazy
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.views.generic.edit import CreateView

...

class SignUp(CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy("login")
    template_name = "user_auth/registration/signup.html"

我們從CreateView. 此類顯示用于創(chuàng)建對象的表單油挥,重新顯示帶有驗證錯誤(如果有的話)的表單潦蝇,并保存對象。對于這個類深寥,我們給UserCreationForm一個值form_class攘乒,這個表單根據(jù)給定的用戶名和密碼創(chuàng)建一個沒有權(quán)限的用戶。

注冊后惋鹅,用戶將被帶到登錄頁面则酝。我們template_name給這個視圖模板的位置作為一個值。

signup.html

{% extends 'user_auth/registration/form_base.html' %}

{% block content %}
<div class="header-bar">
    <h1>Sign Up</h1>
</div>

<div class="card-body">
    <form method="POST">
        {% csrf_token %}
        <label>{{form.username.label}}</label>
        {{form.username}}

        <label>{{form.password1.label}}</label>
        {{form.password1}}

        <label>{{form.password2.label}}</label>
        {{form.password2}}
        <input style="margin-top:10px;" class="button" type="submit" value="Register">
    </form>
    <p>Already have an account?<a href="{% url 'login' %}">Login</a></p>
</div>
{% endblock %}

登錄

from django.shortcuts import render
from django.urls import reverse_lazy
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.views.generic.edit import CreateView

...

class Login(LoginView):
    form_class = AuthenticationForm
    template_name = "user_auth/registration/login.html"

我們從LoginView. 并使用AuthenticationFormas a form_classwhich 是用于登錄用戶的表單闰集。這里我們不定義success_url沽讹,因為它已經(jīng)定義在settings.py.

根據(jù)文檔,這就是LoginView

這是做什么的LoginView

如果通過 GET 調(diào)用武鲁,它會顯示一個 POST 到同一 URL 的登錄表單爽雄。稍后再詳細(xì)介紹。

如果使用用戶提交的憑據(jù)通過 POST 調(diào)用沐鼠,它會嘗試讓用戶登錄挚瘟。如果登錄成功,視圖將重定向到下一個指定的 URL饲梭。如果未提供 next乘盖,它會重定向到 settings.LOGIN_REDIRECT_URL(默認(rèn)為 /accounts/profile/)。如果登錄不成功憔涉,它會重新顯示登錄表單订框。

您有責(zé)任為登錄模板提供 HTML,默認(rèn)情況下稱為registration/login.html兜叨。這個模板被傳遞了四個模板上下文變量:

form:表示 AuthenticationForm 的 Form 對象布蔗。

next:登錄成功后重定向到的 URL藤违。這也可能包含一個查詢字符串。

site:當(dāng)前站點纵揍,根據(jù) SITE_ID 設(shè)置顿乒。如果您沒有安裝站點框架,這將被設(shè)置為 RequestSite 的一個實例泽谨,該實例從當(dāng)前的 HttpRequest 派生站點名稱和域璧榄。

site_name:site.name的別名。如果您沒有安裝站點框架吧雹,這將設(shè)置為 request.META['SERVER_NAME'] 的值骨杂。有關(guān)站點的更多信息,請參閱“站點”框架雄卷。

如果您不想調(diào)用模板registration/login.html搓蚪,您可以通過額外參數(shù)將template_name 參數(shù)傳遞給URLconf 中的as_view 方法。例如丁鹉,此 URLconf 行將使用 myapp/login.html 代替:

path('accounts/login/', auth_views.LoginView.as_view(template_name='myapp/login.html')),

login.html

{% extends 'user_auth/registration/form_base.html' %}

{% block content %}
  <div class="header-bar">
    <h1>Login</h1>
</div>

<div class="card-body">
    <form method="POST">
        {% csrf_token %}
        {{form.as_p}}
        <input class="button" type="submit" value="Login">
    </form>
    <p> Don't have an account?<a href="{% url 'signup' %}">Register</a></p>
</div>

{% endblock %}

密碼更改

views.py

from django.shortcuts import render
from django.urls import reverse_lazy
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, PasswordChangeForm
from django.views.generic.edit import CreateView
from django.contrib.auth.views import LoginView, LogoutView, PasswordChangeView

...

class PasswordChange(PasswordChangeView):
    form_class = PasswordChangeForm
    template_name = "user_auth/registration/password_change_form.html"

PasswordChangeView允許用戶更改此密碼妒潭。這PasswordChangeForm是一種允許用戶更改密碼的表單。

password_change.html

{% extends 'user_auth/registration/form_base.html' %}

{% block content %}
  <div class="header-bar">
    <h1>Password Change</h1>
</div>

<div class="card-body">
    <form method="POST">
        {% csrf_token %}
        {{form.as_p}}
        <input class="button" type="submit" value="Login">
    </form>
</div>

{% endblock %}

home.html

{% extends 'user_auth/base.html' %}

{% block content %}

  <body>
      <div class= "greeting">
        <h1> Welcome {{ user.username|default:'' }}, to the Django Auth site.</h1>
      {% if user.is_authenticated %}
        <p> Change you password<a href="{% url 'password_change' %}"> Here</a></p>
      {% endif %}    
      </div>

  </body>

<style>

 .greeting {

  color: #F0FFFF;
  text-align: center;
  font-family: sans-serif;
 } 

</style>

{% endblock content %}

結(jié)論

Django 允許我們使用其類基礎(chǔ)視圖非常輕松地為我們的項目創(chuàng)建身份驗證揣钦。PasswordResetView 此外雳灾,我們可以使用和使用電子郵件實現(xiàn)密碼重置PasswordResetForm。這是一個優(yōu)勢冯凹,因為它允許我們在應(yīng)用程序的業(yè)務(wù)邏輯上投入更多時間谎亩。

感謝您花時間閱讀這篇文章。

文章來源:https://carlosmv.hashnode.dev/building-an-authentication-app-with-django-authentication-system-python

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宇姚,一起剝皮案震驚了整個濱河市匈庭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浑劳,老刑警劉巖阱持,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異呀洲,居然都是意外死亡紊选,警方通過查閱死者的電腦和手機(jī)啼止,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門道逗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人献烦,你說我怎么就攤上這事滓窍。” “怎么了巩那?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵吏夯,是天一觀的道長此蜈。 經(jīng)常有香客問我,道長噪生,這世上最難降的妖魔是什么裆赵? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮跺嗽,結(jié)果婚禮上战授,老公的妹妹穿的比我還像新娘。我一直安慰自己桨嫁,他們只是感情好植兰,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著璃吧,像睡著了一般楣导。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畜挨,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天筒繁,我揣著相機(jī)與錄音,去河邊找鬼膝晾。 笑死,一個胖子當(dāng)著我的面吹牛务冕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播臊旭,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箩退!你這毒婦竟也來了离熏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤戴涝,失蹤者是張志新(化名)和其女友劉穎滋戳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啥刻,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡奸鸯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了可帽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娄涩。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖映跟,靈堂內(nèi)的尸體忽然破棺而出蓄拣,到底是詐尸還是另有隱情扬虚,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布球恤,位于F島的核電站辜昵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏咽斧。R本人自食惡果不足惜路鹰,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望收厨。 院中可真熱鬧晋柱,春花似錦、人聲如沸诵叁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拧额。三九已至碑诉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侥锦,已是汗流浹背进栽。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留恭垦,地道東北人快毛。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像番挺,于是被迫代替她去往敵國和親唠帝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

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

  • Django提供了一套身份驗證和授權(quán)的權(quán)限系統(tǒng)玄柏,允許驗證用戶憑證襟衰,并定義每個用戶允許執(zhí)行的操作。 權(quán)限系統(tǒng)框架包括...
    JunChow520閱讀 605評論 0 0
  • 一.用戶賬戶介紹 Web應(yīng)用程序的核心是讓任何用戶都能夠注冊賬戶并能夠使用它粪摘,不管用戶身處何方瀑晒。在本章中,你將創(chuàng)建...
    只是甲閱讀 336評論 0 0
  • 19.2 創(chuàng)建用戶賬戶 這一節(jié)徘意,我們將簡歷一個用戶注冊和身份驗證系統(tǒng)苔悦,讓用戶能夠注冊賬戶,進(jìn)而登錄和注銷映砖。我們將創(chuàng)...
    Blue_Eye閱讀 1,281評論 0 1
  • 1. 讓用戶能夠輸入數(shù)據(jù) 添加幾個頁面间坐,讓用戶能夠輸入數(shù)據(jù)灾挨,能夠添加新主題邑退,添加新條目以及編輯既有條目 只有超級用...
    YangDxg閱讀 407評論 0 1
  • 您是否使用 Django 開發(fā)了 Web 應(yīng)用程序并考慮將其擴(kuò)展到 android 應(yīng)用程序竹宋? 那么你就在完美的地...
    蝸牛是不是牛閱讀 572評論 0 0