djanjo book2 学习笔记 (会话 用户 和注册)

会话 用户 和注册在线手册地址
http://docs.oneele.com/django/topics


COOKIES
第一次打开浏览器,访问页面
Response Headers:
Set-Cookie:csrftoken=369caefb109c7a58ed947660ce99104b; expires=Fri, 27-Feb-2015 08:17:35 GMT; Max-Age=31449600; Path=/
Set-Cookie:csrftoken=8bc7a3911f266e87067ecf9dc71a26ec; expires=Fri, 27-Feb-2015 08:20:40 GMT; Max-Age=31449600; Path=/


Set-Cookie:sessionid=942fc061ff46f73b998e3f3e06ce2eb7; expires=Fri, 14-Mar-2014 08:22:17 GMT; Max-Age=1209600; Path=/


接下来再次访问同一个页面
Request Headers:
Cookie:csrftoken=369caefb109c7a58ed947660ce99104b


Cookie:csrftoken=8bc7a3911f266e87067ecf9dc71a26ec; sessionid=61183c29da0f03d5dbbe55e8c696afdc
Cookie:csrftoken=8bc7a3911f266e87067ecf9dc71a26ec; sessionid=942fc061ff46f73b998e3f3e06ce2eb7


from django.contrib.sessions.models import Session
s = Session.objects.get(sessionid='942fc061ff46f73b998e3f3e06ce2eb7')


是时候承认了: 我们有意的避开了Web开发中极其重要的方面。 到目前为止,我们都在假定,网站流量是大
量的匿名用户带来的。
这当然不对。 浏览器的背后都是活生生的人(至少某些时候是)。 这忽略了重要的一点: 互联网服务于人而不是
机器。 要开发一个真正令人心动的网站,我们必须面对浏览器后面活生生的人。
很不幸,这并不容易。 HTTP被设计为”无状态”,每次请求都处于相同的空间中。 在一次请求和下一次请求
之间没有任何状态保持,我们无法根据请求的任何方面(IP地址,用户代理等)来识别来自同一人的连续请求。
在本章中你将学会如何搞定状态的问题。 好了,我们会从较低的层次(cookies)开始,然后过渡到用高层的工
来搞定会话,用户和注册的问题。


Cookies
    浏览器的开发者在很早的时候就已经意识到, HTTP’s 的无状态会对Web开发者带来很大的问题,于是
    (cookies)应运而生。 cookies 是浏览器为 Web 服务器存储的一小段信息。 每次浏览器从某个服务器请求页
    时,它向服务器回送之前收到的cookies
    来看看它是怎么工作的。 当你打开浏览器并访问 google.com ,你的浏览器会给Google发送一个HTTP请求,
    起始部分就象这样:
        GET / HTTP/1.1
        Host: google.com
    ...
    当 Google响应时,HTTP的响应是这样的:
    HTTP/1.1 200 OK
        Content‐Type: text/html
        Set‐Cookie: PREF=ID=5b14f22bdaf1e81c:TM=1167000671:LM=1167000671;
                    expires=Sun, 17‐Jan‐2038 19:14:07 GMT;
                    path=/; domain=.google.com
        Server: GWS/2.1
        
        
Django的 Session 框架
    由于存在的限制与安全漏洞,cookies和持续性会话已经成为Web开发中令人头疼的典范。 好消息是,Django
    的目标正是高效的“头疼杀手”,它自带的session框架会帮你搞定这些问题。
    你可以用session 框架来存取每个访问者任意数据, 这些数据在服务器端存储,并对cookie的收发进行了抽
    象。 Cookies只存储数据的哈希会话ID,而不是数据本身,从而避免了大部分的常见cookie问题。
    下面我们来看看如何打开session功能,并在视图中使用它。
    


