Django's cookie with the session, middleware

cookie与session

Why cookie and session

Since the HTTP protocol is stateless, can not remember who the user is, so every time we landed, we must re-enter the password, even if you do not set a cookie, the Web may have not requested

Stored in the client key on the browser to

Is a server set up in the client keys on the browser right, it means that the browser can actually refuse server commands. By default, the browser is available directly from the server to set key-value pairs

We need three tricks deformation before operation begins

obj1 = HttpResponse()
return obj1
obj2 = render()
return obj2
obj3 = redirect()
return obj3

Set cookie

obj1.set_cookie()

Get cookie

request.COOKIES.get()

Delete cookie

obj1.delete_cookie()

Examples: cookie Login check

Directly on the code:

def login(request):
    # print(request.path_info)  # 只拿url 不拿get请求携带的额外参数
    # print(request.get_full_path())  # 都拿
    
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'yjy' and password == '123':
            old_path = request.GET.get('next')
            if old_path:
                # 保存用户登录状态
                obj = redirect(old_path)
            else:
                obj = redirect('/home/')
            obj.set_cookie('name', 'yjy')  # 让客户端浏览器 记录一个键值对
            # obj.set_cookie('name','jason',max_age=5)  # 让客户端浏览器 记录一个键值对
            return obj
    return render(request, 'login.html')


from functools import wraps   #装饰器修复技术
def login_auth(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('name'):
            res = func(request, *args, **kwargs)
            return res
        else:
            target_url = request.path_info
            return redirect('/login/?next=%s' % target_url)
    return inner


@login_auth
def home(request):
    # 校验用户是否登录
    # if request.COOKIES.get('name'):
    #     return HttpResponse('我是主页 只有登录了才能看')
    # return redirect('/login/')
    return HttpResponse('我是主页 只有登录了才能看')


@login_auth
def index(request):
    return HttpResponse('我是index页面 也需要用户登录之后才能看')


@login_auth
def xxx(request):
    return HttpResponse('xxx页面 也是需要登录了之后才能看')


@login_auth
def logout(request):
    obj = redirect('/login/')
    obj.delete_cookie('name')  #注销之后删除cookie
    return obj

session

Keys stored on the server for

django session default expiration time is 14 days

Set session

 request.session['key'] = value   #仅仅只会在内存产生一个缓存

Three Steps:

  • Django automatically generated internal random string
  • Django_session data stored in tables

session_key session_data date
random string data 1 1 ...
random data string 2 2 ...
a random string of data 3 ... 3

  • It will be sent randomly generated string to the browser so that the browser stores a cookie (sessionid: random string)
def set_session(request):
    request.session['username'] = 'yjy'
    request.session.set_expiry(value=0)   #session在关闭浏览器后消失
    return HttpResponse("设置session")

Obtaining session

request.session..get('key')

Three Steps:

  • After the browser sends the cookie to django django backend will automatically get a cookie value
  • Django_session random string to the table holding ratio whether a corresponding data
  • If the ratio of the stresses on the random string data corresponding to the extracted assigned to request.session, if not on so request.sessionthat the empty

sessionTable a record for a browser on the same computer, a different browser, will have a different record

def get_session(request):
    print(request.session.get('username'))
    return HttpResponse('获取session')

Delete session

delete: delete the service side

request.session.delete()

flush: the browser and the server to delete all

request.session.flush()
def delete_session(request):
    # request.session.delete()  #删除服务端的session
    
    request.session.flush()   #两个端的session都会删除
    return HttpResponse("删除session")

You can also set the timeout session

request.session.set_expiry(value)
  • valueIs an integer, sessionwill disappear after a few seconds (in seconds)
  • valueIs datatime or timedelta, sessionwill disappear after this time
  • value0, sessionwill disappear after you close your browser
  • valueTo None, sessionit will depend on the global sessionexpiration policy

Examples: session Login check

rear end

from django.shortcuts import render, HttpResponse, redirect


# Create your views here.
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        if username == "yjy" and password == "123456":
            # 设置session值
            request.session['username'] = username
            # 获取跳到登陆之前的url
            next_url = request.GET.get("next")
            if next_url:
                return redirect(next_url)
            else:
                return redirect('/index/')
    return render(request, "login.html")

# 装饰器
from functools import wraps

def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        print(next_url)
        if request.session.get('username'):
            return func(request, *args, **kwargs)
        else:
            return redirect(f"/login/?next={next_url}")
    #http://127.0.0.1:8000/login/?username=yjy&password=123456
    return inner

@check_login
def index(request):
    # request.session.get("username", None)
    return HttpResponse('我是index页面 需要用户登录之后才能看')

front end:

<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username"></p>
    <p>password:<input type="text" name="password"></p>
    <button><input type="submit"></button>
</form>

The end result is like this

Display after the submission of data

Database session display

django middleware

Scenarios

Restrict user access frequency
whether the user is a blacklist whitelist
all users log in check
as long as it relates to global web site function middleware is the best choice

Custom method

We need to make the appropriate data preparation

1. Create a new folder inside an arbitrary name of py file
written inside the class inherits fixed

from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin):
    ...

