Cookie、Session和自定义分页

Cookie

cookie 的由来

   Http请求是无状态的.

  无状态的意思就是每次请求都是独立的, 他的执行情况和结果与前面的请求和之后的请求都无直接联系, 他不会受前面的请求情况直接影响, 他也不会直接影响后面的请求相应情况.

  对于服务器而言每次请求都是全新的请求. 状态可理解为客户端与服务端某次会话中产生的数据.那么无状态就不会保留这些数据.如果会话中的数据我们需要保留下来,也就是说要"保持状态", 因此就产生了 Cookie .

什么是 Cookie

  Cookie 具体指的是一段小信息,他是服务器发送出来存储在浏览器上的一组键值对,下次访问服务器时浏览器会自动携带着这些键值对, 以便服务器从中提取有用的信息.

Cookie 的原理

  Cookie 的工作原理是: 有服务器产生内容, 浏览器收到请求后保存在本地, 当浏览器再次访问时, 浏览器会自动带上 Cookie ,这样服务器就能通过 Cookie的内容来判断这个链接的信息.

Django 中操作 Cookie

 获取 Cookie

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

参数:

  • default: 默认值
  • salt: 加密盐
  • max_age: 后台控制过期时间

设置 Cookie

# 设置 cookie
rep = redirect('/home/')
# rep = redirect('/home/')
rep.set_cookie('key','value')    # 告诉浏览器在自己本地保存一个键值对.

rep.ser_signed_cookie(key,value,salt='加密盐',max_age=None......)

