1. 程式人生 > 其它 >什麼是Auth模組?(全面瞭解)

什麼是Auth模組?(全面瞭解)

目錄

一:Auth模組

1.什麼是Auth模組?

Auth模組是Django自帶的使用者認證模組:

1.我們在開發一個網站的時候,無可避免的需要設計實現網站的使用者系統。此時我們需要實現包括使用者註冊、使用者登入、使用者認證、登出、修改密碼等功能,這還真是個麻煩的事情呢。

2.Django作為一個完美主義者的終極框架,當然也會想到使用者的這些痛點。它內建了強大的使用者認證系統–auth,它預設使用 auth_user 表來儲存使用者資料。
2.Auth模組作用
1 django提供的使用者認證,建立,修改密碼。。。使用者相關操作
2 不需要建立使用者表了,預設帶了
3 插入資料(建立使用者):
    python3 manage.py createsuperuser

二:引入Auth模組

1.其實我們在建立好一個Django專案之後直接執行資料庫遷移命令會自動生成很多表
列如:
	django_session
	auth_user
2.django在啟動之後就可以直接訪問admin路由,需要輸入使用者名稱和密碼,資料參考的就是auth_user表,並且還必須是管理員使用者才能進入
3.建立超級使用者(管理員)
python3 manage.py createsuperuser
4.Django自帶的admin後端管理
5.需求
  • 依賴於auth_user表完成使用者相關的所有功能
6.方法總結

問題(1.表如何獲取 2.密碼如何比對 儲存表中密碼是密文的)

三:解決方法(auth模組)

1.自動查詢auth_user標籤
2.自動給密碼加密再比對
該方法注意事項:
	括號內必須同時傳入使用者名稱和密碼
	不能只傳使用者名稱(一步就幫你篩選出使用者物件)
1.比對使用者名稱和密碼是否正確
# 匯入auth模組
from django.contrib import auth

# 1.比對使用者名稱和密碼是否正確
user_obj = auth.authenticate(request,username=username,password=password)
# 括號內必須同時傳入使用者名稱和密碼
print(user_obj)  # 使用者物件  jason   資料不符合則返回None
print(user_obj.username)  # jason
print(user_obj.password)  # 密文
2.儲存使用者狀態
auth.login(request,user_obj)  # 類似於request.session[key] = user_obj
# 主要執行了該方法 你就可以在任何地方通過request.user獲取到當前登陸的使用者物件
3.獲取當前登陸使用者
print(request.user)  # 使用者物件   沒登陸拿到的是匿名使用者 AnonymousUser
# 自動去django_session裡面查詢對應的使用者物件給你封裝到request.user中
4.判斷當前使用者是否登陸
request.user.is_authenticated()
5.校驗使用者是否登陸裝飾器
from django.contrib.auth.decorators import login_required

# 區域性配置
@login_required(login_url='/login/') 

# 全域性配置settings內
LOGIN_URL = '/login/'

1.如果區域性和全域性都有 該聽誰的?
區域性 > 全域性
2.區域性和全域性哪個好呢?
全域性的好處在於無需重複寫程式碼 但是跳轉的頁面卻很單一
區域性的好處在於不同的檢視函式在使用者沒有登陸的情況下可以跳轉到不同的頁面
6.比對原密碼
# 校驗老密碼  check_password 原密碼
# 返回值就是一個布林值
is_right = request.user.check_password(old_password)  # 自動加密比對密碼
7.修改密碼
# 判斷原密碼正常為True 原密碼錯誤為False
if is_right:
    # 修改密碼
    request.user.set_password(new_password)  # 添入新密碼(僅僅修改物件的屬性)
    request.user.save()  # 操作資料庫
return redirect('/login/')
8.登出
auth.logout(request)  # 類似於 request.session.flush()
9.註冊
1.操作auth_user表寫入資料
User.objects.create(username=username,password=password)  # 寫入資料  不能用create 密碼沒有加密處理

2.建立普通使用者  # 加密處理
User.objects.create_user(username=username,password=password)

3.建立超級使用者(瞭解):使用程式碼建立超級使用者 郵箱是必填的 而用命令建立則可以不填
User.objects.create_superuser(username=username,email='[email protected]',password=password)
10.整體程式碼
###### 10.整體程式碼

