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' )
  
=  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,默认修改之后才保存(默认)

转载于:https://www.cnblogs.com/ExMan/p/9473814.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值