python基础九 session

session

Session是服务器端技术,利用这个技术,服务器在运行时可以 为每一个用户的浏览器创建一个其独享的session对象,由于 session为用户浏览器独享,所以用户在访问服务器的web资源时 ,可以把各自的数据放在各自的session中,当用户再去访问该服务器中的其它web资源时,其它web资源再从用户各自的session中 取出数据为用户服务。

Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。


django中操作session

#取值
request.session['k1'] 
request.session.get('k1',None)  # 将django-session表里面的对应sessionid的值的那条记录中的session-data字段的数据给你拿出来(并解密),get方法就取出k1这个键对应的值

#设置值
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在则不设置
#帮你生成随机字符串,帮你将这个随机字符串和用户数据(加密后)和过期时间保存到了django-session表里面,帮你将这个随机字符串以sessionid:随机字符串的形式添加到cookie里面返回给浏览器,

#删除值
del request.session['k1']  #django-session表里面同步删除


# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()

# 会话session的key
session_key = request.session.session_key  获取sessionid的值

# 将所有Session失效日期小于当前日期的数据删除,将过期的删除
request.session.clear_expired()

# 检查会话session的key在数据库中是否存在
request.session.exists("session_key") #session_key就是那个sessionid的值

# 删除当前会话的所有Session数据
request.session.delete()

# 删除当前的会话数据并删除会话的Cookie。
request.session.flush()  #常用,清空所有cookie---删除session表里的这个会话的记录,
    这用于确保前面的会话数据不可以再次被用户的浏览器访问
    例如,django.contrib.auth.logout() 函数中就会调用它。

# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略。
    

session登陆实例

# base session of login
def login(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        pwd = request.POST.get('pwd')
        if name == 'alex' and pwd == '3714':
            # print(request.session)
            # < django.contrib.sessions.backends.db.SessionStore object at 0x000000419351AA58 >
            request.session['is_login'] = True
            request.session['name'] = 'lei'
            return redirect('index')
        else:
            return redirect('login')
    return render(request, 'login.html')
def index(request):
    print(request.session)
    # < django.contrib.sessions.backends.db.SessionStore object at 0x00000089AC457C88 >
    u = request.session.get('name', 'haohao')
    if u == 'lei':
        return render(request, 'index.html')
    else:
        return redirect('login')     

退出登陆实例

def logout(request):
    request.session.flush()
    return redirect('login')


django中的session配置

1. 数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

2. 缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 

4. 缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

其他公用设置项:
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,默认修改之后才保存(默认)

登陆验证加装饰器

基于fbv的装饰器

def login(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        pwd = request.POST.get('pwd')
        if name == 'alex' and pwd == '3714':
            # print(request.session)
            # < django.contrib.sessions.backends.db.SessionStore object at 0x000000419351AA58 >
            request.session['is_login'] = True
            request.session['name'] = 'lei'
            return redirect('index')
        else:
            return redirect('login')
    return render(request, 'login.html')


def check_login(func):
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get('name', '') == 'lei':
            return func(request, *args, **kwargs)
        else:
            return redirect(f"/login/?next={next_url}")
    return inner

@check_login
def index(request):
    return render(request, 'index.html')

基于cbv的装饰器

加载cbv视图的get或者post方法上
url.py
url(r'^index3/', views.index3.as_view(), name='index3'),

views.py
from django.utils.decorators import method_decorator
from django.views import View


def check_login(func):
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get('name', '') == 'lei':
            return func(request, *args, **kwargs)
        else:
            return redirect(f"/login/?next={next_url}")
    return inner

class index3(View):
    @method_decorator(check_login)
    def get(self, request):
        return render(request, 'index.html')
加在dispath方法上
class index3(View):
    @method_decorator(check_login)
    def dispatch(self, request, *args, **kwargs):
        return super(index3, self).dispatch(request, *args, **kwargs)
    
    def get(self, request):
        return render(request, 'index.html')

因为CBV中首先执行的就是dispatch方法,所以这么写相当于给get和post方法都加上了登录校验。

加在视图类上,method_decorator必须传name关键字参数

如果get方法和post方法都需要登录校验的话就写两个装饰器。

from django.utils.decorators import method_decorator

@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):

    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")
补充

CSRF Token相关装饰器在CBV只能加到dispatch方法上,或者加在视图类上然后name参数指定为dispatch方法。

备注:

csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator


class HomeView(View):

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

或者

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator


@method_decorator(csrf_exempt, name='dispatch')
class HomeView(View):
   
    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

posted @ 2019-08-25 12:16  Pyter  阅读(340)  评论(0)    收藏  举报