I implemented JWT authentication for my Spring boot app. Overally, it works like this:
The question is, how should we implement logout ?
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;
}
}
addAuthentication
is used by the JWTLoginFilter
class to send the authentication code when logging in, 'getAuthentication is used by the
JWTAuthenticationFilter` that filter all requests to the end points.
What is the best practice here ?
I don't think there is a best practice here. I guess it depends on the application you're building and it's requirements.
The benefit of JWT is that they're stateless. You don't need to query the database to validate the token. This is good when you wish to reduce the load on your database but bad when you want to invalidate an existing non-expired token.
Possible solutions:
I don't know what's best practice, but in a system whose internals I have seen, there is a central authentication manager which knows all the currently valid authentication tokens, so logging out would simply consist of removing the token from the collection of valid tokens.
So, next time the authentication manager is asked whether the token is valid, it would respond with a "no".
1) Simply remove the token from the client
2) Create a token blacklist
3) Just keep token expiry times short and rotate them often
Please have a look at Invalidating JSON Web Tokens Invalidating JSON Web Tokens
if the token is saved in localStorage:
localStorage.removeItem('token');
in server, if jwt is in a session:
req.session = null;
if you wanna clear the cookie you set
req.session.destroy((err) => { //express-session
res.clearCookie("qid"); //qid is the cookie name
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.