1. 程式人生 > >Django認證系統

Django認證系統

value alias 實現 改密碼 過期 gin 讀取 obj httponly

一、cookie和session

由於HTTP協議無法保存一次連接的狀態信息,而實際應用中我i們又需要知道連接另一端的客戶端的身份,於是就誕生了cookie,cookie的工作原理是:由服務器產生內容,瀏覽器收到請求後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上cookie,這樣服務器就能通過cookie的內容來判斷另一端的客戶端的身份了。但是cookie的內容是保存在瀏覽器本地的,將用戶信息保存在cookie中容易造成信息泄露,安全性較差,為了解決安全性問題就誕生了session,session是保存在服務器上的,將用戶信息保存在session中安全性將得到提高,實際應用中就是將cookie和session配合使用,服務器在cookie中保存一個唯一ID,在session中也保存這個ID並同時保存相關的用戶信息,當瀏覽器攜帶cookie訪問服務器時,服務器就可以通過cookie中的ID獲取對應的用戶信息。

二、Django中使用cookie

1、獲取cookie

request.COOKIES[key]  #普通cookie
request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None)  #加密cookie
    #參數:
        default: 默認值
           salt: 加密鹽
        max_age: 後臺控制過期時間

2、設置cookie

rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect()  #生成一個響應對象
 
rep.set_cookie(key,value,...)  #給響應對象添加cookie
rep.set_signed_cookie(key,value,salt
=加密鹽,...)  ‘‘‘ def set_cookie(self, key, 鍵              value=‘‘, 值              max_age=None, 超長時間              expires=None, 超長時間              path=‘/‘, Cookie生效的路徑, 瀏覽器只會把cookie回傳給帶有該路徑的頁面,這樣可以避免將 cookie傳給站點中的其他的應用。 / 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問              domain=None, Cookie生效的域名 你可用這個參數來構造一個跨站cookie。 如, domain=".example.com" 所構造的cookie對下面這些站點都是可讀的: www.example.com 、 www2.example.com                          和an.other.sub.domain.example.com 。 如果該參數設置為 None ,cookie只能由設置它的站點讀取。              secure=False, 如果設置為 True ,瀏覽器將通過HTTPS來回傳cookie。              httponly=False 只能http協議傳輸,無法被JavaScript獲取 (不是絕對,底層抓包可以獲取到也可以被覆蓋)           ): pass
‘‘‘

<script src=‘/static/js/jquery.cookie.js‘></script>    #Jquery操作cookie
<script>$.cookie("key", value,{ path: / });</script>

3、刪除cookie

response.delete_cookie("cookie_key",path="/",domain=name)

三、Django中session應用

1、Django設置session的工作過程

當設置了session的key-value之後,Django會把它們存在一個字典並序列化,然後產生一串隨機字符並加密,將隨機字符作為session-key,字典作為session-data,以及失效時間作為一條記錄存在auth_session表中,然後在給客戶端的響應中添加一個cookie的鍵值對,key為session_ID,value為產生的那個隨機字符串。當客戶端再次訪問時,從客戶端的cookie中取出session_ID在auth_session表中找出對應記錄,以供後續操作。

2、session基本操作

1、設置Sessions值
          request.session[session_name] ="admin"
2、獲取Sessions值
          session_name = request.session["session_name"]
3、刪除Sessions值
          del request.session["session_name"]
4、檢測是否存在session值
          if "session_name" is request.session : #檢測是否有key為"session_name"對應的值

3、對session的操作

request.session.get(key, default=None)
 
fav_color = request.session.get(fav_color, red)
 
request.session.pop(key)
 
fav_color = request.session.pop(fav_color)
 
request.session.keys()
 
request.session.items()
 
request.session.setdefault()
 
request.session.flush() 刪除當前的會話數據並刪除會話的Cookie。
            這用於確保前面的會話數據不可以再次被用戶的瀏覽器訪問
            例如,django.contrib.auth.logout() 函數中就會調用它。
 
 

request.session.session_key   #獲取session_ID
  
# 將所有Session失效日期小於當前日期的數據刪除
request.session.clear_expired()
  
# 檢查 用戶session的隨機字符串 在數據庫中是否
request.session.exists("session_key")
  