1)打开 Sessions功能
    Sessions 功能是通过一个中间件(参见第17章)和一个模型(model)来实现的。 要打开sessions功能,需要以下
    几步操作:
    1.  编辑 MIDDLEWARE_CLASSES 配置,确保 MIDDLEWARE_CLASSES 中包含
    'django.contrib.sessions.middleware.SessionMiddleware'。
    2.  确认 INSTALLED_APPS 中有 'django.contrib.sessions' (如果你是刚打开这个应用,别忘了运行
    manage.py syncdb )
    如果项目是用 startproject 来创建的,配置文件中都已经安装了这些东西,除非你自己删除,正常情况下,你
    无需任何设置就可以使用session功能。
    如果不需要session功能,你可以删除 MIDDLEWARE_CLASSES 设置中的 SessionMiddleware 和 INSTALLED_APPS 设
    置中的 'django.contrib.sessions' 。虽然这只会节省很少的开销,但积少成多啊。


2)在视图中使用Session
    SessionMiddleware 激活后,每个传给视图(view)函数的第一个参数``HttpRequest`` 对象都有一个 session 属
    性,这是一个字典型的对象。 你可以象用普通字典一样来用它。 例如,在视图(view)中你可以这样用:
    # Set a session value:
    request.session["fav_color"] = "blue"
    # Get a session value ‐‐ this could be called in a different view,
    # or many requests later (or both):
    fav_color = request.session["fav_color"]
    # Clear an item from the session:
    del request.session["fav_color"]
    # Check if the session has a given key:
    if "fav_color" in request.session:
    其他的映射方法,如 keys() 和 items() 对 request.session 同样有效:
    
在视图(View)外使用Session
    从内部来看,每个session都只是一个普通的Django model(在 django.contrib.sessions.models 中定义)。
    每个session都由一个随机的32字节哈希串来标识,并存储于cookie中。 因为它是一个标准的模型,所以你可
    以使用Django数据库API来存取session。
    >>> from django.contrib.sessions.models import Session
    >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
    >>> s.expire_date
    datetime.datetime(2005, 8, 20, 13, 35, 12)
    你需要使用get_decoded() 来读取实际的session数据。 这是必需的,因为字典存储为一种特定的编码格式。
    >>> s.session_data
    'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
    >>> s.get_decoded()
    {'user_id': 42}
    
何时保存Session
    缺省的情况下,Django只会在session发生变化的时候才会存入数据库,比如说,字典赋值或删除。
    # Session is modified.
    request.session['foo'] = 'bar'
    # Session is modified.
    del request.session['foo']
    # Session is modified.
    request.session['foo'] = {}
    # Gotcha: Session is NOT modified, because this alters
    # request.session['foo'] instead of request.session.
    request.session['foo']['bar'] = 'baz'
    你可以设置 SESSION_SAVE_EVERY_REQUEST 为 True 来改变这一缺省行为。
    如果置为True的话,Django会在每收到请求的时候保存session,即使没发生变化。
    注意,会话cookie只会在创建和修改的时候才会送出。 但如果 SESSION_SAVE_EVERY_REQUEST 设置为 True ,会
    话cookie在每次请求的时候都会送出。 同时,每次会话cookie送出的时候,其 expires 参数都会更新。
    
在setting 中设置
SESSION_COOKIE_AGE=60*30 30分钟。
SESSION_EXPIRE_AT_BROWSER_CLOSE False:会话cookie可以在用户浏览器中保持有效期。True:关闭浏览器,则Cookie失效。
SESSION_COOKIE_DOMAIN 生效站点
SESSION_COOKIE_NAME cookie中保存session的名称
Session使用比较简单,在request.session是一个字典类。session是保存在数据库中的。




