1. 程式人生 > 實用技巧 >Django中的auth模組

Django中的auth模組

一、Django自帶的使用者認證-auth模組


  1.auth模組簡介

  網站開發過程中,我們需要設計實現網站的使用者系統。此時我們需要實現包括使用者註冊、使用者登入、使用者認證、登出、修改密碼等功能。Flask框架中我們需要手動的建立User模型,然後逐步實現驗證方法,但Django框架內建了強大的使用者認證系統--auth,它預設使用 auth_user 表來儲存使用者資料。auth模組是對登入認證方法的一種封裝,之前我們獲取使用者輸入的使用者名稱及密碼後需要自己從user表裡查詢有沒有使用者名稱和密碼符合的物件,而有了auth模組之後就可以很輕鬆的去驗證使用者的登入資訊是否存在於資料庫中。除此之外,auth還對session做了一些封裝,方便我們校驗使用者是否已登入。如果需要個性化的User模型,你自己的模型只需要繼承User類,就可以實現auth一樣的驗證方法。

2.auth裡的常用方法

  如果想使用auth模組的方法,必須要先匯入auth模組

from django.contrib import auth

  django.contrib.auth中提供了許多方法,這裡主要介紹其中的四個:

  1 、authenticate()

    提供了使用者認證,即驗證使用者名稱以及密碼是否正確,一般需要username password兩個關鍵字引數

    如果認證資訊有效,會返回一個 User 物件。authenticate()會在User 物件上設定一個屬性標識那種認證後端認證了該使用者,且該資訊在後面的登入過程中是需要的。當我們試圖登陸一個從資料庫中直接取出來不經過authenticate()的User物件會報錯的.

