JWT 인증 방식의 실현
5573 단어 Java 학습
기본 프로세스
1, 우선 서버에서 로그인 요청을 받았을 때 요청 헤더에 영패가 있는지 확인합니다(첫 로그인은 반드시 없습니다).서버는 계정 비밀번호가 모두 통과된 것을 검증하는 상황에서 token(즉 영패)을 생성하여 응답 헤더에 추가하여 클라이언트에게 되돌려줍니다.2, 클라이언트가 token을 받은 후에 모든 요청은 요청 헤더에 이 token을 가지고 와서 신분을 검증해야 합니다.3, token이 효력을 잃었을 때 서버는 클라이언트에게 영패가 만료되었다고 통지하고 로그인 요청을 다시 보내서 새로운 token을 가져옵니다.
필요한 의존
com.auth0
java-jwt
3.1.0
생성token
public static String getToken(final String userId,final String role) {
String token = null;
try {
Long currentTime = System.currentTimeMillis();
String tokenId = new StringBuilder(String.valueOf(currentTime)).append(userId).toString();
Date expiresAt = new Date(currentTime + 10L * 60L * 1000L);
token = JWT.create()
//
.withIssuer("")
//
.withClaim("userId", userId)
.withClaim("role",role)
//
.withIssuedAt(new Date(currentTime))
// id
.withJWTId(tokenId)
// token
.withExpiresAt(expiresAt)
// HMAC256 。
.sign(Algorithm.HMAC256("SECRET_KEY"));
} catch (JWTCreationException exception){
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return token;
}
그중.sign(Algorithm.HMAC256("SECRET_KEY")에서 HMAC256 방법으로 서버에 설정된 키를 암호화하여 token이 위조되는 것을 방지합니다.따라서 이 키는 반드시 잘 저장해야 한다. 유출되면 클라이언트가 임의로 토큰을 서명할 수 있다는 것을 의미한다.
token 검사
public static Boolean decryptToken(final String token) {
if (token == null){
return false;
}
DecodedJWT jwt = null;
try {
// HMAC256 。
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(GlobalConstant.SECRET_KEY))
.withIssuer("")
.build(); //Reusable verifier instance
// , JWTVerificationException InvalidClaimException
jwt = verifier.verify(token);
} catch (JWTVerificationException exception){
//Invalid signature/claims
return false;
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
verifier.verify(token)에서 서명의 시간 초과 여부를 검사했습니다. 시간 초과는 InvalidClaimException을 던져 원본 코드를 첨부합니다.
private void assertValidDateClaim(Date date, long leeway, boolean shouldBeFuture) {
Date today = this.clock.getToday();
today.setTime((long)Math.floor((double)(today.getTime() / 1000L * 1000L)));
boolean isValid;
String errMessage;
if (shouldBeFuture) {
today.setTime(today.getTime() - leeway * 1000L);
isValid = date == null || !today.after(date);
errMessage = String.format("The Token has expired on %s.", date);
} else {
today.setTime(today.getTime() + leeway * 1000L);
isValid = date == null || !today.before(date);
errMessage = String.format("The Token can't be used before %s.", date);
}
if (!isValid) {
throw new InvalidClaimException(errMessage);
}
}
전송 및 수신 token
@ApiOperation(" ")
@PostMapping("login")
public ResponseData login(@RequestBody Account account, HttpServletRequest request, HttpServletResponse response){
// token
String token = request.getHeader("Authorization");
//token , token
if (token == null){
//
// ...
//
// token
response.addHeader("Authorization",getToken(user.getUserId(), user.getRole()));
}else {
// token
if(decryptToken(token)){
//
}else {
// token ,
}
}
}
상기 코드는 기본적으로 로그인 인증을 실현할 수 있습니다. 이외에도 주의해야 할 점이 있습니다. 전방에서 되돌아오는 token을 받을 때 Refused to get unsafe header'Authorization'을 제시합니다. 이것은 Authorization의 header가 우리가 정의한 것이기 때문입니다. 해결 방법은 크로스 처리 부분에 Access-Control-Expose-Headers를 추가하는 것입니다.
response.setHeader("Access-Control-Expose-Headers","Authorization");
Token 만료에 대한 생각
jwt를 사용하는 인증 방식은 확장하기 쉽지만, 사용자가 로그아웃 작업을 실행한 후, 또는 사용자가 비밀번호를 수정한 후, 현재의 token은 효력을 상실해야 하지만, jwt는 현재의 token을 즉시 효력을 상실할 수 없을 것 같습니다.만약에 서버가 모든 token을 기록하는 방식을 사용한다면 jwt의 디자인 취지와 어긋난다.국내외의 일부 방법을 훑어보았는데 비교적 흔히 볼 수 있는 것은 블랙리스트 목록을 설정하여 버려진 토큰을 블랙리스트에 넣는 것이다.블랙리스트를 실현하는 방법은 매우 간단하다. redis의 특성은 이 수요에 완벽하게 적응할 수 있다. 사용자가 로그인한 후에 우리는 token의 tokenId를 redis 키 값에 맞는 키로 설정하고 token은value로 설정하며 token의 시간 초과 시간을 기한이 지난 시간으로 설정하여 사용 시간이 만료되지 않았지만 버려진 token에 접근하는 문제를 피할 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JWT 인증 방식의 실현1, 우선 서버에서 로그인 요청을 받았을 때 요청 헤더에 영패가 있는지 확인합니다(첫 로그인은 반드시 없습니다).서버는 계정 비밀번호가 모두 통과된 것을 검증하는 상황에서 token(즉 영패)을 생성하여 응답 헤더에...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.