惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
H
Heimdal Security Blog
K
Kaspersky official blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Schneier on Security
G
GRAHAM CLULEY
U
Unit 42
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
CERT Recently Published Vulnerability Notes
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
C
Cisco Blogs
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
Security Archives - TechRepublic
Security Archives - TechRepublic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
V
Visual Studio Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
Jina AI
Jina AI
P
Proofpoint News Feed
P
Proofpoint News Feed
有赞技术团队
有赞技术团队
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Application and Cybersecurity Blog
Application and Cybersecurity Blog
IT之家
IT之家
S
Security Affairs
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
N
News | PayPal Newsroom
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
W
WeLiveSecurity
The Last Watchdog
The Last Watchdog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
NISL@THU
NISL@THU

博客园 - Jason Cui

求助:SQL Server 2005数据库修复后无法收缩 用Bugols管理自己的项目 请教:为何Asp.net网站会自己弹出用户名密码输入框? 中文在线Bug管理系统 为什么要创建“理财易”? 继续招聘,请个好用的人可真难啊。 招聘两个Asp.net程序员 记账理财网站列表,用户自己挑一个用吧 坚持,究竟有多难? 又改了一次Django的源代码 请教,关于跨站提交的问题,和网站恶意抓取的防止 请教一个有关反射和缓存的高难度问题 诚聘:Asp.net高级技术人员两名 修改了一下Django的源码 幸亏没有选择Ruby On Rails 关于委托的一次实践 Django运行环境配置 Django学习笔记 Python下的Lucene,PyLucene
Django:更简单的实现记住密码功能
Jason Cui · 2007-10-29 · via 博客园 - Jason Cui

Django的设计里,Session的保存是借助Cookie的,Cookie的保存默认有两种周期,浏览器生命周期和14天周期。这两者的选择在settings.py里面的一个参数,设成True就是前者,设成False就是后者。但是,我们通常的需求是用户登录的时候可以选择是否记住登录,如果不选就是前者,如果选中,就使用后者,但是Django却没有留下这个接口。
在我以前的文章里面,是通过直接修改Django的源代码,改了它的sessionMiddleware来解决的,今天在浏览它的google group的时候,终于找到了一个比较正规的方法。其实其原理跟我那个方法是完全一样的,修改sessionMiddleware,让它在设置Cookie之前从当前的session里面读取一个值,看看是否要记住密码,从而控制生成哪一个周期的Cookie。
但是他的做法就比我要高明了,我的做法直接修改了Django的源代码,所以导致每次升级的时候会很麻烦,因为会覆盖以前的修改。但是他的做法是自己重新写了一个sessionMiddleware,基本上,这个文件应该就是直接把原来的拷了出来,然后做修改。只要在settings文件中指定这个middleware的类,让你的项目使用自己的这个就可以了。这样,系统自己的就完全被忽略掉了。
想来想去,还是把代码附上吧,以防万一:

 1from django.conf import settings
 2from django.contrib.sessions.models import Session
 3from django.contrib.sessions.middleware import SessionWrapper
 4from django.utils.cache import patch_vary_headers
 5import datetime
 6
 7class DualSessionMiddleware(object):
 8    """Session middleware that allows you to turn individual browser-length 
 9    sessions into persistent sessions and vice versa.
10    
11    This middleware can be used to implement the common "Remember Me" feature
12    that allows individual users to decide when their session data is discarded.
13    If a user ticks the "Remember Me" check-box on your login form create
14    a persistent session, if they don't then create a browser-length session.
15    
16    This middleware replaces SessionMiddleware, to enable this middleware:
17    - Add this middleware to the MIDDLEWARE_CLASSES setting in settings.py, 
18      replacing the SessionMiddleware entry.
19    - In settings.py add this setting: 
20      PERSISTENT_SESSION_KEY = 'sessionpersistent'
21    - Tweak any other regular SessionMiddleware settings (see the sessions doc),
22      the only session setting that's ignored by this middleware is 
23      SESSION_EXPIRE_AT_BROWSER_CLOSE. 
24      
25    Once this middleware is enabled all sessions will be browser-length by
26    default.
27    
28    To make an individual session persistent simply do this:
29    
30    session[settings.PERSISTENT_SESSION_KEY] = True
31    
32    To make a persistent session browser-length again simply do this:
33    
34    session[settings.PERSISTENT_SESSION_KEY] = False
35    """
36    
37    def process_request(self, request):
38        request.session = SessionWrapper(request.COOKIES.get(settings.SESSION_COOKIE_NAME, None))
39
40    def process_response(self, request, response):
41        # If request.session was modified, or if response.session was set, save
42        # those changes and set a session cookie.
43        patch_vary_headers(response, ('Cookie',))
44        try:
45            modified = request.session.modified
46        except AttributeError:
47            pass
48        else:
49            if modified or settings.SESSION_SAVE_EVERY_REQUEST:
50                session_key = request.session.session_key or Session.objects.get_new_session_key()
51                
52                if not request.session.get(settings.PERSISTENT_SESSION_KEY, False):
53                    # session will expire when the user closes the browser
54                    max_age = None
55                    expires = None
56                else:
57                    max_age = settings.SESSION_COOKIE_AGE
58                    expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT")
59                
60                new_session = Session.objects.save(session_key, 
61                                                   request.session._session,
62                                                   datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE))
63                response.set_cookie(settings.SESSION_COOKIE_NAME, session_key,
64                                    max_age = max_age, expires = expires, 
65                                    domain = settings.SESSION_COOKIE_DOMAIN,
66                                    secure = settings.SESSION_COOKIE_SECURE or None)
67        return response
68