2👍
I’m assuming you’re using Django’s built-in authentication system – i.e. you have the django.contrib.auth
included in your settings installed apps.
Middlewares get a chance to intercept the request
before any of your views receive it.
This request.user
attribute is set by Django’s auth middleware, here:
class RemoteUserMiddleware(MiddlewareMixin):
"""
Middleware for utilizing Web-server-provided authentication.
If request.user is not authenticated, then this middleware attempts to
authenticate the username passed in the ``REMOTE_USER`` request header.
If authentication is successful, the user is automatically logged in to
persist the user in the session.
The header used is configurable and defaults to ``REMOTE_USER``. Subclass
this class and change the ``header`` attribute if you need to use a
different header.
"""
...
def process_request(self, request):
...
# We are seeing this user for the first time in this session, attempt
# to authenticate the user.
user = auth.authenticate(request, remote_user=username)
if user:
# User is valid. Set request.user and persist user in the session
# by logging the user in.
request.user = user
auth.login(request, user)
0👍
In Authentication in web requests we read a very short explanation
Django uses sessions and middleware to hook the authentication system into request objects. These provide a request.user attribute on every request which represents the current user. If the current user has not logged in, this attribute will be set to an instance of AnonymousUser, otherwise it will be an instance of User.
For most that information will suffice. Yet, if one wants to understand better what happens under the hood, let’s try to login a user and see what happens.
To log a user in, from a view, we use login()
. For example, if one tests in this system by Creative Tim,
One sends a POST
request with the data:
username:test
password:ApS12_ZZs8
If login is successful, login()
saves the user’s ID in the session using Django’s session framework, which is entirely, and solely, cookie-based, (by default, Django stores sessions in your database, in a django_session
table), and we’ll get back a cookie in the request header
cookie: sessionid=53u40ngk6puzfru3gl7p5zhbx0yrkoo3
So, what is that sessionid
we are getting? It’s the session_key
in the django_session
table. The table looks like the following
Column | Type | Collation | Nullable | Default
----------------------+--------------------------+---------------+--------------+-------------
session_key | character varying(40) | | not null |
session_data | text | | not null |
expire_date | timestamp with time zone | | not null |
So, knowing the session_key
it’s possible to know the session_data
. It’s in session_data
that when a user logs in, the user’s ID and the backend that was used for authentication are saved as an encoded dictionary. This allows the same authentication backend to fetch the user’s details on a future request.
Since authentication sources are cached on a per-session basis, if one changes AUTHENTICATION_BACKENDS
(one can even create a custom one) one will need to clear out session data to force users to re-authenticate using different methods (Session.objects.all().delete()
).
By default, Django only saves to the session database when the session has been modified – that is if any of its dictionary values have been assigned or deleted.
Then, when one calls logout()
, the session data for the current request is completely cleaned out. In other words, one still gets a cookie: sessionid=...
in the header, except that the session_data
linked with that session_key
won’t have the _auth_user_id
like before.
Which is great but that still doesn’t explain how Django knows the user making the request. Looking back at the beginning of the answer, there’s a quote saying Django uses sessions and middleware to hook the authentication system into request objects.
. We’ve covered the sessions, so that must be the part handled by Middleware. One is correct if one assumes that. More specifically, Django’s auth middleware sets the request.user
attribute here, as noted by wim, and that’s done essentially by extracting the user and the authentication backend from the session.
Notes:
- As per the documentation, it’s recommended to call
clearsessions
on a regular basis to purge expired sessions, for example as a daily cron job.
- [Django]-How to get rid of spacing in SimpleDocTemplate(). Python. ReportLab
- [Django]-Django Rest shows TemplateDoesNotExist
- [Django]-Can we pass array/list to template content blocks in django? python