参数:

  •  key: 键
  • value='': 值
  • max_age=None: 超时时间.
  • expires=None,超时时间(IE requires expires, so set it if hasn't been already.)
  • path='/',: Cookie生效路径.
  • domain: None,Cookie生效的域名..
  • secure=False,Https传输

删除 Cookie

ret = redirect('/login/')
ret.delete_cookie('key')
return ret

Cookie 版登录验证

from functools import wraps
# cookie 登录验证装饰器
def check_login(func):
    @wraps(func)
    def inner(request,*args,**kwargs):
        # 先做 Cookie 验证
        cookie_value = request.COOKIES.get('kiis')
        if cookie_value == "abcdefg":
            rep = func(request,*args,**kwargs)
            return rep
        else:
            return_url = request.path_info
            print(return_url)
            return redirect('/login/?return_Url={}'.format(return_url))
    return inner

# 登录代码
class login(views.View):
    def get(self,request):
        rep = render(request, 'login.html')
        return rep
    def post(self,request):
        print(request.POST)
        username = request.POST.get('userName')
        pwd = request.POST.get('passWord')
        is_user = UserInfo.objects.filter(username=username,password=pwd)
        if is_user:
            # 设置 cookie
            rep = redirect('/home/')
            rep.set_cookie('kiis','abcdefg')    # 告诉浏览器在自己本地保存一个键值对.
            return rep
        else:
            return render(request, 'login.html',{'msg':'用户名或密码错误!'})

# 注销
@check_login
def home(request):
    if request.method == "POST":
        ret = redirect('/login/')
        ret.delete_cookie('kiis')
        return ret
    return render(request, 'home.html')
cookie版登录验证

 Session

Session的由来

  Cookie 虽然在一定程度上解决了 "保持状态" 的需求, 但是由于 Cookie 本身支持 4096 字节,以及 Cookie 本身保存在客户端, 可能被拦截或窃取, 因此就需要一种新技术,他能支持更多字节,并且保存在服务器,又比较高的安全性,这就是Session.

Django中Session相关方法

常用方法

# 设置 session
request.session['k1']=value

# 获取 session
request.session.get('k1',None)


# 存在则不设置
request.sssion.setdefault('k1',123)

# 删除 session
del request.session['key1']

# 删除当前的会话数据并删除会话的 Cookie
request.session.flush()

其他方法

# 获取所有的 键, 值, 键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()

# 获取会话 session 的key
request.session.session_key

# 将所有session失效日期小于当前的数据删除
request.session.clear_expired()

# 检查会话 session 的key 在数据库中是否存在
request.session.exists('session_key')

# 删除当前会话的所有 session 数据
request.session.delete()

# 设置会话 session 和 cookie 的超时时间
request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略。

Session解析流程

Session版本登录验证

 1 # 设置 session
 2 class login(views.View):
 3     def get(self,request):
 4         rep = render(request, 'login.html')
 5         return rep
 6     def post(self,request):
 7         print(request.POST)
 8         username = request.POST.get('userName')
 9         pwd = request.POST.get('passWord')
10         # 获取用户是否勾选七天免登录
11         remember_7 = request.POST.get('check1',None)
12         user_obj = UserInfo.objects.filter(username=username,password=pwd).first()
13         if user_obj:
14             # 获取用户上个页面跳转的 地址 如果没有获取到则设置 默认值
15             return_url = request.GET.get('return_Url','/home/')
16             print(return_url)
17             # 设置 session 字典属性
18             request.session['user'] = user_obj.username
19             request.session['age'] = 88
20             # 进行判断
21             if remember_7:
22                 # 如果用户勾选七天免登录则设置 session 过期时间
23                 request.session.set_expiry(7*24*60*60)
24             else:
25                 # 如果用户没有勾选则设置 session 过期时间为0
26                 request.session.set_expiry(0)
27 
28             return redirect(return_url)
29         return render(request, 'login.html',{'msg':'用户名或密码错误!'})
30 
31 # 验证装饰器
32 def check_login(func):
33     @wraps(func)
34     def inner(request,*args,**kwargs):
35         # 先做 session 验证
36         session_obj = request.session.get('user',None)
37         print(session_obj)
38         if session_obj:
39             rep = func(request,*args,**kwargs)
40             return rep
41         else:
42             return_url = request.path_info
43             return redirect('/login/?return_Url={}'.format(return_url))
44     return inner
45 
46 # 删除 注销函数
47 @check_login
48 def home(request):
49     if request.method == "POST":
50         request.session.flush() # 删除当前 session 并让 cookie 失效
51 
52         return redirect('/login/')
53     return render(request, 'home.html')
session版登录验证

Django中的Session配置

 1 1. 数据库Session
 2 SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
 3 
 4 2. 缓存Session
 5 SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
 6 SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
 7 
 8 3. 文件Session
 9 SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
10 SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
11 
12 4. 缓存+数据库
13 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
14 
15 5. 加密Cookie Session
16 SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
17 
18 其他公用设置项:
19 SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
20 SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
21 SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
22 SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
23 SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
24 SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
25 SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
26 SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
Session配置

CBV中加装饰器

  要在 CBV 视图中使用 验证装饰器, 必须用 method_decorator 方法.

         from django.utils.decorators import method_decorator 

加在CBVget或者post方法上

from django.utils.decorators import method_decorator

class UserinfoView(views.View):

    # 装饰器方法
    @method_decorator(check_login)
    def get(self,request):
        return render(request,'userinfo.html')

    def post(self,request):
        request.session.flush()  # 删除当前 session 并让 cookie 失效
        return redirect('/login/')

加在 dispatch方法上

  因为 CBV 中首先执行就是 dispatch 方法, 所以只要在 dispath 方法中加校验装饰器函数就相当于给 git/post 方法都加上了.

from django.utils.decorators import method_decorator

class UserinfoView(views.View):

    @method_decorator(check_login)
    def dispatch(self, request, *args, **kwargs):
        return super(UserinfoView,self).dispatch(request, *args, **kwargs)

    def get(self,request):
        return render(request,'userinfo.html')

    def post(self,request):
        request.session.flush()  # 删除当前 session 并让 cookie 失效
        return redirect('/login/')

加在视图类上

  如果 get 和 post 方法都需要登录校验的话就写两个装饰器.

@method_decorator(check_login,name='get')
@method_decorator(check_login,name='post')
class UserinfoView(views.View):

    def get(self,request):
        return render(request,'userinfo.html')

    def post(self,request):
        request.session.flush()  # 删除当前 session 并让 cookie 失效
        return redirect('/login/')

CSRF Token

  CSRF Token 相关装饰器在 CBV 只要加上 dispath 方法,或者加载视图类上然后 name 参数指定为 dispatch方法.

  • csrf_prottect: 为当前函数强制设置跨站请求伪造功能, 即便 settings 中没有设置全局中间件.
  • csrf_exempt: 取消当前函数跨站请求伪造功能, 即便 settings 中设置了全局中间件.
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect

@method_decorator(check_login,name='get')
@method_decorator(check_login,name='post')
class UserinfoView(views.View):
    # 取消 csrf 跨站请求伪造验证功能
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(UserinfoView,self).dispatch(request, *args, **kwargs)

    def get(self,request):
        return render(request,'userinfo.html')

    def post(self,request):
        request.session.flush()  # 删除当前 session 并让 cookie 失效
        return redirect('/login/')

  

 

posted @ 2020-06-10 15:18  闫世成  阅读(102)  评论(0)    收藏  举报