web-dev-qa-db-ja.com

JWTの更新を適切に処理する方法は?

Androidアプリがあります。これはJerseyで開発されたREST APIに接続します。MyRESTエンドポイントはトークンで保護されています。以下は、それらを生成する方法です。

Algorithm algorithm = Algorithm.HMAC256(secret);
String token = JWT.create()
    .withClaim("userName","myusername)
    .withExpiresAt(expirationDate)
    .sign(algorithm);

以下はトークンを検証する方法です

public boolean validateTokenHMAC256(String token, String secret) throws UnsupportedEncodingException, JWTVerificationException
    {       
        Algorithm algorithm = Algorithm.HMAC256(secret);


        JWTVerifier verifier = JWT.require(algorithm) 
                .build(); //Reusable verifier instance
            DecodedJWT jwt = verifier.verify(token);

            Claim usernameClaim = jwt.getClaim("username");
            String username = usernameClaim.asString();
            System.out.println(username);


        return true;
    }

私のREST APIにはフィルターがあり、そのフィルターはすべてのリクエストをチェックして、トークンがそのままかどうかを確認します。以下にコードを示します。

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter{

    //private static String authorizationSecret = "ZXW24xGr9Dqf9sq5Dp8ZAn5nSnuZwux2QxdvcH3wQGqYteJ5yMTw5T8DBUJPbySR";

    public AuthenticationFilter()
    {
        System.out.println("test printing");
    }

    @Override
    public void filter(ContainerRequestContext crc) throws IOException
    {
        String headerString = crc.getHeaderString("Bearer");
        System.out.println("bluh: "+headerString);
        System.out.println("test printing");

        try
        {
            boolean validateToken = validateToken(headerString, AuthKey.authorizationSecret);
            System.out.println("valid");
        }
        catch(Exception e)
        {
            System.out.println("invalid");
            crc.abortWith(
                Response.status(Response.Status.UNAUTHORIZED).build());
        }

    }

    private boolean validateToken(String strToken, String secret) throws UnsupportedEncodingException, JWTVerificationException
    {
        Token token = new Token();
        return token.validateTokenHMAC256(strToken,secret);
    }



}

上記のコードは、ユーザーがアプリケーションにログインしたときに呼び出されます。ただし、トークンは60分で期限切れになります。トークンの有効期限が切れた後、ユーザーをサインイン画面に戻すか、トークンを更新する必要があることを知っています。 herehere でアドバイスを読みました

しかし、私は以下を理解していません。

  1. トークンを更新する必要があるかどうかはどうすればわかりますか?有効期限が切れた後でそれを行うべきだと思いましたが、そうではありません。 now<expで更新するように要求すると、すべてのリクエストで更新されます。

  2. このトークンを割り当ててユーザーに送信するにはどうすればよいですか?現在、ユーザーがログインすると、トークンを取得して変数に保存します。更新されたトークンを機能させるには、loginメソッドを再度呼び出す必要がありますか(トークンはユーザーに送信されます)、またはJWT自体がケースを処理しますか?

  3. Java-jwt を使用して実際に参照するにはどうすればよいですか?

10
Lemon Juice
  1. トークンを更新する必要があるかどうかはどうすればわかりますか?有効期限が切れた後でそれを行うべきだと思いましたが、そうではありません。今すぐリフレッシュしてもらったら

有効期限が切れる前にトークンを更新する必要があります。ポリシーを決定します。

  • すべてのリクエストで新しいトークンを発行する

  • 現在のトークンの有効期限が近づくと、新しいトークンを発行します。例えば10分

  • aPIの「更新サービス」を使用して、必要なときにクライアントアプリが新しいトークンをリクエストできるようにします。例えば


@GET
@Path("/jwt/refresh")
@Produces(MediaType.TEXT_HTML)
public String refresh(){
    //Build a returns a fresh JWT to client 
}
  1. このトークンを割り当ててユーザーに送信するにはどうすればよいですか?

リクエスト中に新しいトークンを発行する場合、レスポンスの処理中にクライアントが読み取る特別なヘッダーでそれを返すことができます。上記のように「更新」サービスを公開すると、現在のJWTの有効期限が近づいたときにクライアントが独立して呼び出します

現在のリクエストが失われるため、ログインメソッドへのリダイレクトは適切な代替手段ではありません

  1. Java-jwtを使用して実際に更新する方法

新しいトークンを発行するだけ

9
pedrofb