Django之session验证的三种姿势
Posted exman
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之session验证的三种姿势相关的知识,希望对你有一定的参考价值。
一.什么是session
session是保存在服务端的键值对,Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
二.FVB中使用装饰器进行session验证
认证装饰器:
1
2
3
4
5
6
7
8
9
10
|
# 登陆验证 def auth(func): ‘‘‘判断是否登录装饰器‘‘‘ def inner(request, * args, * * kwargs): ck = request.session.get( "username" ) ‘‘‘如果没有登陆返回到login.html‘‘‘ if not ck: return redirect( "/login.html" ) return func(request, * args, * * kwargs) return inner |
在需要认证的函数执行前加上装饰器认证即可,实际中应用如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
def login(request): if request.method = = "GET" : return render(request, "login.html" ) else : username = request.POST.get( "user" ) pwd = request.POST.get( "pwd" ) pwd = md5(pwd) dic = { "flag" : False } obj = User.objects. filter (username = username, pwd = pwd).first() if obj: request.session[ "username" ] = username return redirect( "/index.html" ) else : print (dic) return HttpResponse(json.dumps(dic)) @auth def index(request): user = request.session.get( "username" ) business = Business.objects. all ().values( "name" ) host_list = Host.objects. all ().values( "id" , "host" , "port" , "business__name" ) username = User.objects. all ().values( "username" ) return render(request, ‘index.html‘ , { ‘host_list‘ :host_list, "business" :business, "user" :user, "username" :username}) @auth def addhost(request): business = Business.objects. all ().values( "name" ) if request.method = = "POST" : user = request.session.get( "username" ) host = request.POST.get( "host" ) port = request.POST.get( "port" ) select_business = request.POST.get( "business" ) business_id = Business.objects. filter (name = select_business).values( "id" )[ 0 ] host = Host.objects.create(host = host, port = port, business_id = business_id[ "id" ]) # host.business.add(*business) return render(request, "index.html" ) return render(request, "index.html" , { "business" :business}) @auth def up_business(request): if request.method = = "POST" : user = request.session.get( "username" ) host = request.POST.get( "host" ) port = request.POST.get( "port" ) business_name = request.POST.get( "business" ) username = request.POST.get( "username" ) print (host,port,business_name,username) return render(request, "保存成功" ) |
三.CBV中使用类继承的方式进行session认证
- cbv是 class based view(基于类)
- cbv基于dispatch进行反射,get获取,post提交
- 应用场景:登录认证(继承dispatch,在dispatch里做session验证)
CBV第一种方式继承
1.单继承
扫盲:(继承的时候,一定要清楚self是哪个类实例化出来的对象,下例,self为B实例化的对象,任何属性优先从自己里面找,找不到在去父类里找)
1
2
3
4
5
6
7
8
9
10
11
12
|
class A( object ): def aaa( self ): print ( ‘from A‘ ) def bbb( self ): self .aaa() class B(A): def aaa( self ): print ( ‘from B‘ ) c = B() c.aaa() |
应用:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from django.views import View class BaseView(View): def dispatch( self , request, * args, * * kwargs): # 继承父类的dispatch,因为父类里有返回值,所以也要有return if request.session.get( ‘username‘ ): response = super (BaseView, self ).dispatch(request, * args, * * kwargs) return response else : return redirect( ‘/login.html‘ ) class IndexView(BaseView): def get( self , request, * args, * * kwargs): return HttpResponse(request.session[ ‘username‘ ]) |
2.多继承(继承顺序从左到右)
1
2
3
4
5
6
7
8
9
10
11
12
|
class BaseView( object ): def dispatch( self , request, * args, * * kwargs): if request.session.get( ‘username‘ ): response = super (BaseView, self ).dispatch(request, * args, * * kwargs) return response else : return redirect( ‘/login.html‘ ) class IndexView(BaseView,View): #先去找BaseView,BaseView中未定义在去找View def get( self ,request, * args, * * kwargs): return HttpResponse(request.session[ ‘username‘ ]) |
CBV第二种方式装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
from django.utils.decorators import method_decorator def auth(func): #定义装饰器 def inner(request, * args, * * kwargs): if request.session.get( ‘username‘ ): obj = func(request, * args, * * kwargs) return obj else : return redirect( ‘/login.html‘ ) return inner @method_decorator (auth,name = ‘get‘ ) #放在类顶部就需要method_decorator这个装饰器 class IndexView(View): @method_decorator (auth) #放在dispatch上就相当于全局都需要经过认证 def dispatch( self , request, * args, * * kwargs): if request.session.get( ‘username‘ ): response = super (IndexView, self ).dispatch(request, * args, * * kwargs) return response else : return redirect( ‘/login.html‘ ) @method_decorator (auth) def get( self ,request, * args, * * kwargs): return HttpResponse(request.session[ ‘username‘ ]) @method_decorator (csrf_exempt) # 无效 csrf 放到post函数上的装饰器,是无效的,需要放到dispath上或者类上 def post( self ,request, * args, * * kwargs): return HttpResponse(request.session[ ‘username‘ ]) |
四.中间件middleware
如下是django的生命周期
如下为中间件的执行顺序
- 中间件执行时机:请求到来,请求返回时
- 中间件是一个类:
def process_request(self,request):
print(‘m2.process_request‘)
def process_response(self,request, response):
print(‘m2.prcess_response‘)
return response
- 应用:
- 请求日志
- 用户登录认证
Django根目录新建md文件夹,新建Middleware.py文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from django.utils.deprecation import MiddlewareMixin class M1(MiddlewareMixin): ‘‘‘先执行request,然后到url路由,url之后返回到最上方,在执行view,如果出现错误就直接到response上,执行完,到真正到视图,如果有问题就 执行exception,从下至上查找,如果找到exception就直接执行exception的return在走response返回用户 每个中间件中,4个方法不需要都写. ‘‘‘ def process_request( self ,request): if request.path_info = = "/login.html" : return None user_info = request.session.get( "username" ) if not user_info: return redirect( "/login.html" ) |
注:新的django版本可能不存在MiddlewareMixin,需要手动写一下这个类进行继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class MiddlewareMixin( object ): def __init__( self , get_response = None ): self .get_response = get_response super (MiddlewareMixin, self ).__init__() def __call__( self , request): response = None if hasattr ( self , ‘process_request‘ ): response = self .process_request(request) if not response: response = self .get_response(request) if hasattr ( self , ‘process_response‘ ): response = self .process_response(request, response) return response class M1(MiddlewareMixin): def process_request( self ,request): if request.path_info = = "/login.html" : return None user_info = request.session.get( "username" ) if not user_info: return redirect( "/login.html" ) |
settings里配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
MIDDLEWARE = [ ‘django.middleware.security.SecurityMiddleware‘ , ‘django.contrib.sessions.middleware.SessionMiddleware‘ , ‘django.middleware.common.CommonMiddleware‘ , ‘django.middleware.csrf.CsrfViewMiddleware‘ , ‘django.contrib.auth.middleware.AuthenticationMiddleware‘ , ‘django.contrib.messages.middleware.MessageMiddleware‘ , ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘ , ‘md.Middleware.M1‘ , ] WSGI_APPLICATION = ‘BBS.wsgi.application‘ SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 引擎(默认) 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 = True # 是否每次请求都保存Session,默认修改之后才保存(默认) |
以上是关于Django之session验证的三种姿势的主要内容,如果未能解决你的问题,请参考以下文章