浏览器关闭即失效会话 vs 持久会话
    你可能注意到了,Google给我们发送的cookie中有 expires=Sun, 17‐Jan‐2038 19:14:07 GMT; cookie可以有
    过期时间,这样浏览器就知道什么时候可以删除cookie了。 如果cookie没有设置过期时间,当用户关闭浏览器
    的时候,cookie就自动过期了。 你可以改变 SESSION_EXPIRE_AT_BROWSER_CLOSE 的设置来控制session框架的
    这一行为。
    
    缺省情况下, SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 False ,这样,会话cookie可以在用户浏览器中保持
    有效达 SESSION_COOKIE_AGE 秒(缺省设置是两周,即1,209,600 秒)。 如果你不想用户每次打开浏览器都必须
    重新登陆的话,用这个参数来帮你。
    如果 SESSION_EXPIRE_AT_BROWSER_CLOSE 设置为 True ,当浏览器关闭时,Django会使cookie失效。
    其他的Session设置
    除了上面提到的设置,还有一些其他的设置可以影响Django session框架如何使用cookie,详见表 14-2.
    
    表 14-2. 影响cookie行为的设置 设置描述缺省
    SESSION_COOKIE_DOMAIN使用会话cookie(session cookies)的站点。 将它设成一个 None
            字符串,就好象`` “.example.com”`` 以用于跨站点(cross-domain)的cookie,或`` None`` 以用于单个站点。
    SESSION_COOKIE_NAME会话中使用的cookie的名字。 它可以是任意的字符串。"sessionid"
    SESSION_COOKIE_SECURE是否在session中使用安全cookie。 如果设置 True , cookie就 False
    会标记为安全, 这意味着cookie只会通过HTTPS来传输。
    
技术细节
    如果你还是好奇的话,下面是一些关于session框架内部工作方式的技术细节:
    session 字典接受任何支持序列化的Python对象。 参考Python内建模块pickle的文档以获取更多信息。
    Session 数据存在数据库表 django_session 中
    Session 数据在需要的时候才会读取。 如果你从不使用 request.session , Django不会动相关数据库表的
    一根毛。
    Django 只在需要的时候才送出cookie。 如果你压根儿就没有设置任何会话数据,它不会 送出会话
    cookie(除非 SESSION_SAVE_EVERY_REQUEST 设置为 True )。
    Django session 框架完全而且只能基于cookie。 它不会后退到把会话ID编码在URL中(像某些工具
    (PHP,JSP)那样)。
    这是一个有意而为之的设计。 把session放在URL中不只是难看,更重要的是这让你的站点 很容易受到攻击
    ——通过 Referer header进行session ID”窃听”而实施的攻击。
    如果你还是好奇,阅读源代码是最直接办法,详见 django.contrib.sessions 。
    
登录和退出
    Django 提供内置的视图(view)函数用于处理登录和退出 (以及其他奇技淫巧),但在开始前,我们来看看如何
    和退出。 Django提供两个函数来执行django.contrib.auth\中的动作 : authenticate()
    和login()。
    认证给出的用户名和密码,使用 authenticate() 函数。它接受两个参数,用户名 username 和 密码
    password ,并在密码对给出的用户名合法的情况下返回一个 User 对象。 如果密码不合法,authenti
    回None。
    >>> from django.contrib import auth
    >>> user = auth.authenticate(username='john', password='secret')
    >>> if user is not None:
    ...     print "Correct!"
    ... else:
    ...     print "Invalid password."
    authenticate() 只是验证一个用户的证书而已。 而要登录一个用户,使用 login() 。该函数接受一个
    HttpRequest 对象和一个 User 对象作为参数并使用Django的会话( session )框架把用户的ID保存在
    中。
    下面的例子演示了如何在一个视图中同时使用 authenticate() 和 login() 函数:
    from django.contrib import auth
    def login_view(request):
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        user = auth.authenticate(username=username, password=password)
        if user is not None and user.is_active:
            # Correct password, and the user is marked "active"
            auth.login(request, user)
            # Redirect to a success page.
            return HttpResponseRedirect("/account/loggedin/")
        else:
            # Show an error page
            return HttpResponseRedirect("/account/invalid/")
    注销一个用户,在你的视图中使用 django.contrib.auth.logout() 。 它接受一个HttpRequest对象并
    回值。
    from django.contrib import auth
    def logout_view(request):
        auth.logout(request)
        # Redirect to a success page.
        return HttpResponseRedirect("/account/loggedout/")
    注意,即使用户没有登录, logout() 也不会抛出任何异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值