1. 程式人生 > >Django實現cookie&session以及認證系統

Django實現cookie&session以及認證系統

pan json sessionid tor msg 屬性 mem 問題 技術

COOKIE&SESSION

知識儲備

  由於http協議無法保持狀態,但實際情況,我們卻又需要“保持狀態”,因此cookie就是在這樣一個場景下誕生。

  cookie的工作原理是:由服務器產生內容,瀏覽器收到請求後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上cookie,這樣服務器就能通過cookie的內容來判斷這個是“誰”了。

  cookie雖然在一定程度上解決了“保持狀態”的需求,但是由於cookie本身最大支持4096字節,以及cookie本身保存在客戶端,可能被攔截或竊取,因此就需要有一種新的東西,它能支持更多的字節,並且他保存在服務器,有較高的安全性。這就是session。

  問題來了,基於http協議的無狀態特征,服務器根本就不知道訪問者是“誰”。那麽上述的cookie就起到橋接的作用。

  我們可以給每個客戶端的cookie分配一個唯一的id,這樣用戶在訪問時,通過cookie,服務器就知道來的人是“誰”。然後我們再根據不同的cookie的id,在服務器上保存一段時間的私密資料,如“賬號密碼”等等。

  總結而言:cookie彌補了http無狀態的不足,讓服務器知道來的人是“誰”;但是cookie以文本的形式保存在本地,自身安全性較差;所以我們就通過cookie識別不同的用戶,對應的在session裏保存私密的信息以及超過4096字節的文本

Django實現COOKIE

設置cookie

obj = HttpResponse(...) 或 obj= render(request, ...) 或 obj= redirect()
obj.set_cookie(key,value,...)
obj.set_signed_cookie(key,value,salt=‘加密鹽‘,...)

獲取cookie

request.COOKIES.get(key)
request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None)

刪除cookie

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

參數

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獲取
                                         (不是絕對,底層抓包可以獲取到也可以被覆蓋
技術分享圖片
$.cookie("key", value,{ path: / })
jquery操作cookie

Django實現SESSION

設置Session

request.session[key]=value
‘‘‘
實際進行的操作:
    1.  檢查請求是否有sessionid,且是否存在與數據庫,存在則對session_data進行更新
    2. 若不等,則創建隨機字符串
    3. set_cookie(‘sessionid‘,‘隨機字符串‘)
    4. 在session表中添加記錄
                  session-key          session-data
                    隨機字符串          {"key":"value"}-------------進行處理後的
‘‘‘

獲取Session

session_name=request.session[key]
‘‘‘
實際進行了哪些操作:
    1. 取隨機字符串request.COOKIE.get(‘sessionid‘)
    2. 在session表中進行過濾:
        obj=django-session.objects.filter(session-key=random_str).first()
        obj.session-data.get("user")

‘‘‘

其他

#刪除Sessions值
del request.session["session_name"]
#檢測是否操作session值
if "session_name" is request.session:

配置

技術分享圖片
Django默認支持Session,並且默認是將Session數據存儲在數據庫中,即:django_session 表中。
  
a. 配置 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,默認修改之後才保存(默認
數據庫配置(配置) 技術分享圖片
a. 配置 settings.py
  
    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,默認修改之後才保存
緩存配置 技術分享圖片
a. 配置 settings.py
  
    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,默認修改之後才保存
文件配置 技術分享圖片
def login_session(request):
    if request.method==POST:
        user=request.POST.get(user)
        pwd=request.POST.get(pwd)
        ret=UserInfo.objects.filter(name=user,pwd=pwd)
        if ret:
            request.session[user]=user
            return redirect(/index_session/)
    return render(request,login.html)

def index_session(request):
    user=request.session.get(user)
    if not user:
        return redirect(/login_session/)
    return render(request,index.html,locals())
View Code

Django的用戶認證

auth

利用auth模塊中的一些方法來進行認證
from django.contrib import auth

authenticate()

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

如果認證信息有效,會返回一個 User 對象。authenticate()會在User 對象上設置一個屬性標識那種認證後端認證了該用戶,且該信息在後面的登錄過程中是需要的。當我們試圖登陸一個從數據庫中直接取出來不經過authenticate()的User對象會報錯的

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

login(HttpRequest, user)

該函數接受一個HttpRequest對象,以及一個認證了的User對象

此函數使用django的session框架給某個已認證的用戶附加上session id等信息。

login(request, user)

logout(request)

該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會全部清除。該用戶即使沒有登錄,使用該函數也不會報錯。

logout(request)

User對象

User 對象屬性:

username, password(必填項)password用哈希算法保存到數據庫

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

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

is_authenticated()

如果是真正的 User 對象,返回值恒為 True 。 用於檢查用戶是否已經通過了認證。
通過認證並不意味著用戶擁有任何權限,甚至也不檢查該用戶是否處於激活狀態,這只是表明用戶成功的通過了認證。 這個方法很重要, 在後臺用request.user.is_authenticated()判斷用戶是否已經登錄,如果true則可以向前臺展示request.user.name

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

django自帶用於此種情況的裝飾器:login_requierd()

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

若用戶沒有登錄,則會跳轉到django默認的 登錄URL ‘/accounts/login/ ‘ (這個值可以在settings文件中通過LOGIN_URL進行修改)。並傳遞 當前訪問url的絕對路徑 (登陸成功後,會重定向到該路徑)。

創建用戶

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

修改密碼set_password()

user = User.objects.get(username=‘‘)
user.set_password(password=‘‘)
user.save

check_password(passwd)

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

基於auth認證實現登錄:

def login(request):
    ‘‘‘
    登錄驗證
    :param request:
    :return:
    ‘‘‘
    if request.method==POST:
        username=request.POST.get(username)
        pwd=request.POST.get(pwd)
        input_valid_code=request.POST.get(valid_code)
        valid_code=request.session.get(valid_code)
        login_response={user:None,error_msg:‘‘}
        #進行驗證碼的比較
        if valid_code.upper()==input_valid_code.upper():
            user=auth.authenticate(username=username,password=pwd)
            if user:
                auth.login(request,user)
                login_response[user]=user.username
            else:
                login_response[error_msg]=用戶名或密碼錯誤!
        else:
            login_response[error_msg]=驗證碼錯誤!
        import json
        return HttpResponse(json.dumps(login_response))
    return render(request,login.html,locals())

Django實現cookie&session以及認證系統