Django basis cookie and session

Django basis cookie and session

1. Session Tracking

What is the conversation! The conversation can be understood as a meeting between the client and the server, in a meeting that may contain multiple requests and responses. For example, to 10086 make a phone call, you're the client, and 10086 service is the server. From the moment the two sides to connect the call, the session began, to either hang up the phone indicates the end of the session. During the call, it will be issued multiple requests to the 10086, so that multiple requests in a single session. The first client sends a request to a server to start the session began, until the end of the customer closed the browser session.

The origin of the cookie

HTTP protocol

超文本传输协议
关于连接:一次请求一次响应之后断开连接(无状态,短连接)
关于格式:(请求头内容之间用\r\n,请求头和请求体之间\r\n\r\n,响应同理)
        请求:请求头+请求体
        响应:响应头+响应体
        
拓展:
常见的请求头:1.user-agent:用的什么浏览器访问的网站
           2.content-type:请求体的数据格式(服务端按照格式进行解析)

Stateless means are independent of each request, the request after the request and prior to its implementation and the results are not directly related, not by the foregoing case request a respective direct impact, it does not directly affect the back request the appropriate circumstances. state can be understood as both client and server data generated in a given session, stateless and think that these data will not be retained. data generated session is that we need to be saved, that is to "hold" and therefore such cookie is generated

What is a cookie

A cookie is a browser technology, cookie specifically referring to was a little information, it is the server sends out a set of keys stored on the browser's right, next time you access the server browser will automatically carry these key-value pairs, so that the server extracting useful information

The principle cookie

Works cookie is: a browser to access the server, with an empty cookie, and then generate content from the server, the browser receives the response stored locally, when the browser visits, the browser will automatically bring the cookie, so that the server will be able to judge the content of the cookie.

cookie illustration

img

cookie specification

  • Cookie size is 4KB limit;
  • A server save up to 20 Cookie on the client browser;
  • A browser save up to 300 Cookie, because a browser can access multiple servers.

  The above data is only the HTTP Cookie specification, but in the browser wars of today, some of the browser in order to defeat the opponent, in order to show their ability, may Cookie specification for "extended" some, such as the size of each Cookie is 8KB, most 500 Cookie, etc. can be saved! But it may fill your hard drive will not appear!
Note that different browsers is not shared Cookie's. That is when you use IE to access the server, the server will send IE Cookie, and then save the IE up when you access the server using FireFox, IE is not possible to send Cookie saved to the server.

cookie and HTTP header

 Cookie is a HTTP request and response headers client and transmitted from the server:

  • Cookie: request header sent by the client to the server;
  • Format: Cookie: a = A; b = B; c = C. I.e., away from the plurality of Cookie semicolon; Set-Cookie: header in response, the server sends to the client;
  • A Cookie object a Set-Cookie: Set-Cookie: a = A Set-Cookie: b = B Set-Cookie: c = C

cookie coverage

If the server then send repeated Cookie will overwrite the old Cookie, for example, a first client request sent by the server is Cookie: Set-Cookie: a = A; a second request is sent by the server: Set-Cookie : a = AA, then the client, leaving only a Cookie, namely: a = AA.

3.django operation cookie

Ctrl + Shift + del three keys to clear the page cache and cookie

Get cookie

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

parameter:

  • default: default value
  • salt: Salt Encryption
  • max_age: background control expiration

Set cookie

rep = HttpResponse(...)
rep = render(request, ...)

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

parameter:

  • key, key
  • value = '', the value of
  • max_age = None, timeout
  • expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
  • path = '/', which entered into force Cookie path, / represents the root path, special: cookie root path can be accessed any url of the page
  • The domain domain = None, Cookie into force
  • secure = False, https transmission
  • httponly = False only http protocol transport, can not be acquired JavaScript (not absolute, can get to the bottom of capture may be covered)

set_cookie method Source

