1.JWT学習
ユーザー登録やログインの後、我々はユーザーのログイン状態を記録し、またはユーザの認証証明書を作成したいです。私たちは、もはやJSONウェブトークン認証メカニズムを使用して、セッションの認証メカニズムを使用していません。
JSONウェブトークン(JWT)は、オープンな標準のJSONに基づいてネットワークアプリケーション実行環境の間を通過するために、ステートメントです((RFC 7519)。トークンは、コンパクトで安全な、特にシングルに分散したサイトのためになるように設計されてサインオン(SSO)シナリオ.JWT文は通常、サーバからリソースを取得するために識別情報を認証されて提供し、ユーザアイデンティティとの間のサービスプロバイダ転送するために使用されている、あなたはまた、でなければならないいくつかの余分な他のビジネス・ロジックを追加することができます、トークンは直接認証に使用することができますステートメント情報は暗号化されてもよいです。
1.1 JWT組成
3つの情報からなる文字列のJWTは、情報テキストのこれらの3枚を使用し.
たリンクでJWT文字列を構成しています。このように:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
我々は頭部(ヘッダ)を呼び出す最初の部分は、第二の部分は、我々は(平面上に担持された商品と同様ペイロード)負荷を呼び出し、および第三の部分は、ビザ(署名)です。
1.1.1ヘッダ
JWTヘッドは、2つの情報を運びます:
宣言された型、ここにJWTがあります
暗号化アルゴリズムのアサーションは通常、HMAC SHA256直接使用されます
JSONでこのような完全な頭部:
{ ' 標準':' JWT ' 、 ' ALG ':' HS256 ' }
その後、ヘッドbase64で暗号化は、(暗号化は、対称復号化することができる)、第1の部分を構成しています。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
1.1.2ペイロード
ロードローカルストレージが有効な情報です。名前は、航空機上に担持されたそのような物品に特異的に指し、これらの効果的な情報は、3つの部分から構成され
標準的な登録届出書
公式声明
Privateステートメント
標準的な登録届出書(推奨しますが、使用は必須ではありません):
ISS:JWTの発行者
サブ:ユーザーのためのJWT
AUD:受信側JWT
EXP:JWT有効期限、有効期限は、時間の問題よりも大きくなければなりません。
NBF:JWTの前に定義されてどのような時間は利用できません。
IAT:時間の問題JWT
JTI:JWT独自のアイデンティティは、主にリプレイ攻撃を避けるために、ワンタイムトークンとして使用されています。
Publicステートメント:公共の宣言は任意の情報、必要な情報やその他のビジネスニーズを追加するには、ユーザに関する一般的な情報を追加できますが、機密性の高い情報を追加するために、クライアントの一部を解読することができますので、お勧めしません。
Privateステートメント:base64では、情報の一部が平文として分類することができることを意味し、対称を復号化しているので、Privateステートメントは、共通の定義としての文の提供者と消費者であるが、一般的に、機密情報を保存することは推奨されません。
ペイロードを定義します。
{ " サブ":" 1234567890 " 、 " 名前":" ジョン・ドウ" 、 " 管理者" :真 }
次いで、base64で暗号化され、JWTの第2の部分を与えます。
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
1.1.3署名
JWTは、ビザ情報の第3の部分であり、このビザ情報は、3つの部分からなります:
(BASE64後)ヘッダ
ペイロード(BASE64後)
秘密の
そしてBASE64後のヘッダ部の後にbase64で使用して暗号化されたペイロードを暗号化する必要がある.
文字列連結組成物を、その後に宣言塩暗号化ヘッダによってsecret
組み合わせの暗号化、および第三の部分は、JWTを構成しています。
// もしアナログjwttokenを生成する場合はJavaScript、[注:擬似コード]次のコードを生成するために使用されてもよい VARのencodedString = base64UrlEncode(ヘッダ)+ ' ' + Base64UrlEncode(ペイロード); VAR署名 = HMACSHA256(encodedString、' 秘密'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
これらの三つの部分.
に接続完全な文字列は、最後のJWTを構成します:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注:秘密がサーバ側に保存されている、問題はサーバー側でも、JWTを生成し、秘密はそれはあなたのサーバの秘密鍵であるので、JWTの発行とJWTを認証するために使用され、いずれのシナリオで行くことを明らかにすべきではありません。クライアントが秘密を学習した後は、クライアントが自己署名JWTアップすることができることを意味します。
発行し、JWTの検証のために、私たちが完了するまでにDjangoのRESTフレームワークJWT拡張機能を使用することができます。
Documentation Webサイトhttp://getblimp.github.io/django-rest-framework-jwt/
1.2ジャンゴインストールされた構成JWT
1.2.1インストール
djangorestframework-JWTをインストールPIP
コンフィギュレーションファイルに設定1.2.2
REST_FRAMEWORK = { ' DEFAULT_AUTHENTICATION_CLASSES ' :( ' rest_framework_jwt.authentication.JSONWebTokenAuthentication ' 、 ' rest_framework.authentication.SessionAuthentication ' 、 ' rest_framework.authentication.BasicAuthentication ' 、 )、 } インポート日時 JWT_AUTH = { ' JWT_EXPIRATION_DELTA ':datetime.timedelta(日= 1 ) }
注意:JWT_EXPIRATION_DELTAは、トークンの有効指定しました
1.3 JWTを生成
ドキュメントのDjangoのRESTフレームワークJWT JWTの拡張子によって発行されたマニュアルの方法を提供し、
rest_framework_jwt.settings インポートapi_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER ペイロード = jwt_payload_handler(ユーザ) トークン = jwt_encode_handler(ペイロード)
ユーザー登録やログインが成功したら、それは将来的にシリアライザにユーザー情報を返すことができるトークンを返します。
2. JWTに基づいて認定前端と後端を達成
2.1バックエンドの実装のログイン認証インターフェース
ルーティングurls.pyにおけるサブアプリケーションのユーザーに
rest_framework_jwt.views インポートobtain_jwt_token urlpatternsを = [ パス(R ' 承認/ '、obtain_jwt_token、NAME = ' 権限' ) ]
次に、我々は郵便配達で、以下の機能をテストすることができます
JWTを保存するための2.2のフロントエンド
我々JWTはクッキーに保存されていることができますはまた、我々はブラウザのローカルストレージに保存され、ブラウザのローカルメモリに格納することができます
ローカルストアブラウザはのsessionStorageとlocalStorageを2つの方法が用意されています。
sessionStorageのブラウザは消滅する閉じています
localStorageは、長期的な効果
使用
sessionStorage。変数名=変数値// データ保存 のsessionStorageを。変数名 // 読み込んだデータ sessionStorage.clear() // すべてのsessionStorageをデータ保存削除 のlocalStorageを。変数名 =変数値//は、データ保存 のlocalStorageを。変数名 // データ読み込み localStorage.clearを() //がのlocalStorageに保存されているすべてのデータを消去します
以上の2.3着陸条件
JWTは、ユーザー名とパスワードを受信したときに、ログインビューを拡張するだけでなく、Djangoの認証システム提供呼び出すために認証を()ユーザー名とパスワードが正しい確認すること。
私たちは、認証バックエンドDjangoの認証システムは、(主にメソッドを認証)ユーザー名や電話番号のいずれかになります修正することにより、ログインアカウントをサポートすることができます。
認証バックエンドDjangoの認証システムはdjango.contrib.auth.backends.ModelBackendを継承し、authenticateメソッドをオーバーライドする必要があります変更します。
authenticate(self, request, username=None, password=None, **kwargs)
パラメータ説明方法:
要求の認証要求オブジェクト
ユーザー名、ユーザーアカウント、この認証を提供
これは、パスワード認証のパスワードを提供します
我々は、ユーザーが、ユーザー名でログインどちらかあなたはまた、ユーザ名パラメータは、ユーザー名や電話番号を意味し、認証方式のため、電話番号にログインできるようにしたいです。
アイデアを書き換える方法を認証:
ユーザーのユーザーオブジェクトパラメータのユーザ名を見つけるためによると、ユーザ名パラメータはユーザー名であり、それは電話の数であってもよいです
それはユーザーオブジェクトを見つけることができた場合は、正しいパスワードユーザオブジェクトかどうかを確認するcheck_passwordメソッドを呼び出します
ユーザー/ utils.py中に書きます:
django.contrib.auth.backends インポートModelBackend から .models インポートユーザーを から django.db.models インポートQ インポート再 DEF get_user_by_account(アカウント): 「」「ユーザーアカウント情報に基づいて取得モデル」「」 試してみる: #re.match IF ( '^ 1 [3-9] \ {D} $ 9'、アカウント): # # 電話番号 # ユーザ= User.objects.get(=モバイルアカウント) #他: # #ユーザ名 #1 ユーザ= User.objectsは.get(ユーザ名=アカウント) ユーザーUser.objects.get =(Q(モバイルアカウントを=)| Q(ユーザ名= アカウント)) を除いてUser.DoesNotExist: ユーザー = なし 返さないユーザー クラス:UsernameMobileAuthBackend(ModelBackend) DEF認証(自己、要求、ユーザ名=なし、パスワードを=いずれも、** kwargsから): #1 を決定するログ ユーザーを= get_user_by_account(ユーザー名) #のアカウントは、現在のステーションがアクティブな状態であるかどうか、パスワードによって検証する必要がある、との良好な裁判官 IFでisinstance(ユーザー、ユーザー)と user.check_password(パスワード)とself.user_can_authenticate(ユーザー): 返すユーザー
Djangoのsettings.pyは、当社独自の認証バックエンドで使用されるコンフィギュレーション・ファイルに通知します
AUTHENTICATION_BACKENDS = [ ' users.utils.UsernameMobileAuthBackend ' 、 ]
OK