Skip to content

Instantly share code, notes, and snippets.

@samwelkanda
Last active October 14, 2019 20:13
Show Gist options
  • Save samwelkanda/1faf2a28a099a18920e40db13d17c70e to your computer and use it in GitHub Desktop.
Save samwelkanda/1faf2a28a099a18920e40db13d17c70e to your computer and use it in GitHub Desktop.

Authentication in Django

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.

Session-Based Authentication

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.

Cross-Origin Resource Sharing (CORS)

Cross-Site Request Forgery (CSRF)

Token-Based Authentication

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.

  ## What is JWT?

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.

JWT versus API key

API key is usually generated and that’s it! It usually doesn’t expire unless such mechanism is implemented on server side. By using API key, each request to server will include a header with the key. API key creates security issue if such key are exposed to unauthorized user (i.e: captured in man-in-the-middle attack). It could be used by unauthorized party to perform legit request.

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.

JWT versus Cookie-based 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.

JWT can save you a lot of fuss when dealing with authentication across multiple domain and horizontal scalability since there is no need to keep session stored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment