Index: django/contrib/csrf/middleware.py
===================================================================
--- django/contrib/csrf/middleware.py	(revision 10663)
+++ django/contrib/csrf/middleware.py	(working copy)
@@ -27,6 +27,28 @@
 def _make_token(session_id):
     return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()
 
+def _get_validated_session_id(request):
+    # This function might be called by a template tag. So, we don't make the
+    # session framework a requirement, otherwise people would have to change
+    # their templates if they disabled the session middleware
+    if hasattr(request, 'session'):
+        # Code that can create a session key will update
+        # request.session.session_key, so we don't need to check the outgoing
+        # response for cookies, request.session will reflect the same
+        # information.
+        if request.session.accessed or request.session.modified:
+            # Could be a new session, need to use new session ID
+            return request.session.session_key
+        else:
+            # Avoid use of session.session_key, which can trigger
+            # unecessary work
+            session_id = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
+            if session_id is not None and request.session.exists(session_id):
+                return session_id
+            else:
+                return None # not a valid session
+    return None
+
 class CsrfViewMiddleware(object):
     """
     Middleware that requires a present and correct csrfmiddlewaretoken
@@ -40,9 +62,8 @@
             if request.is_ajax():
                 return None
 
-            try:
-                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
-            except KeyError:
+            session_id = _get_validated_session_id(request)
+            if session_id is None:
                 # No session, no check required
                 return None
 
@@ -69,23 +90,9 @@
             return response
 
         csrf_token = None
-        try:
-            # This covers a corner case in which the outgoing response
-            # both contains a form and sets a session cookie.  This
-            # really should not be needed, since it is best if views
-            # that create a new session (login pages) also do a
-            # redirect, as is done by all such view functions in
-            # Django.
-            cookie = response.cookies[settings.SESSION_COOKIE_NAME]
-            csrf_token = _make_token(cookie.value)
-        except KeyError:
-            # Normal case - look for existing session cookie
-            try:
-                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
-                csrf_token = _make_token(session_id)
-            except KeyError:
-                # no incoming or outgoing cookie
-                pass
+        session_id = _get_validated_session_id(request)
+        if session_id is not None:
+            csrf_token = _make_token(session_id)
 
         if csrf_token is not None and \
                 response['Content-Type'].split(';')[0] in _HTML_TYPES:
Index: django/contrib/csrf/tests.py
===================================================================
--- django/contrib/csrf/tests.py	(revision 10663)
+++ django/contrib/csrf/tests.py	(working copy)
@@ -1,9 +1,11 @@
 # -*- coding: utf-8 -*-
 
+from django.conf import settings
+from django.contrib.csrf.middleware import CsrfMiddleware, _make_token, csrf_exempt
+from django.contrib.sessions.middleware import SessionMiddleware
+from django.http import HttpRequest, HttpResponse, HttpResponseForbidden
 from django.test import TestCase
-from django.http import HttpRequest, HttpResponse, HttpResponseForbidden
-from django.contrib.csrf.middleware import CsrfMiddleware, _make_token, csrf_exempt
-from django.conf import settings
+from django.utils.importlib import import_module
 
 
 def post_form_response():
@@ -17,25 +19,37 @@
 
 class CsrfMiddlewareTest(TestCase):
 
-    _session_id = "1"
+    def setUp(self, *args, **kwargs):
+        super(CsrfMiddlewareTest, self).setUp(*args, **kwargs)
+        # We have to create an actual session in the DB as the
+        # middleware validates the session
+        engine = import_module(settings.SESSION_ENGINE)
+        s = engine.SessionStore(None)
+        s.create()
+        self._session_id = s.session_key
 
+    def _apply_request_middleware(self, req):
+        SessionMiddleware().process_request(req)
+        return req
+
     def _get_GET_no_session_request(self):
-        return HttpRequest()
+        return self._apply_request_middleware(HttpRequest())
 
     def _get_GET_session_request(self):
-        req = self._get_GET_no_session_request()
+        req = HttpRequest()
         req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id
-        return req
+        return self._apply_request_middleware(req)
 
     def _get_POST_session_request(self):
-        req = self._get_GET_session_request()
+        req = HttpRequest()
+        req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id
         req.method = "POST"
-        return req
+        return self._apply_request_middleware(req)
 
     def _get_POST_no_session_request(self):
-        req = self._get_GET_no_session_request()
+        req = HttpRequest()
         req.method = "POST"
-        return req
+        return self._apply_request_middleware(req)
 
     def _get_POST_session_request_with_token(self):
         req = self._get_POST_session_request()
@@ -50,8 +64,10 @@
         resp.cookies[settings.SESSION_COOKIE_NAME] = self._session_id
         return resp
 
-    def _check_token_present(self, response):
-        self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % _make_token(self._session_id))
+    def _check_token_present(self, response, session_id=None):
+        if session_id is None:
+            session_id = self._session_id
+        self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % _make_token(session_id))
 
     def get_view(self):
         return test_view
@@ -83,11 +99,12 @@
         Check that the token is inserted if there is a new session being started
         """
         req = self._get_GET_no_session_request() # no session in request
-        resp = self._get_new_session_response() # but new session started
+        req.session.create() # but new session started
+        resp = self._get_post_form_response()
         resp_content = resp.content # needed because process_response modifies resp
         resp2 = CsrfMiddleware().process_response(req, resp)
         self.assertNotEqual(resp_content, resp2.content)
-        self._check_token_present(resp2)
+        self._check_token_present(resp2, session_id=req.session.session_key)
 
     def test_process_response_exempt_view(self):
         """