class HttpResponseBase:

    def set_cookie(self, key,       #键
                    value='',       #值
               max_age=None,   #超长时间 ,有效事件,max_age=20意思是这个cookie20秒后就消失了,默认时长是2周,这个是以秒为单位的
#cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止。

               expires=None,   #超长时间,值是一个datetime类型的时间日期对象,到这个日期就失效的意思,用的不多,expires默认None ,cookie失效的实际日期/时间。 
                                

               path='/',       #Cookie生效的路径,就是访问哪个路径可以得到cookie,'/'是所有路径都能获得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

Delete cookie

def logout(request):
    rep = redirect("/login/")
    rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
    return rep

cookie Login check example

def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.get_signed_cookie("login", salt="SSS", default=None) == "yes":
            # 已经登录的用户...
            return func(request, *args, **kwargs)
        else:
            # 没有登录的用户,跳转刚到登录页面
            return redirect("/login/?next={}".format(next_url))
    return inner


def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("password")
        if username == "xxx" and passwd == "dashabi":
            next_url = request.GET.get("next")
            if next_url and next_url != "/logout/":
                response = redirect(next_url)
            else:
                response = redirect("/class_list/")
            response.set_signed_cookie("login", "yes", salt="SSS")
            return response
    return render(request, "login.html")

4.session

Session is a server-side technology, the use of this technology, the server can be created at run time for each user's browser session object of its exclusive, due to the user's browser session is exclusive, so when users access the web server resources, It can be placed in each respective data session when the user access other web resources to go to the server, and then remove the other web resources, user services data from the respective user session.

img

img

Although Cookie solved to a certain extent, a "hold" requirements, but due to the 4096 byte maximum support itself Cookie, Cookie and stored in the client itself, may be intercepted or stolen, and therefore there is a need for something new, it support more bytes, and he saved on the server, there is high security. This is the Session.

  The question is, based on the characteristics of the stateless HTTP protocol, the server does not know the visitor "who." Then the aforementioned Cookie will play the role of bridge.

  We can give each client Cookie assigned a unique id, so that users access by Cookie, the server knows to the people "who." Then we id different based on Cookie's, private information stored on the server for some time, such as "account password" and so on.

  In conclusion: Cookie up for the lack HTTP stateless, let the server know to the people "who"; however Cookie in the form of text stored locally, their security is poor; so we can identify the user through different Cookie, corresponding saving private information and text than 4096 bytes in the Session.

  Further, the above-mentioned fact, Cookie and Session commonality things, not limited to the language and the frame.

5.django operation session

session related methods

Note: This method is provided by django, the framework will need other methods on your own cookie and a session of the.

# 获取、设置、删除Session中数据#取值
request.session['k1'] 
request.session.get('k1',None) #request.session这句是帮你从cookie里面将sessionid的值取出来,将django-session表里面的对应sessionid的值的那条记录中的session-data字段的数据给你拿出来(并解密),get方法就取出k1这个键对应的值#设置值
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置
#帮你生成随机字符串,帮你将这个随机字符串和用户数据(加密后)和过期时间保存到了django-session表里面,帮你将这个随机字符串以sessionid:随机字符串的形式添加到cookie里面返回给浏览器,这个sessionid名字是可以改的
#但是注意一个事情,django-session这个表,你不能通过orm来直接控制,因为你的models.py里面没有这个对应关系
#删除值
del request.session['k1']  #django-session表里面同步删除


# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()


# 会话session的key
session_key = request.session.session_key  获取sessionid的值

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

# 检查会话session的key在数据库中是否存在
request.session.exists("session_key") #session_key就是那个sessionid的值

# 删除当前会话的所有Session数据
request.session.delete()
  
# 删除当前的会话数据并删除会话的Cookie。
request.session.flush()  #常用,清空所有cookie---删除session表里的这个会话的记录,
    这用于确保前面的会话数据不可以再次被用户的浏览器访问
    例如,django.contrib.auth.logout() 函数中就会调用它。

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

session detailed flow analysis

img

session Login verification example

from functools import wraps


def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get("user"):
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next={}".format(next_url))
    return inner


def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        if user == "alex" and pwd == "alex1234":
            # 设置session
            request.session["user"] = user
            # 获取跳到登陆页面之前的URL
            next_url = request.GET.get("next")
            # 如果有,就跳转回登陆之前的URL
            if next_url:
                return redirect(next_url)
            # 否则默认跳转到index页面
            else:
                return redirect("/index/")
    return render(request, "login.html")


@check_login
def logout(request):
    # 删除所有当前请求相关的session
    request.session.delete()
    return redirect("/login/")


@check_login
def index(request):
    current_user = request.session.get("user", None)
    return render(request, "index.html", {"user": current_user})
问题:同一个浏览器上,如果一个用户已经登陆了,你如果在通过这个浏览器以另外一个用户来登陆,那么到底是第一个用户的页面还是第二个用户的页面,有同学是不是懵逼了,你想想,一个浏览器和一个网站能保持两个用户的对话吗?你登陆一下博客园试试,第一个用户登陆的时候,没有带着sessionid,第二个用户登陆的时候,带着第一个用户的sessionid,这个值在第二个用户登陆之后,session就被覆盖了,浏览器上的sessionid就是我第二个用户的了,那么你用第一个用户再点击其他内容,你会发现,看到的都是第二个用户的信息(注意:公众都能访问的a标签不算)。还有,你想想是不是你登陆一次就在django-session表里面给你添加一条session记录吗?为什么呢?因为你想,如果是每个用户每次登陆都添加一条sesson的记录,那么这个用户一年要登陆多少次啊,那你需要记录多少次啊,你想想,所以,你每次登陆的时候,都会将你之前登陆的那个session记录给你更新掉,也就是说你登陆的时候,如果你带着一个session_id,那么不是新添加一条记录,用的还是django-session表里面的前面那一次登陆的session_key随机字符串,但是session_data和expire_date都变了,也就是说那条记录的钥匙还是它,但是数据变了,有同学又要问了,那我过了好久才过来再登陆的,那个session_id都没有了啊怎么办,你放心,你浏览器上的session_id没有了的话,你django-session表里的关于你这个用户的session记录肯定被删掉了。再想,登陆之后,你把登陆之后的网址拿到另外一个浏览器上去访问,能访问吗?当然不能啦,另外一个浏览器上有你这个浏览器上的cookie吗,没有cookie能有session吗?如果你再另外一个浏览器上又输入了用户名和密码登陆了,会发生什么事情,django-session表里面会多一条记录,记着,一个网站对一个浏览器,是一个sessionid的,换一个浏览器客户端,肯定会生成另外一个sessionid,django-session表里面的session_key肯定不同,但是session_data字段的数据肯定是一样的,当然了,这个还要看人家的加密规则。

session configuration in django

Django default support Session, its interior offers five types of Session for developers to use.

1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 

4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   
# 引擎

其他公用设置项:
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,默认修改之后才保存(默认)

Guess you like

Origin www.cnblogs.com/tutougold/p/11701140.html