Django 简明教程

Django - Sessions

如前所述,我们可以使用客户端 cookie 为 Web 应用程序存储大量有用的数据。我们之前已经看到,我们可以使用客户端 cookie 为 Web 应用程序存储各种有用的数据。这会产生许多安全漏洞,具体取决于你想要保存的数据的重要性。

As discussed earlier, we can use client side cookies to store a lot of useful data for the web app. We have seen before that we can use client side cookies to store various data useful for our web app. This leads to lot of security holes depending on the importance of the data you want to save.

出于安全原因,Django 有一个会话框架,用于处理 cookie。会话用于抽象 cookie 的接收和发送,数据保存在服务器端(如在数据库中),并且客户端 cookie 只拥有一个用于标识的会话 ID。会话对于避免用户浏览器设置为“不接受”cookie 的情况也很有用。

For security reasons, Django has a session framework for cookies handling. Sessions are used to abstract the receiving and sending of cookies, data is saved on server side (like in database), and the client side cookie just has a session ID for identification. Sessions are also useful to avoid cases where the user browser is set to ‘not accept’ cookies.

Setting Up Sessions

在 Django 中,会话启用在你的项目 settings.py 中完成,通过向 MIDDLEWARE_CLASSESINSTALLED_APPS 选项添加几行。这应该在创建项目时完成,但了解它总是好的,所以 MIDDLEWARE_CLASSES 应有:

In Django, enabling session is done in your project settings.py, by adding some lines to the MIDDLEWARE_CLASSES and the INSTALLED_APPS options. This should be done while creating the project, but it’s always good to know, so MIDDLEWARE_CLASSES should have −

'django.contrib.sessions.middleware.SessionMiddleware'

INSTALLED_APPS 应有:

And INSTALLED_APPS should have −

'django.contrib.sessions'

默认情况下,Django 将会话信息保存在数据库中(django_session 表或集合),但你可以配置引擎以使用其他方式存储信息,如在 filecache 中。

By default, Django saves session information in database (django_session table or collection), but you can configure the engine to store information using other ways like: in file or in cache.

当会话启用时,每个请求(Django 中任何视图的第一个参数)都会有一个会话(dict)属性。

When session is enabled, every request (first argument of any view in Django) has a session (dict) attribute.

我们创建一个简单的示例,看看如何创建和保存会话。我们之前构建了一个简单的登录系统(请参阅 Django 表单处理章节和 Django Cookie 处理章节)。让我们将用户名保存在一个 cookie 中,因此如果不是注销,在访问登录页面时,你将看不到登录表单。基本上,让我们通过在服务器端保存 cookie 来使我们在 Django Cookie 处理中使用的登录系统更加安全。

Let’s create a simple sample to see how to create and save sessions. We have built a simple login system before (see Django form processing chapter and Django Cookies Handling chapter). Let us save the username in a cookie so, if not signed out, when accessing our login page you won’t see the login form. Basically, let’s make our login system we used in Django Cookies handling more secure, by saving cookies server side.

为此,首先让我们更改登录视图以将我们的用户名 cookie 保存到服务器端:

For this, first lets change our login view to save our username cookie server side −

def login(request):
   username = 'not logged in'

   if request.method == 'POST':
      MyLoginForm = LoginForm(request.POST)

      if MyLoginForm.is_valid():
         username = MyLoginForm.cleaned_data['username']
         request.session['username'] = username
      else:
         MyLoginForm = LoginForm()

   return render(request, 'loggedin.html', {"username" : username}

然后,让我们为登录表单创建 formView 视图,如果设置了 cookie,我们不会显示表单:

Then let us create formView view for the login form, where we won’t display the form if cookie is set −

def formView(request):
   if request.session.has_key('username'):
      username = request.session['username']
      return render(request, 'loggedin.html', {"username" : username})
   else:
      return render(request, 'login.html', {})

现在,让我们更改 url.py 文件以更改该 URL,以便它与我们的新视图配对:

Now let us change the url.py file to change the url so it pairs with our new view −

from django.conf.urls import patterns, url
from django.views.generic import TemplateView

urlpatterns = patterns('myapp.views',
   url(r'^connection/','formView', name = 'loginform'),
   url(r'^login/', 'login', name = 'login'))

当你访问 /myapp/connection 时,你将看到以下页面:

When accessing /myapp/connection, you will get to see the following page −

setting up sessions

你将被重定向到以下页面:

And you will get redirected to the following page −

sessions redirected page

现在,如果你再次尝试访问 /myapp/connection,你将直接被重定向到第二个屏幕。

Now if you try to access /myapp/connection again, you will get redirected to the second screen directly.

我们创建一个简单的注销视图来抹除我们的 cookie。

Let’s create a simple logout view that erases our cookie.

def logout(request):
   try:
      del request.session['username']
   except:
      pass
   return HttpResponse("<strong>You are logged out.</strong>")

并将其与 myapp/url.py 中的注销 URL 配对:

And pair it with a logout URL in myapp/url.py

url(r'^logout/', 'logout', name = 'logout'),

现在,如果你访问 /myapp/logout,你将看到以下页面:

Now, if you access /myapp/logout, you will get the following page −

logged out page

如果你再次访问 /myapp/connection,你将获得登录表单(屏幕 1)。

If you access /myapp/connection again, you will get the login form (screen 1).

Some More Possible Actions Using Sessions

我们已经了解了如何存储和访问会话,但了解请求的会话属性还有一些其他有用的操作,如下所示:

We have seen how to store and access a session, but it’s good to know that the session attribute of the request have some other useful actions like −

  1. set_expiry (value) − Sets the expiration time for the session.

  2. get_expiry_age() − Returns the number of seconds until this session expires.

  3. get_expiry_date() − Returns the date this session will expire.

  4. clear_expired() − Removes expired sessions from the session store.

  5. get_expire_at_browser_close() − Returns either True or False, depending on whether the user’s session cookies have expired when the user’s web browser is closed.