Token、JWT構造、Javaを初めて見たJJWT実装JWT(Token、Token認証とCookie認証の違いを簡潔に理解)

13307 ワード

1.なんてToken?
Tokenはトークンという意味で、クッキーやセッションと似ていて、一般的にはユーザー認証に使われています.ユーザ認証とは,既にログインしたユーザが再アクセスして再ログインしなくてもよいことであり,サーバはそのユーザが合法であると考えている.Tokenは現在web開発で広く使われている.
2.なぜTokenを使うのですか?
この問題は「認証メカニズム」の違いについてお話しします
  • HTTP Basic Authは、ユーザーがアクセスするたびにアカウントとパスワードを携帯します.最も簡単な認証ですが、アカウントとパスワードをサードパーティクライアントに暴露するため、リスクが大きいため、現在はほとんどそうしません.
  • Cookie Authは、最初のリクエスト時にサービス側でセッションオブジェクトを作成するとともに、ブラウザ側でcookieを作成し、その後のユーザリクエストはブラウザ内のcookieを携帯し、サービス側でsessionに一致する.
  • Token Auth、ユーザーがログインすると、サービス側はブラウザにToken(文字列)を送信し、ユーザーが再アクセスするとToken文字列を携帯します.もちろんToken文字列は暗号化されています.

  • 3.Tokenのメリットは何ですか?
    なぜクッキー認証を使わずにToken認証を使うのですか?もちろんToken認証はもっと優秀です
  • ドメイン間アクセスをサポートし、Cookieはドメイン間アクセスを許可しないが、Tokenは可能である.もちろんTokenはCookieに置くことはできない.HTTPヘッダに置く.
  • ステータスなし、ステータスがあるかどうかはサーバに情報を格納するかどうかであり、Cookie認証はサーバ側にセッション情報を格納する必要があるが、Tokenは不要である.ユーザに関する情報はTokenに格納されているため、サーバの圧力が大幅に軽減される.
  • より多くのプラットフォームに適用され、クライアントがオリジナルプラットフォーム(iOS、Android、Windows 8など)である場合、Cookieはサポートされません(Cookieコンテナで処理する必要があります)、Token認証メカニズムを採用するとより簡単になります.
  • 性能、Cookie認証はToken認証よりずっと遅い.Cookie認証はサーバ内のセッションを探す必要があるが、Tokenは復号するだけでよいからだ.

  • 4.JWTに基づくToken認証メカニズムの実現
    JSON Web Token(JWT)は非常に軽量な仕様です.この仕様では、JWTを使用して、ユーザーとサーバの間で安全で信頼性の高い情報を伝達できます.
    4.1 JWTの構成
    頭部、荷重、署名の3つの部分から構成されています.
    ヘッダ(Header)ヘッダは、JWTに関する最も基本的な情報、例えば、そのタイプや署名に使用されるアルゴリズムなどを記述するために使用される.これをJSONオブジェクトとして表すこともできます.
    {"typ":"JWT","alg":"HS256"}
    

    ヘッダには、署名アルゴリズムがHS 256アルゴリズムであることが示されている.BASE 64符号化を行います(符号化は暗号化ではありません)
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
    

    荷重(playload)荷重は有効な情報を格納する場所です.この名前は特に飛行機に搭載された貨物を指すようで、これらの有効な情報には3つの部分基準に登録された声明が含まれています(推奨されていますが強制的に使用しません)
    iss: jwt   
    sub: jwt      
    aud:   jwt   
    exp: jwt     ,               
    nbf:          , jwt      .
    iat: jwt     
    jti: jwt       ,         token,        。
    
    {"sub":"1234567890","name":"John Doe","admin":true}
    

    そしてこれをbase 64符号化してJwtの第2部分を得る.
    eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
    

    ビザ(signature)jwtの第3部はビザ情報である、このビザ情報は3部からなる:header(base 64後)、payload(base 64後)、secret(塩、加塩暗号化)という部分はbase 64暗号化後のheaderとbase 64暗号化後のpayloadが使用する必要がある.構成された文字列を接続し、headerで宣言された暗号化方式で塩secretを組み合わせて暗号化し、jwtの第3の部分を構成します.secret:
    TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
    

    この3つの部分を使います.完全な文字列に接続され、最終的なjwtを構成します.
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
    

    注意:secretはサーバ側に保存され、jwtの署名生成もサーバ側にあり、secretはjwtの署名とjwtの検証を行うために使用されるので、それはあなたのサービス側の秘密鍵であり、いかなるシーンでも漏らすべきではありません.クライアントがこのsecretを知ったら、クライアントはjwtを自己発行できることを意味します.
    5.JavaのJJWT実装JWT
    JJJWTは、エンドツーエンドのJWTの作成と検証を提供するJavaライブラリです.
    5.1クイックスタート
    環境mavenプロジェクト、座標のインポート
    		
                io.jsonwebtoken
                jjwt
                0.6.0
            
    

    5.1.1トークンの生成
    CreateJwtクラスの作成
    public class CreateJwt {
        public static void main(String[] args) {
            JwtBuilder jwtBuilder = Jwts.builder()
                    .setId("666")
                    .setSubject("  ")
                    .setIssuedAt(new Date())
                    .signWith(SignatureAlgorithm.HS256,"lois")//  
                    .setExpiration(new Date(new Date().getTime()+60000))//     1  
                    .claim("role","admin");//     
            System.out.println(jwtBuilder.compact());
        }
    }
    
  • setIssuedAt発行時間の設定に使用
  • signWith(使用する暗号化アルゴリズム、塩)署名鍵を設定するために使用
  • setExpirationは書く必要はありません.永久Tokenでもいいですが、これはお勧めしません
  • claimカスタム追加情報
  • クラスを実行すると、コンソールに出力が表示されます.
    eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2NjYiLCJzdWIiOiLlsI_mmI4iLCJpYXQiOjE1NjQzODg2ODl9.KryyWowEat-L86CwsTzEfCw9IPaw3wWf0ddj9H98c_4
    

    再実行すると、負荷に時間が含まれているため、実行するたびに結果が異なることがわかります.
    5.1.2解析トークン
    解析クラスParseJwtTestの作成
    public class ParseJwtTest {
        public static void main(String[] args) {
            Claims claims = Jwts.parser()
                    .setSigningKey("lois")
                    .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2NjYiLCJzdWIiOiLlsI_mmI4iLCJpYXQiOjE1NjQzOTEyMTEsImV4cCI6MTU2NDM5MTI3MSwicm9sZSI6ImFkbWluIn0.8JF9G6AX33wtzcdyT0NxpEsVEL2XEm5nklDtdykV5YI")
                    .getBody();
            System.out.println("  id:" + claims.getId());
            System.out.println("   :" + claims.getSubject());
            System.out.println("    :" + claims.get("role"));//       
            System.out.println("    :" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(claims.getIssuedAt()));
            System.out.println("    :" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(claims.getExpiration()));
        }
    }
    
  • 解析Jwtsのparserメソッド
  • を使用
  • setSigningKey設定解析塩
  • parseClaimsJwsトークンフィールド
  • 戻るClaimsはMapと同様であり、暗号化されたばかりの情報を取得することができる.
  • カスタム情報取得getメソッド
  • コンソール表示
      id:666
       :  
        :admin
        :2019-07-29 17:06:51
        :2019-07-29 17:07:51
    

    Tokenが期限切れになった後、解析クラスを再実行するとエラーが発生するので注意してください.
    Exception in thread "main" io.jsonwebtoken.ExpiredJwtException: JWT expired at 2019-07-29T16:57:47+0800. Current time: 2019-07-29T16:59:33+0800
    

    解析クラスにtry-catchを付けたほうがいいです
    作者の编纂は容易ではありませんて、転载して私のブログを明记してください、もし书くのが悪くないと感じたら、手当たり次第に少しいいです、ありがとうございます!!!作者の编纂は容易ではありませんて、転载して私のブログを明记してください、もし书くのが悪くないと感じたら、手当たり次第に少しいいです、ありがとうございます!!!作者の编纂は容易ではありませんて、転载して私のブログを明记してください、もし书くのが悪くないと感じたら、手当たり次第に少しいいです、ありがとうございます!!!