```python
# views.py

from django.shortcuts import render, HttpResponse, redirect


from django.contrib import auth
#登陸
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 去使用者表中效驗資料
        # 1.表如何獲取
        # 2.密碼如何比對 儲存表中密碼是密文的
        # 使用auth模組
        user_obj = auth.authenticate(request, username=username, password=password)
        # 判斷當前使用者是否存在
        if user_obj:
            # 儲存使用者狀態(利用auth操作session表)
            auth.login(request, user_obj)  # 類似於request.session[key] = user_obj  將使用者物件存到session表內

    return render(request, 'login.html')


from django.contrib.auth.decorators import login_required


# 主頁

# 區域性配置: 使用者沒有登陸跳轉到login_user後面指定的網址
# @login_required(login_url='/login/')  # 優先順序 區域性 大於 全域性
@login_required
def home(request):
    print(request.user)  # 使用者物件   沒登陸拿到的是匿名使用者 AnonymousUser
    # 判斷使用者是否登陸
    print(request.user.is_authenticated())
    # 自動去django_session裡面查詢對應的使用者物件給你封裝到request.user中
    return HttpResponse('home')


@login_required
def index(request):
    return HttpResponse('index')

# 修改
@login_required
def set_password(request):
    if request.method == 'POST':
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        confirm_password = request.POST.get('confirm_password')
        # 校驗兩次密碼是否一致
        if new_password == confirm_password:
            # 校驗老密碼  check_password 原密碼
            # 返回值就是一個布林值
            is_right = request.user.check_password(old_password)  # 自動加密比對密碼
            # 判斷原密碼正常為True 原密碼錯誤為False
            if is_right:
                # 修改密碼
                request.user.set_password(new_password)  # 添入新密碼(僅僅修改物件的屬性)
                request.user.save()  # 操作資料庫
        return redirect('/login/')
    return render(request, 'set_password.html', locals())

# 登出
@login_required
def logout(request):
    auth.logout(request)  # 類似於 request.session.flush()
    return redirect('/login/')


from django.contrib.auth.models import User

# 註冊
@login_required
def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 操作auth_user表寫入資料
        # User.objects.create(username=username, password=password)  # 寫入資料 不能使用create 密碼沒有加密處理
        # 建立普通使用者 加密處理
        User.objects.create_user(username=username, password=password)
    return render(request, 'registration.html')


# settings.py

# 全域性配置 沒有登陸跳轉到指定頁面
LOGIN_URL = '/login/'


# urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 1.登陸功能
    url(r'^login/', views.login),
    # 2.主頁(校驗使用者是否登陸)
    url(r'^home/', views.home),
    url(r'^index/', views.index),
    # 3.修改密碼
    url(r'^set_password/', views.set_password),
    # 4.登出功能
    url(r'^logout/', views.logout),
    # 5.註冊功能
    url(r'^register/', views.register),
]

# login.html

<form action="" method="post">
    {% csrf_token %}
    <p>username: <input type="text" name="username"></p>
    <p>password: <input type="text" name="password"></p>
    <input type="submit">
</form>

# registration.html

<form action="" method="post">
    {% csrf_token %}
    <h1>註冊</h1>
    <p>username: <input type="text" name="username"></p>
    <p>password: <input type="text" name="password"></p>
    <input type="submit">
</form>

# set_password.html

<form action="" method="post">
    {% csrf_token %}
    {# disabled 只能看 不能改   #}
    <p>username: <input type="text" name="username" disabled value="{{ request.user.username }}"></p>
    <p>old_password: <input type="text" name="old_password"></p>
    <p>new_password: <input type="text" name="new_password"></p>
    <p>confirm_password: <input type="text" name="confirm_password"></p>
    <input type="submit">
</form>

四:如何擴充套件auth_user表

1.需求:
  • 擴充套件auth_user欄位
2.如果繼承了AbstractUser會如何?
1.那麼在執行資料庫遷移命令的時候auth_user表就不會再創建出來了
2.而userInfo表中出現auth_user所有的欄位外加自己擴充套件的欄位
3.優點
1.這麼做的好處在於你能夠直接點選你自己的表更加快速的完成操作及擴充套件
4.實現該方法前提:
1.在繼承之前沒有執行過資料庫遷移命令(auth_user沒有被建立)
如果當前庫已經建立了,那麼你就重新換一個庫
2.繼承的類裡面不要覆蓋AbstractUser裡面的欄位名
表裡面有的欄位都不要動,只擴充套件額外欄位即可
3.需要在配置檔案中告訴Django你要用UserInfo替代auth_user
AUTH_USER_MODEL = 'app01.UserInfo'
直接應用名點表名即可
5.擴充套件auth_user欄位實踐
  • models
from django.db import models
from django.contrib.auth.models import User, AbstractUser

# User繼承了AbstractUser, auth_user內的欄位來自AbstractUser類

# 1.利用面向物件的繼承
class UserInfo(AbstractUser):
    phone = models.BigIntegerField()
6.實現擴充套件
1.__init__.py
# 切換到pymysql
import pymysql
pymysql.install_as_MySQLdb()

2.配置檔案settings更改資料庫mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day00',
        'USER': 'root',
        'PASSWORD': '123',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'CHARSET': 'utf8',
    }
}

3.auth表配置
AUTH_USER_MODEL = 'app01.UserInfo'

4.資料庫遷移
makemigrations

# 同步
migrate
7.總結:
你如果自己寫表替代了auth_user那麼
auth模組的功能還是照常使用,參考的表頁由原來的auth_user變成了UserInfo