Django's authentication only works with the traditional HTML request-response cycle. Historically, when a user wanted to perform some action (such as creating a new account), the user would fill out a form in their web browser. When they clicked the "Submit" button, the browser would make a request — which included the data the user had typed into the registration form — to the server, the server would process that request, and it would respond with HTML or redirect the browser to a new page.
Today, frontend clients expect the server to return JSON instead of HTML. By returning JSON, we can let the client decide what it should do next instead of letting the server decide. With a JSON request-response cycle, the server receives data, processes it, and returns a response (just like in the HTML request-response cycle), but the response does not control the browser's behavior. It just tells us the result of the request.
By default, Django uses sessions for authentication. In Django, sessions are stored as cookies. These sessions, along with some built-in middleware and request objects, ensure that there is a user available on every request. The user can be accessed as request.user
. When the user is logged in, request.user
is an instance of the User
class. When they're logged out, request.user
is an instance of the AnonymousUser
class. Whether the user is authenticated or not, request.user
will always exist.
What's the difference? Put simply, anytime you want to know if the current user is authenticated, you can use request.user.is_authenticated()
which will return True
if the user is authenticated and False
if they aren't. If request.user
is an instance of AnonymousUser
, request.user.is_authenticated()
will always return False
. This allows the developer to turn if request.user is not None and request.user.is_authenticated()
: into if request.user.is_authenticated()
. Less typing is a good thing in this case!
In most cases, the client and the server will be running at different locations. The server will be running at http://localhost:3000/ and the client will be at http://localhost:5000/. The browser considers these two locations to be on different domains, similar to running the server on http://www.server.com and running the client on http://www.client.com. We will not be allowing external domains access to our cookies, so we have to find another alternative solution to using sessions.
To keep track of all user sessions, server has to maintain a record of those. In Django, user sessions are stored and maintained in it’s underlying DB. This constraints scalability of the system, even if system are distributed and scaled horizontally, each node will still have to retrieve the session data stored in underlying database. Second, it is even more complex to make your session universal across multiple domains.
With token-based auth, the server provides the client with a token upon a successful login request. This token is unique to the user logging in and is stored in the database along with the user's ID. The client is expected to send the token with future requests so the server can identify the user. The server does this by searching the database table containing all of the tokens that have been created. If a matching token is found, the server goes on to verify that the token is still valid. If no matching token is found, then we say the user is not authenticated.
JWT stands for JSON Web Token. JWT is a short-lived token issued by server for clients to authenticate themselves without having to maintain an active session. JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.
Unlike API token, JWT has an expiry timestamp, it has to be constantly renewed or refreshed to keep the token valid. If such token is exposed to third party, he/she might not be able to refresh the token and it will be invalidated after it’s expiring timestamp.