Java – JWT authentication: how to log off?

I implemented JWT authentication for my spring launch application In general, its working principle is as follows:

>The client sends the user name and password to the login endpoint. > The server checks whether the credentials provided are valid. > If not, it will return an error > If yes, it will return a token that actually contains > and the client will send the token in each future request

The question is, how should we implement cancellation?

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.Date;

class TokenAuthenticationService {
    static final long EXPIRATIONTIME = 864_000_000; // 10 days
    static final String SECRET = "ThisIsASecret";
    static final String TOKEN_PREFIX = "Bearer";
    static final String HEADER_STRING = "Authorization";

    static void addAuthentication(HttpServletResponse res,String username) {
        String JWT = Jwts
                .builder()
                .setSubject(username)
                .setExpiration(
                        new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(SignatureAlgorithm.HS512,SECRET).compact();
        res.addHeader(HEADER_STRING,TOKEN_PREFIX + " " + JWT);
    }

    static Authentication getAuthentication(HttpServletRequest request,UserDetailsService customUserDetailsService) {
        String token = request.getHeader(HEADER_STRING);
        if (token != null) {
            // parse the token.
            Claims claims = Jwts.parser().setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX,"")).getBody();
            String userName = claims.getSubject();
            Date expirationTime = claims.getExpiration();
            if (expirationTime.compareTo(new Date()) < 0) {
                return null;
            }
            UserDetails user = customUserDetailsService.loadUserByUsername(userName);
            return user != null ? new UsernamePasswordAuthenticationToken(user.getUsername(),user.getpassword(),user.getAuthorities()) : null;
        }
        return null;
    }
}

Jwtloginfilter class uses addauthentication to send authentication code during login, and 'getauthentication is used by jwtauthenticationfilter to filter all requests to endpoints

What are the best practices here?

Solution

I don't think there is a best practice here I think it depends on the application you are building and its requirements

The advantage of JWT is that they are stateless You do not need to query the database to verify the token This is good when you want to reduce the load on the database, but it is good when you want to invalidate existing non expired tokens

Possible solutions:

>Store the JWT in the database You can check which tokens are valid and which have been revoked, but in my opinion, it is completely contrary to the purpose of using JWT. > Delete token from client This will prevent the client from making an authenticated request, but if the token is still valid and others can access it, it can still be used This leads to my next point. > Token life cycle is short Let the token expire quickly Depending on the application, it may be a few minutes or half an hour When the client deletes its token, there will be a short time window for it to still be available The token is deleted from the client and has a short token lifetime, which does not require significant modifications to the back end However, the short life cycle of the token means that the user is constantly logged off because the token has expired. > Rotate tokens Perhaps the concept of refresh token is introduced When users log in, provide them with JWT and refresh token Store the refresh token in the database For authenticated requests, the client can use JWT, but when the token expires (or is about to expire), let the client use the refresh token to issue a request in exchange for a new JWT In this way, you only need to access the database when the user logs in or requests a new JWT When the user logs off, you need to invalidate the stored refresh token Otherwise, even if the user has logged off, someone can still get a new JWT when listening for the connection. > Create JWT blacklist Depending on the expiration time, when a client deletes its token, it may still be valid for a period of time If the token lifetime is short, it may not be a problem, but if you still want the token to expire immediately, you can create a token blacklist When the backend receives a logout request, it obtains the JWT from the request and stores it in the in memory database For each authenticated request, you need to check the in memory database to see if the token has expired In order to keep a small search space, you can delete expired tokens from the blacklist

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>