Django認證系統
一、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認證系統