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='加密盐',...)
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
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
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:
. 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.
Flow analysis chart
Examples
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 |
|
# 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):
...
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