2. Sign up to the middleware configuration file to configure the
path is requested in writing strings

 'app01.mymiddleware.myaabb.MyMiddle1'
 'app02.mymiddleware.myaabb.MyMiddle2'

process_request:

When the request will be from top to bottom through each broker which process_request, once inside returns HttpResponsean object that is no longer carried out later will perform at the same levelprocess_response

def process_request(self,request):
    print('我是第一个自定义中间件里面的process_request方法')
    return HttpResponse("我是第一个自定义中间件里面的HttpResponse对象返回值")  # 直接原地返回

process_response:

响应走的时候 会从下往上依次经过每一个中间件里面的process_response

def process_response(self,request,response):  # response就是要返回给用户的数据
     print("我是第一个自定义中间件里面的process_response方法")
     return response  #只要有response参数,就必须给他返回

process_view:

路由匹配成功之后,执行视图函数之前触发

process_exception:

当视图函数出现异常(bug)的时候自动触发

process_template_response:

当视图函数执行完毕之后并且返回的对象中含有render方法的情况下才会触发

django请求生命周期流程图

中间件之前端操作

form表单

写form表单之前只需要加上{% csrf_token %}

ajax

第一种: 自己再页面上先通过{% csrf_token %}获取到随机字符串 然后利用标签查找

data:{'username':'jason','csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()},

第二种:

data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},

第三种:拷贝js文件

#这个东西在中间件的官网上拷贝就行了
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');


function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

跨站请求伪造(csrf)

原理:

你写的form表单中 用户的用户名 密码都会真实的提交给银行后台

但是收款人的账户却不是用户填的 你暴露给用户的是一个没有name属性的input框
你自己提前写好了一个隐藏的带有name和value的input框

钓鱼网站实例

后端

def transfer(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print('%s 给 %s转了%s钱' % (username, target_user, money))
    return render(request, 'transfer.html')

正儿八经网站前端

<form action="" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>target_user:<input type="text" name="target_user"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>

钓鱼网站前端

<form action="http://127.0.0.1:8000/transfer/" method="post">
    <p>username:<input type="text" name="username"></p>
    <p>targer_user:<input type="text"></p>
    <p><input type="text" name="target_user" value="jason" style="display: none"></p>
    <p>money:<input type="text" name="money"></p>
    <input type="submit">
</form>

防钓鱼网站策略

只要是用户想要提交post请求的页面 我在返回给用户的时候就提前设置好一个随机字符串当用户提交post请求的时候 我会自动先取查找是否有该随机字符串
如果有 正常提交,如果没有 直接报403

以上仅仅是一个思路,还是需要我们用代码去实现,具体的实现方法就是在里面注入中间件。

CBV加装饰器

先要导入模块

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator

csrf_exempt 两种装饰方式

第一种

@method_decorator(csrf_exempt,name='dispatch')
class MyCsrf(View):

第二种

@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
    return super().dispatch(request,*args,**kwargs)
def get(self,request):
    return HttpResponse('hahaha')

其他装饰器 三种装饰方式

第一种

@method_decorator(csrf_protect,name='post')
class MyCsrf(View):

第二种

@method_decorator(csrf_protect)
def dispatch(self, request, *args, **kwargs):
    return super().dispatch(request,*args,**kwargs)
def get(self,request):
    return HttpResponse('hahaha')

第三种

@method_decorator(csrf_protect)
def post(self,request):
   return HttpResponse('post'

每日面试题

python2和python3的区别(至少写三个)

'''
py2:
>>> print("hello", "world")
('hello', 'world')
py3:
>>> print("hello", "world")
hello world


py2:input_raw()
py3:input()


1/2的结果
py2:返回0
py3:返回0.5


py2:默认编码ascii
py3:默认编码utf-8


字符串
py2:unicode类型表示字符串序列,str类型表示字节序列
py3::str类型表示字符串序列,byte类型表示字节序列


py2:函数用关键字global声明某个变量为全局变量,但是在嵌套函数中,想要给一个变量声明为非局部变量是没法实
现的。
py3:新增了关键字nonlocal,使得非局部变量成为可能


py2:
 int() # 整型
 long() # 长整型
py3:没有long类型,只有int类型


py2:xrange 用法与 range 完全相同,所不同的是生成的不是一个list对象,而是一个生成器。
py3:将以前的range取消了,而将xrange重新命名成了range!所以我们现在看到的range其实本质还是xrange~。


py2: iteritems() 用于返回本身字典列表操作后的迭代器【Returns an iterator on allitems(key/value pairs) 】,不占用额外的内存。
py3: iteritems()方法已经废除了。在3.x里用 items()替换iteritems() ,可以用于 for 来循环遍历
'''

什么是可变,什么是不可变

'''
可变不可变指的是内存中的值是否可以被改变,
可变:值得改变不会引起内存地址的改变
不可变:值得改变会引起内存地址的改变
不可变类型有数值、字符串、元组;
可变类型则是可以改变,主要有列表、字典。
'''

m=10,n=5,互换值(至少两种方式)

'''
t = m  #t=10
m = n  #m=5
n = t  #n=10


m,n = n,m   #交叉赋值
'''

Guess you like

Origin www.cnblogs.com/yanjiayi098-001/p/11768375.html