Cookie, session and auth for user authentication

1. Introduction to cookies and sessions

The cookie does not belong to the scope of the http protocol. Since the http protocol cannot maintain the state, but in reality, we need to "keep the state", so the cookie was born in such a scenario.

The working principle of the cookie is: the server generates the content, and the browser saves it locally after receiving the request; when the browser accesses again, the browser will automatically bring the cookie, so that the server can judge the "who is" through the content of the cookie. ".


Although the cookie solves the requirement of "maintaining state" to a certain extent, since the cookie itself supports a maximum of 4096 bytes, and the cookie itself is stored in the client, it may be intercepted or stolen, so a new thing is needed that can Support more bytes, and he is stored in the server, with higher security. This is the session.


To sum up: cookies make up for the lack of statelessness of http, and let the server know who is coming; but cookies are stored locally in the form of text, and their own security is poor; so we use cookies to identify different users, Correspondingly, private information and more than 4096 bytes of text are stored in the session.


2. Simple use of cookies

1. Get cookies

request.COOKIES.get("islogin",None) #If there is, get it, if not, it defaults to none

2. Set cookies

  obj = redirect("/index/")

  obj.set_cookie("islogin",True) #Set the cookie value, pay attention to the parameters here, one is the key and the other is the value

  obj.set_cookie("haiyan","344",20) #20 represents the expiration time

  obj.set_cookie("username", username)

3. Delete cookies

obj.delete_cookie("cookie_key",path="/",domain=name) #path is defined to take effect on those paths, / means for all url paths

4. Advantages and disadvantages of cookies

Advantages: Data is stored on the client side. Reduce the pressure on the server and improve the performance of the website

Disadvantages: low security, it is easy to view or crack user session information on the client side


5. Example of cookie login

Models.py file content:

class UserInfo(models.Model):
    username =models.CharField(max_length=32)
    password =models.CharField(max_length=32)


urls.py file content:

from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^index/', views.index),
]


views.py file content:

from django.shortcuts import render,redirect,HttpResponse
from app01 import models

def login(request):
    if request.method=="POST":
        print("All request data", request.POST)
        username = request.POST.get("username")
        password = request.POST.get("password")
        ret = models.UserInfo.objects.filter(username=username,password=password) #Determine whether the user input is the value in the database
        if ret: #If the username and password are correct, the login is successful
            print(request.COOKIES)
            obj = redirect("/index/")
            obj.set_cookie("islogin",True) #Set the cookie value to keep the state, pay attention to the parameters here, one is the key and the other is the value
            obj.set_cookie("haiyan","344",20) #20 represents the expiration time
            obj.set_cookie("username", username)
            return obj
        else:
            return render(request,"login.html")
    else:
        return render(request,"login.html")
def index(request):
    is_login = request.COOKIES.get("islogin",None) #Get the cookie, get it if you have it, get none if you don't
    if is_login:
        username = request.COOKIES.get("username")
        return render(request,"index.html",{"username":username})
    else:
        return redirect("/login/")


login.html file content:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>User login</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <style>
        .c1{
            margin-top: 100px;
        }
        .btn {
            width: 130px;
        }
        .c2{
            margin-left: 40px;
        }
    </style>
</head>
<body>
<div>
    <div>
        <div class="c1 col-md-5 col-md-offset-3">
            <form action="/login/" method="post" novalidate>
                {% csrf_token %}
                <div>
                    <label for="username" class="col-sm-2 control-label">用户名</label>
                    <div>
                        <input type="email" id="username" placeholder="Email" name="username">
                    </div>
                </div>
                <div>
                    <label for="password" class="col-sm-2 control-label">密码</label>
                    <div>
                        <input type="password" name="password" id="password"
                               placeholder="Password">
                    </div>
                </div>
                <div>
                    <div class="col-sm-offset-2 col-sm-10">
                        <button type="submit" class="btn btn-primary">登录</button>
                        <button type="submit" class="btn btn-success c2">注册</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
</html>


index.html file content:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
</head>
<body>
<h1>hello{{ username }}</h1>
</body>
</html>


3. Simple use of session

1. Set the session value

    request.session["session_name"]="admin"

2. Get session value

    session_name = request.session("session_name")

3. Delete session value

    del request.session["session_name"] deletes a set of key-value pairs

    request.session.flush() deletes a record

4. Check whether the session value is manipulated

    if "session_name"  is request.session:

5. Random string of user session

        request.session.session_key


        # Delete all data whose session expiration date is less than the current date

        request.session.clear_expired()

        # Check if the random string of the user session is in the database

        request.session.exists("session_key")

        # Delete all session data of the current user

        request.session.delete("session_key")


        request.session.set_expiry(value)

            * If value is an integer, the session will expire after a few seconds.

            * If value is a datatime or timedelta, the session will expire after this time.

            * If the value is 0, the user closes the browser session will be invalid.

            * If the value is None, the session will rely on the global session invalidation policy.


6. Session process analysis

The session will save the information on the server, usually the session and the cookie are used together.

(1) session settings

request.session["user_id"]=user.pk
request.session["username"]=user.user
The internal implementation mechanism is as follows:
'''
if request.COOKIE.get("sessionid"): #The browser can get the sessionid and update it
    Update the value of sessionid
else:
    {"user_id": 1, "username": "wang"}
    Step 1: Generate a random string: vwerascxh24asdasdasdsd
    Step 2: Generate a record in the django-session table:
    session - key             vwerascxh24asdasdasdsd
    session - data            {"user_id": 1, "username": "wang"}
    third step:
    obj.set_cookie("sessionid", vwerascxh24asdasdasdsd)
'''


