Django之session验证的三种姿势

一.什么是session

session是保存在服务端的键值对,Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

二.FVB中使用装饰器进行session验证

认证装饰器:

# 登陆验证
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

 在需要认证的函数执行前加上装饰器认证即可,实际中应用如下:

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实例化的对象,任何属性优先从自己里面找,找不到在去父类里找)

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()

应用:

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.多继承(继承顺序从左到右)

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第二种方式装饰器

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文件

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,需要手动写一下这个类进行继承

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里配置:

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,默认修改之后才保存(默认)
时间: 2024-11-09 00:55:37

Django之session验证的三种姿势的相关文章

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

django之创建第7-6-第三种传值方式

1.创建bar.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>time</title> </head> <body> <li>1.当前时间:{{today}}</li><br> <li>my id:{{id}}<

HDU1233 - 还是畅通工程 最小生成树,用了三种姿势AC

HDU1233 - 还是畅通工程 : http://acm.hdu.edu.cn/showproblem.php?pid=1233 用了三种姿势AC这题之后, 感觉对最小生成树的理解又更深了一层. 嗯, 让你们看看我用的是哪三种姿势 方法 1 : #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const in

JSP中设置Session有效时间的三种方式

JSP中设置Session有效时间的三种方式 2010-08-03 10:02:49|  分类: Java Web|举报|字号 订阅 (1)在主页面或者公共页面中加入: HttpSession session=request.getSession(true); session.setMaxInactiveInterval(900);参数900单位是秒,即在没有活动15分钟后,session将失效.这里要注意这个session设置的时间是根据服务器来计算的,而不是客户端.所以如果是在调试程序,应该

cookie 和 session的区别 &amp; 三种传值方式

1.session保存在服务器,客户端不知道其中的信息:cookie保存在客户端,服务器能够知道其中的信息. 2.session中保存的是对象,cookie中保存的是字符串. 3.session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到.而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的. 4.session以cookie为基础,session需要借助cookie才能正常工作,如果客户端完全禁止cookie

【bzoj3224】Tyvj 1728 普通平衡树 平衡树的三种姿势 :splay,Treap,ScapeGoat_Tree

直接上代码 正所谓 人傻自带大常数 平衡树的几种姿势:  AVL Red&Black_Tree 码量爆炸,不常用:SBT 出于各种原因,不常用. 常用: Treap 旋转 基于旋转操作和随机数堆 但不支持区间操作. 非旋转 基于随机数堆和拆分合并操作 常数较大 Spaly 完全基于旋转 各种操作 ScapeGoat_Tree 基于a权值平衡树和压扁重构 无旋转 但不支持区间操作 PS:非旋转可以实现平衡树的可持久化,从而来套一些东西 splay #include<cstdio> #de

关于 tomcat 集群中 session 共享的三种方法

前两种均需要使用 memcached 或 redis 存储 session ,最后一种使用 terracotta 服务器共享. 建议使用 redis ,不仅仅因为它可以将缓存的内容持久化,还因为它支持的单个对象比较大,而且数据类型丰富, 不只是缓存 session ,还可以做其他用途,一举几得啊. 1.使用 filter 方法存储 这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于 tomcat ,而且实现的原理比较简单容易控制. 可以使用 memcached-session-filter

ASP.NET中身份验证的三种方法

Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活.Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cookie一起发送到服务端.服务端上的授权设置就可以根据不同目录对不同用户的访问授权进行控制了. 问题来了,在实际是用中我们往往需要的是基于角色,或者说基于用户组的验

Tomcat实现session保持的三种方式、使用msm方式搭建jsp网站

Tomcat简单的来说类似于php的功能,主要实现java程序的编译,最后呈现给用户的是html格式的代码,使用用户可以在浏览器中访问.Tomcat是Java语言研发的,所以依赖于java的虚拟机(jvm). 一.使用前端调度器实现实现session保持 实现的原理如下图,会话保持使用前端的调度器实现.例如:使用Ngnix调度时,使用ip_hash算法就可以实现. 配置步骤: 1.安装配置 Tomcat 操作系统: CentOS 6,5 目标主机:172.16.10.122  172.10.10