Understanding JWT (JSON web token) authentication and python practice

Time:2020-10-25

Recently want to do a small program, need to use the authorization authentication process. Previous projects used oauth2 authentication, but it is not convenient for sanic to use oauth2. I want to try JWT authentication.
The main content of this article is the authentication principle of JWT and the practice of Python using JWT.

Several common authentication mechanisms

HTTP Basic Auth

HTTP Basic AuthIn HTTP, basic authentication is a kind of login authentication method that allows web browser or other client programs to provide identity certificate in the form of user name and password when requesting. Usually, user name and clear code will be passed through HTTP header.

Before sending, a colon is added to the user name, then the password is concatenated, and the resulting string is encoded with Base64 algorithm. For example, if the user name provided is Aladdin and the password is open sesame, the result of splicing is Aladdin:open sesame And then use itBase64 encodingAnd qwxhzgrpbjpvcgvuihnlc2ftzq = =. Finally, the base64 encoded string is sent out and decoded by the receiver to get a colon separated string of user name and password.

advantage

One of the advantages of basic authentication is that basically all popular web browsers support basic authentication.

shortcoming

Since the user name and password are Base64 encoded, and Base64 encoding is reversible, the user name and password can be considered as plaintext. Therefore, it can only be used if the connection between the client and the server host is secure and trusted.

Next, let’s look at a more secure wayOAuth

OAuth

OAuth is an open network standard about authorization. Allows users to provide a token, rather than a user name and password, to access their data stored with a specific service provider. The current version is version 2.0.

Strictly speaking, oauth2 is not a standard protocol, but a secure authorization framework. It describes in detail how to realize mutual authentication between different roles, users, service front-end applications (such as API), and clients (such as websites or mobile apps).

Definition of terms

  • Third party application: third party application, also known as “client”

  • HTTP service: http service provider

  • Resource owner: the owner of a resource, usually called a “user.”.

  • User agent: a user agent, such as a browser.

  • Authorization server: the authentication server, that is, the server used by the service provider to process authentication.

  • Server: the server that stores the resource service provider. It can be the same server as the authentication server, or it can be a different server.

The running process of OAuth 2.0 is as follows:

(A) After the user opens the client, the client requests authorization from the user.
(B) The user agrees to authorize the client.
(C) The client uses the authorization obtained in the previous step to request a token from the authentication server.
(D) After the authentication server authenticates the client, it confirms that it is correct and agrees to issue the token.
(E) The client uses a token to apply to the resource server to obtain resources.
(F) The resource server confirms that the token is correct and agrees to open the resource to the client.

advantage

Rapid development
The amount of implementation code is small
Reduced maintenance
If the designed API is to be used by different apps and each app uses different ways, oauth2 is a good choice.

shortcoming
Oauth2 is a security framework, which describes the authorization between multiple applications in different scenarios. There is a huge amount of information to learn, and it takes a lot of time to fully understand.
Oauth2 is not a strict standard protocol, so it is easier to make mistakes in the implementation process.

After understanding the above two ways, now we finally come to the focus of this article, JWT certification.

JWT certification

Json web token (JWT)According to the definition of official website, RFC 7519 is an open standard based on JSON (RFC 7519) for delivering statements between network application environments. The token is designed to be compact and secure, especially suitable for single sign on (SSO) scenarios of distributed sites. JWT statement is generally used to transfer the authenticated user identity information between identity provider and service provider, so as to obtain resources from resource server. It can also add some additional declaration information required by other business logic. The token can also be directly used for authentication and can be encrypted.

JWT features

  • Small size, so fast transmission speed

  • There are various transmission methods, such as URL / post parameter / HTTP header

  • Strictly structured. In addition, all the messages related to the user, such as payload, are valid in the user’s database.

  • It supports cross domain authentication and can be applied to single sign on.

JWT principle

JWT is a scheme proposed by auth0 to implement authorization verification by encrypting and signing JSON. The encoded JWT looks like a string of characters

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ  

