我为Spring启动应用程序实现了JWT身份验证。总的来说,它的工作原理如下:
问题是,我们应该如何实施注销?
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;
}
}
{p> addAuthentication
被JWTLoginFilter
类用于在登录时发送身份验证代码,&#39; getAuthentication is used by the
JWTAuthenticationFilter`,用于过滤对端点的所有请求。
这里的最佳做法是什么?
答案 0 :(得分:16)
我认为这里没有最好的做法。我想这取决于您正在构建的应用程序及其要求。
JWT的好处是他们无国籍。您不需要查询数据库来验证令牌。当您希望减少数据库的负载时这很好,但是当您想要使现有的非过期令牌无效时,这是很好的。
可能的解决方案:
答案 1 :(得分:3)
我不知道什么是最佳做法,但在我见过的内部系统中,有一个中央身份验证管理器,它知道所有当前有效的身份验证令牌,因此注销只包含从有效令牌集合中删除令牌。
因此,下次向身份验证管理器询问令牌是否有效时,它会响应&#34; no&#34;。
答案 2 :(得分:0)
答案 3 :(得分:0)
如果令牌保存在 localStorage 中:
localStorage.removeItem('token');
在服务器中,如果 jwt 在会话中:
req.session = null;
如果你想清除你设置的cookie
req.session.destroy((err) => { //express-session
res.clearCookie("qid"); //qid is the cookie name
}