Django's cookie, session, authentication system auth

Django's cookie, session, authentication system auth

navigation

COOKIE 与 SESSION

concept

http cookie does not belong to the scope of the agreement, due to the http protocol can not hold, but the reality, but we need to "hold" and therefore cookie is born under such a scenario.

Works cookie is: generated content from the server, the browser receives the request saved locally; when the browser visits, the browser will automatically bring the cookie, so that the server can be judged by the content of the cookie is "Who "a.

Although cookie solved to a certain extent, a "hold" requirements, but due to the cookie itself supports up to 4096 bytes, and the cookie 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. That's session.

The question is, based on the characteristics of a stateless http protocol, the server does not know the visitor "who." Then the above-mentioned cookie will play the role of bridge.

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

To sum up: cookie to make up for the lack of http stateless, let the server know to the people "who"; but the cookie in the form of text stored locally, their security is poor; so we can identify different users by cookie, corresponding saving private information and text than 4096 bytes in the session.

In addition, the above mentioned cookie and session commonality is actually something that is not limited to language and framework

Application Log

Introduction previous sections, we have been able to make a landing page, after verifying the correctness of a user name and password to jump to the background page. But the tests also found that if the bypass login page. Direct input background url address can also be accessed directly. This is clearly unreasonable. In fact, we are missing is a cookie and a session with the verification. With this verification process, we can achieve and other Web sites must be logged in to enter the back page.

      Let me talk about this kind of authentication mechanism. Whenever we use a browser to access a landing page, once we have passed the certification. The server sends a random set of unique strings (assumed to be 123abc) to the browser, the cookie is stored in what is called the browser side. And the server will store about their own current state of the user, such as login = true, username = user information hahaha like. But this memory is stored in the form of dictionaries, dictionaries of the only key issue is just a unique cookie value of the user. So if you view session information on the server side, then, in theory, you will see the following dictionary look like

{'123abc':{'login':true,'username:hahaha'}}

Because each cookie is unique, so we change the browser on your computer and then landing with a website also needs to be verified again. So why do we just say theoretically see it like this dictionary? Because of safety considerations in the fact that a big dictionary not only for the above key is encrypted 123abc value, value a value { 'login': true, 'username: hahaha'} at the server side is the same encrypted. So we open on the server even if the session information see something like the following also look like

{ '123abc': dasdasdasd1231231da1231231}

Know the principle, following on to be implemented in code.

Django achieved COOKIE

Get Cookie

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    #参数:
        default: 默认值
           salt: 加密盐
        max_age: 后台控制过期时间

Cookie settings

rep = HttpResponse(...) 或 rep = render(request, ...) 或 rep = redirect()
 
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...) 

Copy the code

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

Copy the code

Since the cookie stored on the client computer, so, JavaScript and jquery can also operate cookie.

<script src='/static/js/jquery.cookie.js'>
 
</script> $.cookie("key", value,{ path: '/' });

Delete cookie

response.delete_cookie("cookie_key",path="/",domain=name)

 cookie stored in the client
       benefits:
           data exists on the client, reduce the pressure on the server side, to improve site performance.
       Cons:
           security is not high: it is easy to be viewed or crack user session information on the client machine

Django achieved SESSION

Basic Operations

Copy the code

1, Sessions set value 
          makes request.session [ 'session_name'] = "ADMIN" 
2, obtaining the value of Sessions 
          session_name makes request.session = [ "session_name"] 
. 3, remove Sessions value 
          del makes request.session [ "session_name"] 
. 4, detecting whether operating session value 
          if "session_name" is request.session:

Copy the code

Copy the code

. 5, GET (Key, default = None) 
 
fav_color = request.session.get ( 'fav_color', 'Red') 
 
. 6, POP (Key) 
 
fav_color = request.session.pop ( 'fav_color') 
 
. 7, Keys () 
 
. 8 , items () 
 
9, setDefault () 
 
10, flush () delete the current session data and deletes the session Cookie. 
            This is used to ensure that the previous session data can not be accessed again the user's browser, 
            for example, django.contrib.auth.logout () function is called it. 
 
 
11 user session random string of 
        request.session.session_key 
  
        # expiration date will be less than the current date data to remove all the Session 
        request.session.clear_expired () 
  
        random string # to check whether the user session in the database 
        request.session.exists ( " session_key ") 
  
        # delete all the current user Session data 
        request.session.delete (" session_key ")
  
        request.session.set_expiry (value) 
            * If the value is an integer, session will expire after some number of seconds. 
            * If the value is datatime or timedelta, session will expire after this time. 
            * If the value is 0, the user closes the browser session will fail. 
            * If the value is None, session will depend on the global session expiration policy.

Copy the code

 Flow analysis chart

Examples

Copy the code