(2) Session acquisition

request.session.get("user_id")
'''
Step 1: request.COOKIE.get("sessionid"):vwerascxh24asdasdasdsd
Step 2: Query a record in the django-session table: session-key=vwerascxh24asdasdasdsd
第三步: session-data({"user_id":1,"username":"alex"}).get("user_id")
'''


7. Session login example

views.py file content:

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:
            request.session['is_login'] = 'true' #Define session information
            request.session['username'] = username
            return redirect('/backend/') ## If the login is successful, redirect the url to the url in the background
    return render(request, 'login.html')
def backend(request):
    print(request.session, "------cookie")
    print(request.COOKIES, '-------session')
    """
    Here, the value of is_login must be set to False by default with the get() method of reading the dictionary. When the user accesses the backend url, first try to obtain the corresponding session of the browser.
    The value of is_login. If the other party logs in successfully, the value of is_login has been changed to True in the login, otherwise this value is False
    """
    is_login = request.session.get('is_login', False)
    if is_login: # If true, it means the user is logged in normally
        cookie_content = request.COOKIES
        session_content = request.session
        username = request.session['username']
        return render(request, 'backend.html', locals())
    else:
        return redirect('/login/')
def log_out(request):
    """
    When returning directly through request.session['is_login'], if the value corresponding to is_login does not exist, it will cause a program exception. So you need to do exception handling
    """
    try:
        del request.session['is_login'] # Delete the value corresponding to is_login
        #request.session.flush() # Delete the corresponding row in the django-session table
    except KeyError:
        pass
    return redirect('/login/') #Redirect back to the login page

login.html file content:

<!DOCTYPE html>
<html>
<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>

content of backend.html file:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>hello {{ username }}</h3>
<a href="/logout/">注销</a>
</body>
</html>

Fourth, the auth module

auth_user #Saves the user information required for user authentication

python manage.py createsuperuser #Create a super user command, and then enter relevant information according to the prompts, the information is saved in auth_user

from django.contrib import auth #import module


1. authenticate(): Verify that the username and password entered by the user are the same

Provides user authentication, that is, to verify whether the user name and password are correct, generally need two keyword parameters username and password

If the authentication information is valid, a User object is returned. authenticate() will set an attribute on the User object to identify which authentication backend authenticated the user, and this information is required in the subsequent login process.

2. login(HttpRequest, user): login  

This function accepts an HttpRequest object, and an authenticated User object

This function uses Django's session framework to attach information such as session id to an authenticated user.

3. logout (request) to log out the user 

This function accepts an HttpRequest object and returns no value. When this function is called, the session information of the current request will be cleared. Even if the user is not logged in, using this function will not report an error.

4. is_authenticated() of the user object

Require:

(1) Users can only access certain pages after logging in

(2) If the user visits the page without logging in, jump directly to the login page

(3) After the user completes the login in the jumped login interface, the user will automatically access and jump to the previously accessed address

def my_view(request):

    if not request.user.is_authenticated():

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


5. User object

User object attributes: username, password (required) password is saved to the database with a hash algorithm

is_staff : Whether the user has administrative rights to the site.

is_active : Whether to allow the user to log in, set to ``False``, you can prohibit the user from logging in without deleting the user


1、is_authenticated()

If it is a real User object, the return value is always True. Used to check whether the user has been authenticated.

Authenticating does not mean that the user has any permissions, nor even checking if the user is active, it just means that the user has successfully authenticated. This method can use request.user.is_authenticated() to determine whether the user is logged in, if true, request.user.name can be displayed to the front desk


2. Create a user: create_user

from django.contrib.auth.models import User

user = User.objects.create_user(username='',password='',email='')

3. Modify the password: set_password()

user = User.objects.get(username='')

user.set_password(password='')

user.save 


Six, based on the auth module to achieve user authentication

urls.py file content:

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^index/', views.index),
    url(r'^logout/', views.logout),
    url(r'^reg/', views.reg),
]

views.py文件内容:

from django.shortcuts import render,redirect
from django.contrib import auth
from django.contrib.auth.models import User
def login(request):
    if request.method=="POST":
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")
        print("before", request.user)
        user=auth.authenticate(username=user,password=pwd)
        if user:
            auth.login(request,user)                   # request.user:当前登录对象
            return redirect("/index/")
        else:
            s = "用户名和密码输入错误"
            return render(request, "login.html", {"s": s})
    return render(request,"login.html")
def index(request):
    if not request.user.username:
        return redirect("/login/")
    print(request.user)
    name=request.user.username
    return render(request,"index.html",{"name":name})
def logout(request):
    auth.logout(request)
    return redirect("/login/")
def reg(request):
    if request.method=="POST":
        username = request.POST.get("username")
        password = request.POST.get("password")
        User.objects.create_user(username=username,password=password)           #得到用户输入的用户名和密码创建一个新用户
        s = "恭喜你注册成功,现在可以登录了"
        return redirect("/login/")
    return render(request,"reg.html")


login.html文件内容:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    用户名 <input type="text" name="user">
    密码 <input type="password" name="pwd">
    <input type="submit">
</form>
</body>
</html>

index.html文件内容:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<h3>hi {{ name }}</h3>
<a href="/logout/">注销</a>
</body>
</html>





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325341123&siteId=291194637