In the traditional integral Django Website Authentication , Certification is simpler , And it involves session based Cookie Pattern , We will review below . But use API It'll be a little tricky . please remember ,HTTP Is stateless protocol , Therefore, there is no built-in way to remember whether the user has authenticated from one request to another . Every time a user requests a restricted resource , It has to verify itself .
The solution is in every HTTP Pass a unique identifier in the request . What is puzzling is , There is no accepted method for the form of this identifier , It can take many forms . Django REST Framework Only four different built-in authentication options are included ! And there are more third-party packages that provide other functions , for example JSON Web token ( JSON Web Tokens,JWT).
In this paper , We will thoroughly explore API How Authentication works , Review the pros and cons of each approach , Then for our Blog API Choose wisely . In the end , We will create a for registration , Login and logout API Endpoint .
HTTP The most common form of authentication is called “ basic ” Authentication . Client issue HTTP When asked , You must force the sending of approved authentication credentials before granting access .
Complete request / The response flow is as follows :
Client issue HTTP request
Server to include 401( unauthorized ) State of HTTP Respond to the response code and WWW-Authenticate HTTP Header and details on how to authorize
Client pass Authorization HTTP Mark the hair and send it back
The server checks the credentials and returns with 200 OK or 403 Forbiddenstatus Response code
After approval , The client will use authorization HTTP Header credentials send all future requests . We can also visualize this exchange as follows :
Please note that , The authorization certificate sent is <username>:<password>
Unencrypted base64 Code version . So in my case , This is a wsv:password123
Of base64 Encoded as d3N2OnBhc3N3b3JkMTIz
.
The main advantage of this method is simplicity . But there are several main disadvantages . First , For each individual request , The server must find and verify the user name and password , It's inefficient . It's best to make a query first , A token that has been approved by the user is then passed . secondly , User credentials are passed in clear text , Instead of not encrypting at all . It's very unsafe . Any unencrypted Internet traffic can be easily captured and reused . therefore , Basic authentication can only pass HTTPS(HTTP Security version of ) Use .
Like the traditional Django equally , Integrated websites have long used alternative authentication schemes , The scheme combines session and cookie Bind together . At a higher level , The client uses its credentials ( user name / password ) Authentication , Then receive the session from the server ID( Stored as cookie). then , This meeting ID Will be in every future HTTP Pass... In the header of the request .
Delivery session ID after , The server will use it to find the session object , This object contains all available information for a given user , Include credentials .
This method is stateful , Because it must be on the server ( Conversation object ) And the client ( conversation ID ) Keep and maintain a record on the .
Let's review the basic process :
Users enter their login credentials ( Usually the user name / password )
The server verifies that the credentials are correct , And generate a session object , The session object , And then it's stored in the database
The server sends a session to the client ID, Not the session object itself , The session ID As cookie Store in browser
In all future requests , conversation ID Both contain HTTP header , And if the database has been verified , Then request to continue
After the user logs out of the application , Both the client and the server will be destroyed session ID.
If the user logs in again later , Then a new session ID , And use it as cookie Stored on the client
Django REST Framework The default setting in is actually a combination of basic authentication and session authentication . Use Django Traditional session based authentication system , And pass basic authentication at the end of each request HTTP Pass session in header ID .
The advantage of this method is that it is safer , Because user credentials are sent only once , Not on every request like basic authentication / Send once in the response cycle . Because the server does not have to verify the user's credentials every time , It just takes the session ID Match with the session object to quickly find , So it's more efficient .
But there are a few drawbacks . First , conversation ID Valid only in the browser that performs the login ; It cannot work across multiple domains . When API Need to support multiple front ends ( For example, websites and mobile apps ) when , This is an obvious problem . secondly , The session object must be kept up to date , This can be a challenge in large sites with multiple servers . How do you maintain the accuracy of session objects on each server ? Third , For each individual request , Even requests that do not require authentication , Will send cookie, It's inefficient .
result , It is generally not recommended for any that will have multiple front ends API Use session based authentication scheme .
The third main method and we will be in Blog API The method implemented in is to use Token Authentication . Due to the rise of single page applications , This is the most popular method in recent years .
be based on Token Is stateless : After the client sends the initial user credentials to the server , A unique token will be generated , The client then stores it as cookie or The local store . then , this Token In each incoming HTTP Pass... In the header of the request , The server uses it to authenticate users . The server itself does not retain user records , It's just whether the token is valid .
Cookies vs localStorage
Cookies Used to read server-side information . They are smaller (4KB), And with each HTTP Requests are sent automatically . LocalStorage Designed for client information . It's bigger (5120KB), By default , Every HTTP Requests do not send their contents . Cookie and localStorage Tokens stored in are vulnerable to XSS attack . The current best practice is to use httpOnly and Secure cookie Flags store tokens in cookie in .
Let's take a look at this challenge/response The actual in the stream HTTP A simple version of the message . Please note that ,HTTP header WWW-Authenticate Specifies the token used in response to the authorization header request .
This method has many advantages . Because the token is stored on the client , Therefore, extending the server to maintain the latest session objects is no longer a problem . Tokens can be shared across multiple front ends : same Token It can represent users on the website and the same user on the mobile application . Same conversation ID Cannot share between different front ends , This is a major limitation .
The potential downside is that tokens can become very large . The token contains all user information , Not just a conversation ID / Session object settings ID. Because the token is sent on each request , Therefore, managing the size of tokens can be a performance issue .
The implementation of tokens can also be very different . Django REST Built in of frame TokenAuthentication Is a very basic setting . therefore , It does not support setting token expiration , This is a security improvement that can be added . It also generates only one token per user , Therefore, users on the website and subsequent mobile applications will use the same token . Because the information about users is stored locally , Therefore, this may lead to the problem of maintaining and updating two sets of customer information .
JSON Web token (JWT) Is an enhanced new version of token , It can be added to... Through several third-party packages Django REST Framework in . JWT It has many advantages , This includes the ability to generate unique client tokens and expired tokens . They can be generated on the server , Third party services can also be used ( Such as Auth0) Generate . and ,JWT Can be encrypted , So that it can pass through unsafe HTTP Connect to send .
Final , For most Web API Come on , The safest option is to use a token based authentication scheme . JWT It's a good , Modern add , Although they require other configurations . therefore , In this book , We're going to use the built-in TokenAuthentication.
The first step is to configure our new authentication settings . Django REST The frame is attached Many implicit settings Set up . for example , Before we will DEFAULT_PERMISSION_CLASSES Updated to IsAuthenticated Before , It has been set to AllowAny.
By default ,DEFAULT_AUTHENTICATION_CLASSES Set to SessionAuthentication and BasicAuthentication. Let's add them explicitly to our blog_project/settings.py
In file .
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': [ # new 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ],}
Why use both methods at the same time ? The answer is that they have different uses . Sessions are used to enhance Browsable API And the ability to log in and out of this function . BasicAuthentication Used in API Of itself HTTP Pass session in header ID.
If you are in http://127.0.0.1:8000/api/v1/
Browsable on API, It will work as before .