def log_in(request):

    if request.method=="POST":
        username=request.POST['user']
        password=request.POST['pwd']

        user=UserInfo.objects.filter(username=username,password=password)

        if user:
            #设置session内部的字典内容
            request.session['is_login']='true'
            request.session['username']=username

            #登录成功就将url重定向到后台的url
            return redirect('/backend/')

    #登录不成功或第一访问就停留在登录页面
    return render(request,'login.html')




def backend(request):
    print(request.session,"------cookie")
    print(request.COOKIES,'-------session')
    """
    这里必须用读取字典的get()方法把is_login的value缺省设置为False,
    当用户访问backend这个url先尝试获取这个浏览器对应的session中的
    is_login的值。如果对方登录成功的话,在login里就已经把is_login
    的值修改为了True,反之这个值就是False的
    """

    is_login=request.session.get('is_login',False)
    #如果为真,就说明用户是正常登陆的
    if is_login:
        #获取字典的内容并传入页面文件
        cookie_content=request.COOKIES
        session_content=request.session

        username=request.session['username']

        return render(request,'backend.html',locals())
    else:
        """
        如果访问的时候没有携带正确的session,
        就直接被重定向url回login页面
        """
        return redirect('/login/')



def log_out(request):
    """
    直接通过request.session['is_login']回去返回的时候,
    如果is_login对应的value值不存在会导致程序异常。所以
    需要做异常处理
    """
    try:
        #删除is_login对应的value值
        del request.session['is_login']
        
        # OR---->request.session.flush() # 删除django-session表中的对应一行记录

    except KeyError:
        pass
    #点击注销之后,直接重定向回登录页面
    return redirect('/login/')

===================================login.html==================
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="/login/" method="post">
    <p>用户名: <input type="text" name="user"></p>
    <p>密码: <input type="password" name="pwd"></p>
    <p><input type="submit"></p>
</form>


</body>
</html>


===================================backend.html==================

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h3>hello {{ username }}</h3>
<a href="/logout/">注销</a>

</body>
</html>




 

ession stored configuration 

1. Configuration Database (default) 
the Django Session support default, and the default is in the database, i.e. the data storage Session: django_session table. 
  
. a configuration the settings.py 
  
    SESSION_ENGINE = 'django.contrib.sessions.backends.db' # engine (default) 
      
    SESSION_COOKIE_NAME = "SessionID" # Session Key when stored in a cookie on the browser, namely: sessionid = random string ( default) 
    SESSION_COOKIE_PATH = "/" # save the cookie path of Session (the default) 
    SESSION_COOKIE_DOMAIN = saved None # Session of cookie domain (default) 
    SESSION_COOKIE_SECURE = False # whether Https transfer cookie (default) 
    SESSION_COOKIE_HTTPONLY = True # whether the Session cookie only support http transmission (default) 
    SESSION_COOKIE_AGE = 1209600 # Session of cookie expiration date (2 weeks) (default)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False # if you close the browser makes Session expired (default) 
    SESSION_SAVE_EVERY_REQUEST = False Session # save if every request, only after saving changes to the default (default)

 

2. cache configuration

 

a. Configuring the settings.py 
  
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # engine 
    SESSION_CACHE_ALIAS = 'default' # alias buffer used (the default cache memory, may be memcache), provided by the alias cache dependency 
  
  
    SESSION_COOKIE_NAME = when the "sessionid" # Session's cookie on the browser key, namely: sessionid = random string 
    SESSION_COOKIE_PATH = "/" # saved Session cookie path 
    saved SESSION_COOKIE_DOMAIN = None # Session of cookie domain 
    SESSION_COOKIE_SECURE = False # are Https transfer cookie 
    SESSION_COOKIE_HTTPONLY = True # whether the Session cookie only supports http transmission  
    SESSION_COOKIE_AGE = 1209600 # Session of cookie expiration date (two weeks)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False # if you close the browser makes Session expired 
    SESSION_SAVE_EVERY_REQUEST = False # Whether to save the Session each request, only saved after modifying default

 

3. Configuration file 

a. 配置 settings.py
  
    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 authentication system 

auth module

from django.contrib import auth

 django.contrib.auth provides a number of methods, here we focus on three of them:

1 authenticate()   

Provides user authentication, which validates the username and password are correct, it normally takes two keyword arguments username password

If the authentication information is valid, it returns a User object. authenticate () will be provided on a User object attribute that identifies the user authentication backend authentication and the login information is later in the process is required. When we attempted to land a take out directly from the database without authenticate () User object will complain! !

user = authenticate(username='someone',password='somepassword')

2 login(HttpRequest, user)

This function takes an HttpRequest object and a User object certified

This function uses the session django framework of an authenticated user to attach the session id and other information.

 

from django.contrib.auth import authenticate, login
   
def my_view(request):
  username = request.POST['username']
  password = request.POST['password']
  user = authenticate(username=username, password=password)
  if user is not None:
    login(request, user)
    # Redirect to a success page.
    ...
  else:
    # Return an 'invalid login' error message.
    ...

 

3 logout (request) Logout

from django.contrib.auth import logout
   
def logout_view(request):
  logout(request)
  # Redirect to a success page.

