JWT
JWTの基本的な導入
フルネーム:JSONウェブトークン
技術の進歩、分散型Webアプリケーションの人気が、ユーザーがセッション管理に高いコストと高い経由でログインし、そうゆっくりログイン本人確認を行うためのトークン道へと発展し、その後を介して取得するためにキャッシュされたユーザートークンをRedisのRedisのキャッシュを経由せず、しかし直接トークン格納されているユーザ情報だけでなく、トークンのチェックアウト可用性、チェックのよりシンプルで便利な方法の出現、単純に基づいたシングルサインオンとJWT後の情報、。
トークンの形式
三段階 - 最初のペイロード・シグネチャ - ヘッド及びペイロードの暗号化は、不可逆的な暗号化を使用して、MD5署名を可逆BASE64を使用します
token内容
ヘッド(基本情報、また空にすることができます):暗号化、企業情報、チーム情報、...
ペイロード(コア情報):ユーザー情報、有効期限、...
署名(セキュリティ):頭の暗号化結果結果+ + MD5暗号化されたペイロード・サーバの秘密鍵の暗号化結果
セキュリティ
セキュリティキーが唯一のセキュリティであるようにDjangoのサーバーとして、その署名の一部に主に依存します
認定規則
背景には、サーバの秘密鍵のセキュリティを保護する必要があります(それが唯一のセキュリティJWTのある)
トークンの背景の発行- >フロントストレージ- >トークンによる認証を必要とする要求を送信する- >正当なユーザーを取得するには、バックグラウンドチェック
使用JWT
認証モジュールパッケージ、成功裏に暗号化されたトークンを返し、ログ、そこトークンの機能を解析します
まずJWTインストールします。
pip install djangorestframework-jwt
三つの主要な機能をJWT
三つのビューインタフェース
機能のJWTデフォルトの実装では、それは一般的に直接ビューで彼を提供するインタフェースではありません、あまりにも簡単です
url(r'^login1/$', obtain_jwt_token),
#签发token,接收username和password
obtain_jwt_token = ObtainJSONWebToken.as_view()
#校验token,验证token,对的原样返回,错的报错
refresh_jwt_token = RefreshJSONWebToken.as_view()
#刷新token,使用要配置'JWT_ALLOW_REFRESH': False,允许刷新为True,token过期,刷新为有效时间
verify_jwt_token = VerifyJSONWebToken.as_view()
JWTの設定
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
# 'JWT_ALLOW_REFRESH': True,
# 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
トークンの発行プロセス
ユーザー - > jwt_payload_handler - >ペイロード - > jwt_encode_handler - >トークン
#全局钩子,登录之后在序列化类里面做校验的时候就直接签发token。
def validate(self, attrs):
user = authenticate(**attrs)
if not user:
raise ValidationError({'user':'信息有误'})
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
self.user = user
self.token = token
return attrs
JWTグローバル認定
# drf的配置
REST_FRAMEWORK = {
# 异常模块
'EXCEPTION_HANDLER': 'utils.exception.exception_handler',
# 认证模块
'DEFAULT_AUTHENTICATION_CLASSES': [
# jwt认证类
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
],
# 权限模块
'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated',
# 自定义权限类
],
# 频率设置
'DEFAULT_THROTTLE_RATES': {
'three': '3/min',
},
}
# 修改auth模块的用户表指向
AUTH_USER_MODEL = 'api.User'
# drf-jwt配置
import datetime
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
# 'JWT_ALLOW_REFRESH': True,
# 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
複数のログイン
class LoginAPIView(APIView):
authentication_classes = []
permission_classes = []
def post(self, request, *args, **kwargs):
serializer = serializers.LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
return APIResponse(msg='login success', data={
'username': serializer.user.username,
'token': serializer.token
})
シリアライザ:
from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
class LoginSerializer(ModelSerializer):
username = CharField(write_only=True)
password = CharField(write_only=True)
class Meta:
model = models.User
fields = ('username', 'password')
# 在全局钩子中签发token
def validate(self, attrs):
# user = authenticate(**attrs)
# 账号密码登录 => 多方式登录
user = self._many_method_login(**attrs)
# 签发token,并将user和token存放到序列化对象中
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
self.user = user
self.token = token
return attrs
# 多方式登录
def _many_method_login(self, **attrs):
username = attrs.get('username')
password = attrs.get('password')
if re.match(r'.*@.*', username):
user = models.User.objects.filter(email=username).first() # type: models.User
elif re.match(r'^1[3-9][0-9]{9}$', username):
user = models.User.objects.filter(mobile=username).first()
else:
user = models.User.objects.filter(username=username).first()
if not user:
raise ValidationError({'username': '账号有误'})
if not user.check_password(password):
raise ValidationError({'password': '密码有误'})
return user
JWTについての概要
コードは、ペイロード、トークン、構成設定、3であります
ヒム3つの周波数認定の認定と認定することができので、唯一の書き込みアクセス、あなたの完全なユーザー認証を支援します。あなただけのトークンが生成され、その後、ユーザーの名前空間に配置された検証トークン、それは内部のあなたの構成された設定のJWT一部で行われているJWT使用することを行うようにされる必要があります。
高周波モジュール
カスタムクラスの完全な周波数の上限周波数ビュークラス
SimpleRateThrottle継承1)で定義されたクラス、get_cache_keyオーバーライドメソッド、スコープクラス属性セット
2)は、スコープの認証文字列、構成ファイル内の構成スコープ周波数設定に対応する文字列である
3)get_cache_key戻り値は文字列で、文字列は、キャッシュアクセス頻度とキャッシュキーであります
設定DRFコンフィギュレーション・ライト・本で
'DEFAULT_THROTTLE_RATES': {
'three': '3/min',
},
ビュークラス定義された頻度をカスタマイズするには
from rest_framework.permissions import IsAuthenticated
from utils.throttles import ThreeTimeUserThrottle
class UserCenterAPIView(APIView):
# 认证全局配置吗,权限局部配置,认证已经交给jwt了
# authentication_classes = []
permission_classes = [IsAuthenticated]
# 频率模块局部配置
throttle_classes = [ThreeTimeUserThrottle]
def get(self, request, *args, **kwargs):
user = request.user
serializer = serializers.UserModelSerializer(user)
return APIResponse(data=serializer.data)
スロットル
# 自定义频率类
from rest_framework.throttling import SimpleRateThrottle
# 1)定义类继承SimpleRateThrottle,重写get_cache_key方法,设置scope类属性
# 2)scope就是一个认证字符串,在配置文件中配置scope字符串对应的频率设置
# 3)get_cache_key的返回值是字符串,该字符串是缓存访问次数的缓存key
class ThreeTimeUserThrottle(SimpleRateThrottle):
#这里的scope要和settings里面的key对上。
scope = 'three'
# 当前用户缓存的key,这个方法的返回值是一个能够唯一标识用户的信息,如果name是唯一的,用name也行,总之它会认得这个字符串,知道下次进来的人是不是你。如果返回的字符串每次都是同样的,那么你所有用户登录就共用一个频率了。
def get_cache_key(self, request, view):
return 'throttle:user_%s' % (request.user.id)