from.It is divided into three parts, and can be obtained by decoding

1. Head

//It includes typ and alg;
{
  "alg": "HS256",
  "typ": "JWT"
}

The header of JWT contains two parts of information

  • Declaration type, here is JWT

  • HMAC sha256 is usually used directly for the algorithm of declaring encryption

Then the header is encrypted with Base64 (the encryption can be decrypted symmetrically) to form the first part.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

2. Payload

A load is a place where valid information is stored. The effective information consists of three parts:

  • Registration statement in the standard

  • Public reputation

  • Private statement

Public statement:
Any information can be added to the public statement. Generally, the user’s relevant information or other necessary information required by the business can be added. However, it is not recommended to add sensitive information, because this part can be decrypted at the client.

Private statement:
Private statement is defined by both provider and consumer. It is generally not recommended to store sensitive information because Base64 is symmetric decrypted, which means that this part of information can be classified as plaintext information.

Here is an example:

//Including user information to be transmitted;
{ "iss": "Online JWT Builder", 
  "iat": 1416797419, 
  "exp": 1448333419, 
  "aud": "www.gusibi.com", 
  "sub": "uid", 
  "nickname": "goodspeed", 
  "username": "goodspeed", 
  "scopes": [ "admin", "user" ] 
}
  • ISS: the signer of the JWT. Whether to use it or not is optional;

  • Sub: whether to use the JWT is optional;

  • Aud: the party receiving the JWT is optional;

  • Exp (expires): when it will expire. Here is a UNIX timestamp. Whether to use it or not is optional;

  • IAT (issued at): when it is issued (UNIX time) and whether to use it is optional;

Others are:

  • NBF (not before): if the current time is before the time in NBF, token will not be accepted. Generally, some space will be left, such as a few minutes; whether to use it is optional;

  • JTI: the unique identity of JWT, which is mainly used as a one-time token to avoid replay attacks.

Run the JSON object aboveBase64 encodingYou can get the following string. We call this string the payload of JWT.

eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTY3OTc0MTksImV4cCI6MTQ0ODMzMzQxOSwiYXVkIjoid3d3Lmd1c2liaS5jb20iLCJzdWIiOiIwMTIzNDU2Nzg5Iiwibmlja25hbWUiOiJnb29kc3BlZWQiLCJ1c2VybmFtZSI6Imdvb2RzcGVlZCIsInNjb3BlcyI6WyJhZG1pbiIsInVzZXIiXX0

Information will be exposedBecause of the reversible Base64 encoding, the data in the second part is actually plaintext. We should avoid storing privacy information that cannot be made public here.

3. Signature

//The signature string is encrypted by alg algorithm and private key;
//This section is the most important sensitive information, which can only be decrypted on the server side;
HMACSHA256(  
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    SECREATE_KEY
)

The third part of JWT is a visa information, which consists of three parts:

  • Header (after Base64)

  • Payload (after Base64)

  • secret

The above two encoded strings are connected with a period (with the head in front) to form:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

Finally, we use hs256 algorithm to encrypt the above spliced string. When encrypting, we also need to provide a secret. If we usesecretAs a key, we can get the encrypted content:

pq5IDv-yaktw6XEa5GEv07SzS9ehe6AcVSdTj0Ini4o

These three parts are connected into a complete string with. To form the final JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTY3OTc0MTksImV4cCI6MTQ0ODMzMzQxOSwiYXVkIjoid3d3Lmd1c2liaS5jb20iLCJzdWIiOiIwMTIzNDU2Nzg5Iiwibmlja25hbWUiOiJnb29kc3BlZWQiLCJ1c2VybmFtZSI6Imdvb2RzcGVlZCIsInNjb3BlcyI6WyJhZG1pbiIsInVzZXIiXX0.pq5IDv-yaktw6XEa5GEv07SzS9ehe6AcVSdTj0Ini4o