This function takes a HttpRequest object, no return value. When the function is called, the current request will clear all session information. Even if the user is not logged in, use this function also does not complain.

4  is_authenticated()

Claim:

1 users logged in to access some of the pages,

2 If the user is not logged in to access this page, then skip directly to the login page

3 After the user completes the login screen landing the jump, the jump to automatically access addresses visited before

1

2

3

4

// 方法一

def my_view(request):

  if not request.user.is_authenticated():

    return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

 

# Django has been good for us to design a decorator for such situations: login_requier

from django.contrib.auth.decorators import login_required
      
@login_required
def my_view(request):
  ...

Copy the code

If the user is not logged, it will jump to the django default login URL '/ accounts / login /' (this value can be modified by LOGIN_URL in the settings file). And passing the current url to access the absolute path (after a successful landing, you will be redirected to the path).

User objects

User object properties: username, password (required) password saved to the database using a hash algorithm

is_staff: whether the user has administrative permissions for the site.

is_active: whether to allow user login, set to `` False``, you can not delete users to disable user login

2.1 is_authenticated()

If it is true the User object, the return value of the constant to True. For checking whether the user has passed the certification.
By certification does not mean that the user has no rights, not even check whether the user is in an active state, which only indicates the success of the certification by the user. This method is very important, () to determine whether the user has logged in with request.user.is_authenticated in the background, if true, you can display the front desk request.user.name

2.2 Creating a User

Create a user create_user helper:

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email='')

2.3 check_password(passwd)

用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

 

def change_password(request):
    if request.is_ajax():
        data = json.loads(request.POST.get('data'))
        oldPassword = data.get('oldPassword')
        newPassword = data.get('newPassword')
        confirmPassword = data.get('confirmPassword')
        if request.user.check_password(oldPassword):     # 判断旧密码是否正确
            request.user.set_password(newPassword)
            request.user.save()
            result = {'status': 0, "info": "密码修改登录成功!!"}
        else:
            result = {'status': 1, "info": "原密码不正确!!"}
        return HttpResponse(json.dumps(result))
    return render(request, 'changepassword.html')

 

2.4 Change Password

Use set_password () to change the password:

 

def change_password(request):
    if request.is_ajax():
        data = json.loads(request.POST.get('data'))
        oldPassword = data.get('oldPassword')
        newPassword = data.get('newPassword')
        confirmPassword = data.get('confirmPassword')
        if request.user.check_password(oldPassword):     # 判断旧密码是否正确
            request.user.set_password(newPassword)    # 设置密码
            request.user.save()
            result = {'status': 0, "info": "密码修改登录成功!!"}
        else:
            result = {'status': 1, "info": "原密码不正确!!"}
        return HttpResponse(json.dumps(result))
    return render(request, 'changepassword.html')

 

 Examples

 

 

from django.shortcuts import render, HttpResponse, redirect
from . import models
from utils import page
import json
from django.db.models import Count, Max
from django.contrib import auth
from django.contrib.auth.models import User


# Create your views here.

# 登录注册,验证, 注销
def login_auth(func):
    def inner(request, *args, **kwargs):
        if request.user.is_authenticated():
            return func(request, *args, **kwargs)
        else:
            return redirect('/app01/login/')
    return inner


def log_in(request):
    if request.is_ajax():
        path = request.GET.get('getUrl')
        if not path:
            path = '/app01/books/'
        data = json.loads(request.POST.get('data'))
        username = data.get('user')
        passwd = data.get('password')
        user = auth.authenticate(username=username, password=passwd)
        if user:
            auth.login(request, user)
            result = {'status': 0, 'path': path, "info": "{} 登录成功!!".format(user)}
        else:
            result = {'status': 1, "info": "账户或密码不正确!!"}
        return HttpResponse(json.dumps(result))
    else:
        return render(request, 'Signin.html')


def login_out(request):
    auth.logout(request)

    return redirect('/app01/login/')


def register(request):
    if request.is_ajax():
        data = json.loads(request.POST.get('data'))
        confirmPwd = data.pop('confirmPassword')
        User.objects.create_user(**data)
        redirect('/app01/login')
    return render(request, 'register.html')


def change_password(request):
    if request.is_ajax():
        data = json.loads(request.POST.get('data'))
        oldPassword = data.get('oldPassword')
        newPassword = data.get('newPassword')
        confirmPassword = data.get('confirmPassword')
        if request.user.check_password(oldPassword):
            request.user.set_password(newPassword)
            request.user.save()
            result = {'status': 0, "info": "密码修改登录成功!!"}
        else:
            result = {'status': 1, "info": "原密码不正确!!"}
        return HttpResponse(json.dumps(result))
    return render(request, 'changepassword.html')

Original link: https://www.cnblogs.com/wangyuanming/p/8028623.html

Published 24 original articles · won praise 30 · views 50000 +

Guess you like

Origin blog.csdn.net/yufen9987/article/details/89672856