user = authenticate(username='someone',password='somepassword')

  2 、login(HttpRequest, user)

    該函式接受一個HttpRequest物件,以及一個認證了的User物件,此函式會使用django的session框架給某個已認證的使用者附加上session id等資訊。

 1 from django.contrib.auth import authenticate, login
 2    
 3 def my_view(request):
 4   username = request.POST['
username'] 5 password = request.POST['password'] 6 user = authenticate(username=username, password=password) 7 if user is not None: 8 login(request, user) 9 # Redirect to a success page. 10 ... 11 else: 12 # Return an 'invalid login' error message. 13 ...

3 、logout(request) 登出使用者

該函式接受一個HttpRequest物件,無返回值。當呼叫該函式時,當前請求的session資訊會全部清除。該使用者即使沒有登入,使用該函式也不會報錯。

1 from django.contrib.auth import logout
2    
3 def logout_view(request):
4   logout(request)
5  # Redirect to a success page.

4 、user物件的 is_authenticated()

要求:

1 使用者登陸後才能訪問某些頁面,

2 如果使用者沒有登入就訪問該頁面的話直接跳到登入頁面

3 使用者在跳轉的登陸介面中完成登陸後,自動訪問跳轉到之前訪問的地址

方法1:直接用auth的is_authenticated()方法驗證

def my_view(request):
   if not request.user.is_authenticated():
      return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

   方法2: 根據request.user.username來驗證,如果為空,則說明沒有登入

1 def my_view(request):
2    if not request.user.username:
3       return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

方法3:django已經為我們設計好了一個用於此種情況的裝飾器:login_requierd()

1 from django.contrib.auth.decorators import login_required
2     
3 @login_required
4 def my_view(request):
5      pass

若使用者沒有登入,則會跳轉到django預設的 登入URL '/accounts/login/ ' (這個值可以在settings檔案中通過LOGIN_URL進行修改)。並傳遞當前訪問url的絕對路徑 ( 登陸成功後,會重定向到該路徑 )。

3. user物件

User 物件屬性:username, password(必填項)password用雜湊演算法儲存到資料庫

is_staff : 使用者是否擁有網站的管理許可權.

is_active : 是否允許使用者登入, 設定為``False``,可以不用刪除使用者來禁止 使用者登入

4、is_authenticated()

如果是真正的 User 物件,返回值恆為 True 。 用於檢查使用者是否已經通過了認證。

通過認證並不意味著使用者擁有任何許可權,甚至也不檢查該使用者是否處於啟用狀態,這只是表明使用者成功的通過了認證。 這個方法很重要, 在後臺用request.user.is_authenticated()判斷使用者是否已經登入,如果true則可以向前臺展示request.user.name

5、建立使用者

使用 create_user 輔助函式建立使用者:

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email=''

6 、check_password(passwd) 檢驗密碼

user = User.objects.get(username=' ')
if user.check_password(passwd):
  pass

使用者需要修改密碼的時候 首先要讓他輸入原來的密碼 ,如果給定的字串通過了密碼檢查,返回 True使用 set_password() 來修改密碼

user = User.objects.get(username='')
password = request.Post.get('password')
 if user.check_password(password):
    user.set_password(password=''):
    user.save 
else: 
    return HttpResponse('密碼錯誤')

7、註冊

def sign_up(request):
  
  state = None
  if request.method == 'POST':
  
    password = request.POST.get('password', '')
    repeat_password = request.POST.get('repeat_password', '')
    email=request.POST.get('email', '')
    username = request.POST.get('username', '')
    if User.objects.filter(username=username):
        state = 'user_exist'
    else:
        new_user = User.objects.create_user(username=username, password=password,email=email)
        new_user.save()
  
        return redirect('/book/')
  content = {
    'state': state,
    'user': None,
  }
  return render(request, 'sign_up.html', content) 

8、修改密碼

@login_required
def set_password(request):
  user = request.user
  state = None
  if request.method == 'POST':
    old_password = request.POST.get('old_password', '')
    new_password = request.POST.get('new_password', '')
    repeat_password = request.POST.get('repeat_password', '')
    if user.check_password(old_password):
      if not new_password:
        state = 'empty'
      elif new_password != repeat_password:
        state = 'repeat_error'
      else:
        user.set_password(new_password)
        user.save()
        return redirect("/log_in/")
    else:
      state = 'password_error'
  content = {
    'user': user,
    'state': state,
  }
  return render(request, 'set_password.html', content)

2.2 、建立使用者

使用 create_user 輔助函式建立使用者:

1 2 from django.contrib.auth.models import User user = User.objects.create_user(username='',password='',email='')

2.3 、check_password(passwd)

1 2 3 user = User.objects.get(username=' ') if user.check_password(passwd): ......

使用者需要修改密碼的時候 首先要讓他輸入原來的密碼 ,如果給定的字串通過了密碼檢查,返回 True

使用 set_password() 來修改密碼

1 2 3 user = User.objects.get(username='') user.set_password(password='') user.save 

2.5 、簡單示例

註冊:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def sign_up(request): state = None if request.method == 'POST': password = request.POST.get('password', '') repeat_password = request.POST.get('repeat_password', '') email=request.POST.get('email', '') username = request.POST.get('username', '') if User.objects.filter(username=username): state = 'user_exist' else: new_user = User.objects.create_user(username=username, password=password,email=email) new_user.save() return redirect('/book/') content = { 'state': state, 'user': None, } return render(request, 'sign_up.html', content)  

修改密碼:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @login_required def set_password(request): user = request.user state = None if request.method == 'POST': old_password = request.POST.get('old_password', '') new_password = request.POST.get('new_password', '') repeat_password = request.POST.get('repeat_password', '') if user.check_password(old_password): if not new_password: state = 'empty' elif new_password != repeat_password: state = 'repeat_error' else: user.set_password(new_password) user.save() return redirect("/log_in/") else: state = 'password_error' content = { 'user': user, 'state': state, } return render(request, 'set_password.html', content)

自己建立User表

需要注意的是,以上的所有操作,都是針對django自動建立的auth_user表的,我們可以看一下這張表的結構

這是django給我們自動建立的一張user表,而如果要用auth模組,就必須要使用(或繼承)這張表。

繼承表的好處是我們可以增加一些自己需要的欄位,並且同時可以使用auth模組提供的介面、方法

下面就講一下繼承auth的方法:

1、匯入AbstractUser類,並且寫一個自定義的類,繼承AbstractUser類,如下:

1 2 3 4 5 6 7 8 9 from django.contrib.auth.models import AbstractUser class UserInfo(AbstractUser): """ 使用者資訊 """ nid = models.AutoField(primary_key=True) telephone = models.CharField(max_length=11, null=True, unique=True) ......

需要注意的是,UserInfo表裡就不需要有auth_user裡重複的欄位了,比如說username以及password等,但是還是可以直接使用這些欄位的,並且django會自動將password進行加密

2、這樣寫完之後,還需要在setting.py檔案裡配置:

1 AUTH_USER_MODEL = 'blog.UserInfo'

這樣,django就知道從blog專案下的models去查詢UserInfo這張表了