Very detailed Django uses Token (rpm)

Token-based identity verification

When implementing login function, normal B / S application will use cookie + session way to do authentication, background write data directly to a cookie, but due to the existence of the mobile terminal, the mobile terminal is no cookie mechanism, so use token mobile communication terminal may be implemented token and the client.

Verification process

Token based authentication entire process is as follows:

  1. The client uses the user login name with the password request
  2. Server receives the request, to verify the user name and password
  3. After successful authentication, the server will issue a Token, then the Token is sent to the client
  4. Token client received after it can be stored, such as Cookie or placed in LocalStorage
  5. Each time the client sends another request to the server at all times with a server issued Token
  6. Server receives the request, to verify the client requests inside with the Token, if authentication is successful, as the client return the requested data

JWT

Token construction method of a lot can be said as long as the client and server-side format agreed Well, thinking about how to write on how to write, but there are some standard wording, such as JWT pronounced / jot /, represents: JSON Web . Tokens
the JWT standard Token has three parts:

  • header
  • payload
  • signature
    three parts separated by dots will be, and will use Base64 encoding, it looks like the real Token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

Header

header part is two parts, one is the Token type, other algorithms are used, such as the following types is the JWT, the algorithm used is HS256:

{
  "typ": "JWT",
  "alg": "HS256"
}

The above content to use Base64 encoded form of it, so it becomes like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

Payload Token which is the specific content of these elements there are some standard fields, you can also add other needed content. Here is the standard fields:

  • iss: Issuer, the issuer
  • sub: Subject, theme
  • aud: Audience, audience
  • exp: Expiration time, the expiration time
  • nbf:Not before
  • iat: Issued at, Released
  • JTI: JWT ID

Signature

The final part of the Signature JWT, which portion corresponds to a summary of the first two, to prevent tampering with the information to others in the Token, may first be generated using the previous two paragraphs Base64 look at the process of generating and using plus salt MD5 digest algorithm, etc. in the generated again

The server generates a Token

When the server generated Token, we need to solve two problems

  1. What encryption algorithm
  2. How Token storage

Encryption Algorithm

Here encryption algorithm is not MD5, SHA1 hashing algorithm such as the algorithm can not be decrypted only be used to generate a summary, a built-in encryption module in front of the module django.core.signing Django, can be used encrypt and decrypt any data, using a signature module dumps and load functions to achieve

Example:

from django.core import signing
value = signing.dumps({"foo":"bar"})
src = signing.loads(value)
print(value)
print(src)

result:

eyJmb28iOiJiYXIifQ:1NMg1b:zGcDE4-TCkaeGzLeW9UQwZesciI 
{‘foo’: ‘bar’}

How Token storage

What storage

Token in the server can be stored in memory, because the nature of the string, it does not take up much memory space, if it is distributed can be stored on a different server, you can also store all the information segment token stored in the database, a cache provided in Django class, can be used to store the Token, may be combined Redis cache Django used, can be implemented by means of django-redis

installation

pip install django-redis

Configuration

In order to use django-redis, django cache setting need to revise, modify settings.py, there is no default configuration information of the Cache, in which added:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

Of course, you first need to install redis

Use cache

When using a basic cache set and get methods may be used to load / store data

>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'

How to save

Since redis using kv mode for storing data, we can use it as a key, and token information as a value, compared to the direct use token as a key way, the advantage is that we can use less space to achieve some of the features, for example, when the user changed the password or click cancellation, it can direct the token fails, direct the user name corresponding to the deleted data like, or the user after a successful login, the login interface to request once again, we can be very simple update the user's token information, and this depends on our store can be decrypted token, if you are directly generate the data can not be decrypted string as a token, you can not use it as a token of

code

import time
from django.core import signing
import hashlib
from django.core.cache import cache

HEADER = {'typ': 'JWP', 'alg': 'default'}
KEY = 'CHEN_FENG_YAO'
SALT = 'www.lanou3g.com'
TIME_OUT = 30 * 60  # 30min


def encrypt(obj):
    """加密"""
    value = signing.dumps(obj, key=KEY, salt=SALT)
    value = signing.b64_encode(value.encode()).decode()
    return value


def decrypt(src):
    """解密"""
    src = signing.b64_decode(src.encode()).decode()
    raw = signing.loads(src, key=KEY, salt=SALT)
    print(type(raw))
    return raw


def create_token(username):
    """生成token信息"""
    # 1. 加密头信息
    header = encrypt(HEADER)
    # 2. 构造Payload
    payload = {"username": username, "iat": time.time()}
    payload = encrypt(payload)
    # 3. 生成签名
    md5 = hashlib.md5()
    md5.update(("%s.%s" % (header, payload)).encode())
    signature = md5.hexdigest()
    token = "%s.%s.%s" % (header, payload, signature)
    # 存储到缓存中
    cache.set(username, token, TIME_OUT)
    return token


def get_payload(token):
    payload = str(token).split('.')[1]
    payload = decrypt(payload)
    return payload


# 通过token获取用户名
def get_username(token):
    payload = get_payload(token)
    return payload['username']
    pass


def check_token(token):
    username = get_username(token)
    last_token = cache.get(username)
    if last_token:
        return last_token == token
    return False

Guess you like

Origin www.cnblogs.com/Paul-watermelon/p/11286698.html