17-3 cookie和session

一 . Cookie
1.cookie 是什麼?
  保存在瀏覽器端的鍵值對!
  服務端在返回響應的時候,告訴瀏覽器保存的鍵值對!瀏覽器能夠拒絕保存Cookie.

2. 爲何要有cookie?
  HTTP請求是無狀態的,咱們須要保存狀態 --> cookie

3. Django中cookie的使用
  1. 設置cookie
  rep = HttpResponse("ok")
  rep.set_cookie("key", "value", max_age=xx秒)
  rep.set_signed_cookie("key", "value", salt="ooxx", max_age=xx秒)
  2. 獲取cookie
  request.COOKIES.get("key")
  request.get_signed_cookie("key", default="", salt="ooxx")html

  參數:django

  • default: 默認值
  • salt: 加密鹽
  • max_age: 後臺控制過時時間


4. cookie有失效時間
  1. Django中不設置,關閉瀏覽器就失效了
  2. 經過max_age設置超時時間後端

5. 補充3點:
1. 如何登錄後再跳轉回以前訪問的頁面 瀏覽器

  寫個登陸函數:例子安全

 1 def login(request):
 2     if request.method == "POST":
 3         path = request.GET.get("path")
 4         print(path)
 5         username = request.POST.get("username")
 6         pwd = request.POST.get("pwd")
 7         if username == "alex" and pwd == "123":
 8             if path:
 9                 rep = redirect(path)
10             else:
11                 rep = redirect("/publisher_list/")
12             rep.set_signed_cookie("hu", "hao", salt="ooxx", max_age=7)
13             return rep
14         else:
15             return HttpResponse("用戶名或者密碼錯誤")
16     else:
17 
18         return render(request, "login.html")

寫個裝飾器cookie

from functools import wraps


# 裝飾器版本登陸認證
def login_check(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        path = request.path_info
        # 登陸驗證
        v = request.get_signed_cookie("hu", default="", salt="ooxx")  # 獲取加鹽的cookie
        if v == "hao":
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?path={}".format(path))

    return inner

你想要訪問那個頁面,把裝飾器加到它的上面session

@login_check
def book_list(request):
    data = models.Book.objects.all()
    return render(request, "book_list.html", {"book_list": data})

最後訪問,book_list這個頁面,會讓你先登陸,而且在url後面拼接一個目錄app

http://127.0.0.1:8001/login/?path=/book_list/,而後登錄成功,跳轉到book_list函數

注意:login.html文件裏面的action必定要寫空,不然不能跳轉,或者寫成{{request.get_path_info}}工具

 


2. 如何將FBV的裝飾器應用到CBV上?

在views裏面導入

from django.utils.decorators import method_decorator

就是

 @method_decorator(login_check) 括號裏面是你寫的裝飾器函數

例子:

class AddBook(views.View):

    @method_decorator(login_check)  # login_check是剛纔寫的裝飾器函數
    def get(self, request):
        data = models.Publisher.objects.all()
        return render(request, "add_book.html", {"publisher_list": data})

    def post(self, request):
        book_name = request.POST.get("title")
        publisher_id = request.POST.get("publisher")
        publisher_obj = models.Publisher.objects.get(id=publisher_id)
        # 建立書籍
        models.Book.objects.create(
            title=book_name,
            publisher_id=publisher_id
            # publisher=publisher_obj
        )
        return redirect("/book_list/")

 


3. 裝飾器修復技術 --> from functools import wraps

在inner函數的上面加上@wraps(func),默認不加是不影響使用的,只是被裝飾的函數名字和註釋信息都不能查看了

例子:

from functools import wraps


def wrapper(func):
    @wraps(func)  # 藉助內置的工具修復被裝飾的函數
    def inner(*args, **kwargs):
        print("呵呵")
        func(*args, **kwargs)
    return inner


@wrapper
def foo(arg):
    """
    這是一個測試裝飾器的函數
    :param arg: int 必須是int類型
    :return: None
    """
    print("嘿嘿嘿" * arg)


foo(10)
print(foo.__doc__)

 二  session

爲何要有session
1. Cookied額缺點:
  1. 數據量只有4096
  2. 數據都保存在客戶端(瀏覽器)上,不安全

2. Session
保存在服務端的鍵值對

  1. 請求來了以後,仍是生成隨機字符串
  2. 以隨機字符串爲key,在服務端生成一個大字典,真正保存數據是value
  3. 把隨機字符串以cookie的形式回覆給瀏覽器

  4. 下一次請求再來的時候,會攜帶上一步的隨機字符串
  5. 從請求中拿到隨機字符串,
  6. 去後端以 該隨機字符串爲key找對應的value
  7. value裏面存的就是真正有用的數據

3. Django中如何使用Session
  1. 不管設置Session仍是獲取Session都是針對request對象來操做

  2. 設置Session
  request.session["key"] = "value"
  3. 獲取session
  request.session.get("key")

4. 其餘經常使用命令
  1. # 將全部Session失效日期小於當前日期的數據刪除
  request.session.clear_expired()
  2. # 刪除當前的會話數據並刪除會話的Cookie。
  request.session.flush()

  3. 設置超時時間
  request.session.set_expiry(7)

5. 經常使用配置項(寫在Settings.py中)
# 全局配置session超時時間
SESSION_COOKIE_AGE = 60 * 60 * 24 * 2 #7天

# 是否每次請求都刷新session超時時間
SESSION_SAVE_EVERY_REQUEST = True

例子:

def login_check(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next = request.path_info
        # 登陸驗證
        # 取Session
        v = request.session.get("s21")
        if v == "hao":
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next={}".format(next))

    return inner


# 登陸 session驗證
def login(request):
    if request.method == "POST":
        next = request.GET.get("next")
        username = request.POST.get("username")
        pwd = request.POST.get("pwd")
        if username == "alex" and pwd == "123":
            if next:
                rep = redirect(next)
            else:
                rep = redirect("/secode/")
            request.session["s21"] = "hao"
            request.session.set_expiry(70)
            return rep
        else:
            return HttpResponse("走吧")
    else:
        return render(request, "login.html")


@login_check
def index(request):
    return render(request, "index.html")


@login_check
def secode(request):
    return render(request, "secode.html")
相關文章
相關標籤/搜索