# 刪除當前用戶的所有Session數據
request.session.delete("session_key")
  
request.session.set_expiry(value)
            * 如果value是個整數,session會在些秒數後失效。
            * 如果value是個datatime或timedelta,session就會在這個時間後失效。
            * 如果value是0,用戶關閉瀏覽器session就會失效。
            * 如果value是None,session會依賴全局session失效策略。

4、session存儲配置

數據庫存儲

in   settings.py

SESSION_ENGINE = django.contrib.sessions.backends.db   # 引擎(默認)
      
SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認)
SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路徑(默認)
SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默認)
SESSION_COOKIE_SECURE = False                            # 是否Https傳輸cookie(默認)
SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http傳輸(默認)
SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默認)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否關閉瀏覽器使得Session過期(默認)
SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次請求都保存Session,默認修改之後才保存(默認)

緩存存儲

SESSION_ENGINE = django.contrib.sessions.backends.cache  # 引擎
SESSION_CACHE_ALIAS = default                            # 使用的緩存別名(默認內存緩存,也可以是memcache),此處別名依賴緩存的設置
  
  
SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串
SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路徑
SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False                             # 是否Https傳輸cookie
SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http傳輸
SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否關閉瀏覽器使得Session過期
SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次請求都保存Session,默認修改之後才保存

文件存儲

SESSION_ENGINE = django.contrib.sessions.backends.file    # 引擎
SESSION_FILE_PATH = None                                    # 緩存文件路徑,如果為None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir()        
SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串
SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路徑
SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False                               # 是否Https傳輸cookie
SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http傳輸
SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否關閉瀏覽器使得Session過期
SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次請求都保存Session,默認修改之後才保存

四、auth模塊

auth模塊有三個常用的函數分別是authenticate() ,login(HttpRequest, user),logout(request) 註銷用戶 ,使用方法如下

from django.contrib.auth import authenticate, login,logout
   
def my_view(request):
  username = request.POST[username]
  password = request.POST[password]
  user = authenticate(username=username, password=password) #根據傳入的用戶名,密碼從auth_user表中查詢對應記錄,如果查到記錄會返回一個加了認證標識的user對象
  if user is not None:
    login(request, user)   #接收一個請求對象和已認證user對象,給這個user對象添加session_ID等信息
    # Redirect to a success page.
    ...
  else:
    # Return an ‘invalid login‘ error message.
    ...


def logout_view(request):
  logout(request)   #清除該請求在數據庫中的session記錄
  # Redirect to a success page.

五、Django的user表

我們在用戶驗證登陸的時候需要用到存儲用戶信息的user表,而我們不需要自己創建user表,Django自動創建了user,而我們要使用Django的user需要導入Django的models

 User 對象屬性:username, password(必填項)password用哈希算法保存到數據庫

 is_staff : 用戶是否擁有網站的管理權限.

 is_active : 是否允許用戶登錄, 設置為``False``,可以不用刪除用戶來禁止 用戶登錄

#創建用戶
from django.contrib.auth.models import User
user = User.objects.create_user(username=‘‘,password=‘‘,email=‘‘#修改密碼
user = User.objects.get(username=‘‘)
user.set_password(password=‘‘)
user.save 

#在修改密碼前應該先驗證舊密碼
from django.contrib.auth.hashers import  check_password
is_true = check_password(‘wmyj1203‘,user_obj.password)  #第一個參數為輸入的舊密碼,第二個參數為數據庫中的密碼
 

六、檢測用戶是否通過驗證

方法1  #用戶未驗證就跳轉到登錄頁(django默認的 登錄URL ‘/accounts/login/ ‘ (這個值可以在settings文件中通過LOGIN_URL進行修改)),通過驗證後跳轉回之前的頁面
def my_view(request):
  if not request.user.is_authenticated():
    return redirect(%s?next=%s % (settings.LOGIN_URL, request.path))


方法2 #用戶未驗證就跳轉到登錄頁(django默認的 登錄URL ‘/accounts/login/ ‘ (這個值可以在settings文件中通過LOGIN_URL進行修改)),通過驗證後跳轉回之前的頁面,通過裝飾器實現 

from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
  ...

七、示例

#註冊
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)  


#修改密碼
@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)

Django認證系統