Purpose of signature: signature is actually the signature of the header and payload content. Therefore, if someone decodes and modifies the contents of the header and payload, then the signature of the new header and payload will be different from the previous signature. Moreover, if you don’t know the key used by the server when encrypting, the signature will be different.
This ensures that the token will not be tampered with.

After the token is generated, you can use the token to communicate with the server.

The following figure shows the interaction process between client and server using JWT:

Here, in step 3, after we get the JWT, we need to store the JWT in the client, and send the JWT every time we need to authenticate. (it can be put into the authorization of the header when requested)

JWT usage scenarios

The main advantage of JWT is that it uses a stateless, extensible way to handle user sessions in applications. The server can easily obtain the user’s session information through the embedded declaration information, without accessing the user’s or session database. This is very useful in a distributed service-oriented framework.

However, if the system needs to use blacklist to achieve a long-term effective token refresh mechanism, this stateless advantage is not obvious.

advantage

Rapid development
No cookies are required
The wide application of JSON in mobile terminal
Independent of social login
Relatively simple concept understanding

shortcoming

Token has length limit
Token cannot be revoked
Token needs to have expiration time limit (EXP)

Practice of using JWT in Python

I basically use Python as the server-side language. We can use pyjwt: https://github.com/jpadilla/pyjwt/

It is easy to use. The following is an example of my application:

import jwt
import time

#Using sanic as restful API framework 
def create_token(request):
    grant_type = request.json.get('grant_type')
    username = request.json['username']
    password = request.json['password']
    if grant_type == 'password':
        account = verify_password(username, password)
    elif grant_type == 'wxapp':
        account = verify_wxapp(username, password)
    if not account:
        return {}
    payload = {
        "iss": "gusibi.com",
         "iat": int(time.time()),
         "exp": int(time.time()) + 86400 * 7,
         "aud": "www.gusibi.com",
         "sub": account['_id'],
         "username": account['username'],
         "scopes": ['open']
    }
    token = jwt.encode(payload, 'secret', algorithm='HS256')
    return True, {'access_token': token, 'account_id': account['_id']}
    

def verify_bearer_token(token):
    #If the AUD parameter is used when generating the token, this parameter needs to be added during verification
    payload = jwt.decode(token, 'secret', audience='www.gusibi.com', algorithms=['HS256'])
    if payload:
        return True, token
    return False, token

Here, we can use JWT to generate token directly without manual base64 encryption and splicing.

Detailed code can refer to gusibi / Metis: a test class applet (including the front and back-end code).

In this project, the API uses Python sanic, and the documents are generated using swagger py CodeGen, providing the swagger UI.

Now you can use the swagger UI to test JWT.

summary

This article mainly introduces the principle of JWT, verification steps, and finally uses thepyjwtThe package demonstrates how to generate token and verify token.

The packages mentioned above can be found inPublic reply keywordsGet address

Notice, the next article is to introduce the authentication process and implementation of JWT in applets.

Reference link

  • HTTP Basic Authentication

  • Implementation of various languages for accessing resources requiring HTTP basic authentication authentication

  • Understanding OAuth 2.0

  • OAuth 2 and JWT – how to design a secure API?

  • Securing RESTful Web Services with OAuth2

  • Server side authentication — embrace

  • JSON web token – securely transfer information between web applications

  • Understanding and using JSON Web

  • Web background authentication mechanism based on token

  • What is JWT — JSON web token


Finally, thank your girlfriend for your support.

Welcome to (April_ Louisa) Treat me to Fanta

Recommended Today

What black technology does the real-time big data platform use behind the glory of the king?

Hello everyone, I’m Xu Zhenwen. Today’s topic is “Tencent game big data service application practice based on Flink + servicemesh”, which is mainly divided into the following four parts: Introduction to background and Solution Framework Real time big data computing onedata Data interface service onefun Microservice & servicemesh 1、 Introduction to the solution framework and […]