spring boot+jwt api 구현 token 인증 상세 설명
이 편 은 jwt(json web token)의 사용 을 공유 합 니 다.그녀 는 주로 인터페이스 에 접근 하 는 token 과 검증 을 생 성 하 는 데 사 용 됩 니 다.springboot 와 단독으로 결합 하여 api 인터페이스 token 검증 을 개발 하 는 것 이 편리 합 니 다.jwt 의 token 에 사용자 의 정보 가 저장 되 어 있 고 암호 화 되 어 있 기 때문에 분포 식 에 적 용 됩 니 다.이렇게 직접 합 시다.정 보 는 사용자 로 컬 에 저장 되 어 서버 에서 sessiion 이나 token 의 압력 을 줄 였 습 니 다.
다음 빠 른 사용:
<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<!-- FastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
일반적으로 jwt 를 사용 하여 3 가지 결과 에 도달 합 니 다.jjwt 의존 도 를 도입 한 후 token 을 생 성 하 는 것 이 편리 합 니 다.하나의 token 에 있어 유일한 것 이 고 거 스 를 수 없 는 것 을 대표 하기 때문에 우 리 는 생 성 할 때 유일한 데 이 터 를 추가 해 야 합 니 다.예 를 들 어 아래 의 id:
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //
.setSubject("system") //
.setIssuer("shenniu003") //
.setAudience("custom") //
.compressWith(CompressionCodecs.GZIP) //
.signWith(SignatureAlgorithm.HS256, encryKey) //
.setExpiration(new Date(currentTime + secondTimeOut * 1000)) //
.addClaims(claimMaps) //cla
.compact();
uid 를 통 해 유일한 id 정 보 를 표시 합 니 다.물론 token 을 암호 화 할 때 비밀 키 를 사용 해 야 합 니 다.jwt 는 HS 256,HS 265,Md5 등 복잡 하고 자주 사용 하 는 암호 화 방식 을 지원 합 니 다.jwt 가 생 성 한 token 의 내용 은 세 부분 으로 나 뉜 다.head 정보,payload 정보,sign 정보 이다.보통 우리 가 해 야 할 일 은 payload 에 사용자 정 보 를 추가 하 는 것 이다(예 를 들 어 계 정,닉네임,권한 등 이지 만 비밀 번 호 는 포함 되 지 않 는 다).jwt 의 token 에 대해 어느 정도 알 고 있 는 후에 실제 생 성 된 token 값 을 살 펴 보 겠 습 니 다.
eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAAFWMTQ7CIBSE7_LWkPDzaEsP4QnYINCIptX4INE0vbtg4sLlfPPN7HAtGWbwg1BKL4GrcbEcIwpujZF8iiEpjXFapAAG2ReYpUEcR2VxYED13Nb0ppLW3hP1eEnblqsQuiFfY0OhUrl3I70evweU_aFSejZhd7DlcDv5NTmYHUilHTD3rf_hAccHRTv--7YAAAA.i4xwoQtaWI0-dwHWN8uZ4DBm-vfli5bavYU9lRYxU5E
token 이 유효한 지 검증token 이 생 성 될 때 수반 되 는 실효 시간 이 있 습 니 다.이 경우 setExpiration 함수 로 만 료 시간 을 설정 할 수 있 습 니 다.jwt 의 유효 시간 은 미 끄 러 지 는 것 이 아니 라 는 것 을 기억 하 십시오.즉,어떠한 처리 도 하지 않 을 때 첫 번 째 설정 의 실효 시간 에 도 착 했 을 때 거의 사용 되 지 않 습 니 다.token 이 만 료 되 었 는 지 여 부 를 가 져 오 려 면 다음 과 같은 방식 을 사용 할 수 있 습 니 다.
public static boolean isExpiration(String token, String encryKey) {
try {
return getClaimsBody(token, encryKey)
.getExpiration()
.before(new Date());
} catch (ExpiredJwtException ex) {
return true;
}
}
여기에 date before 를 사용 하여 얻 은 만 료 시간 과 현재 시간 을 비교 하여 계속 유효한 지 여 부 를 판단 합 니 다.주의해 야 할 것 은 token 이 실 효 된 후에 getClaims Body(token,encry Key)를 통 해 정 보 를 얻 으 면 Expired JwtException 오 류 를 보고 하고 만 료 되 었 다 고 생각 할 수 있 습 니 다.token 의 jwt 정보 가 져 오기(주요 사용자 정보)
일반적으로 저 희 는 로그 인 사용자 정 보 를 jwt 에서 생 성 된 token 에 저장 해 야 합 니 다.여 기 는 addClaims(claimMaps)를 통 해 map 를 전달 하여 정 보 를 설정 할 수 있 고 반대로 token 의 사용자 정 보 를 얻 으 려 면 이렇게 해 야 합 니 다.
return Jwts.parser()
.setSigningKey(encryKey)
.parseClaimsJws(token)
.getBody();
이때 body 는 Claims 형식 을 가 져 옵 니 다.사용자 정 보 를 가 져 와 야 합 니 다.주의해 야 할 것 은 addClaims 가 정 보 를 저장 할 때 저 장 된 map 값 이 만들어 지지 않 으 면 완전한 실체 대상 이 저장 되면 LinkHasMap 형식 으로 매 핑 됩 니 다.다음 과 같 습 니 다.따라서 보통 저장 할 때 json 화 됩 니 다.다음 과 같은 코드 입 니 다.
claimMaps.forEach((key, val) -> {
claimMaps.put(key, JSON.toJSONString(val));
});
그리고 get 방법 을 통 해 우리 가 저장 한 정 보 를 얻 고 json 의 반 직렬 화 입 니 다.
/**
* body
*
* @param token
* @param encryKey
* @param key
* @return
*/
public static Object getVal(String token, String encryKey, String key) {
return getJws(token, encryKey).getBody().get(key);
}
/**
* body ,json
*
* @param token
* @param encryKey
* @param key
* @param tClass
* @param <T>
* @return
*/
public static <T> T getValByT(String token, String encryKey, String key, Class<T> tClass) {
try {
String strJson = getVal(token, encryKey, key).toString();
return JSON.parseObject(strJson, tClass);
} catch (Exception ex) {
return null;
}
}
여기에 오 면 Jwt 의 Util 코드 가 기본적으로 완성 되 었 습 니 다.다음은 완전한 코드 예 를 보 여 드 리 겠 습 니 다.참고 하 시기 바 랍 니 다.
public class JwtUtil {
/**
* token - json map
*
* @param claimMaps
* @param encryKey
* @param secondTimeOut
* @return
*/
public static String getTokenByJson(Map<String, Object> claimMaps, String encryKey, int secondTimeOut) {
return getToken(claimMaps, true, encryKey, secondTimeOut);
}
/**
* token
*
* @param claimMaps
* @param isJsonMpas
* @param encryKey
* @param secondTimeOut
* @return
*/
public static String getToken(Map<String, Object> claimMaps, boolean isJsonMpas, String encryKey, int secondTimeOut) {
if (isJsonMpas) {
claimMaps.forEach((key, val) -> {
claimMaps.put(key, JSON.toJSONString(val));
});
}
long currentTime = System.currentTimeMillis();
return Jwts.builder()
.setId(UUID.randomUUID().toString())
.setIssuedAt(new Date(currentTime)) //
.setSubject("system") //
.setIssuer("shenniu003") //
.setAudience("custom") //
.compressWith(CompressionCodecs.GZIP) //
.signWith(SignatureAlgorithm.HS256, encryKey) //
.setExpiration(new Date(currentTime + secondTimeOut * 1000)) //
.addClaims(claimMaps) //cla
.compact();
}
/**
* token claims
*
* @param token
* @param encryKey
* @return
*/
private static Jws<Claims> getJws(String token, String encryKey) {
return Jwts.parser()
.setSigningKey(encryKey)
.parseClaimsJws(token);
}
public static String getSignature(String token, String encryKey) {
try {
return getJws(token, encryKey).getSignature();
} catch (Exception ex) {
return "";
}
}
/**
* token head
*
* @param token
* @param encryKey
* @return
*/
public static JwsHeader getHeader(String token, String encryKey) {
try {
return getJws(token, encryKey).getHeader();
} catch (Exception ex) {
return null;
}
}
/**
* payload body
*
* @param token
* @param encryKey
* @return
*/
public static Claims getClaimsBody(String token, String encryKey) {
return getJws(token, encryKey).getBody();
}
/**
* body
*
* @param token
* @param encryKey
* @param key
* @return
*/
public static Object getVal(String token, String encryKey, String key) {
return getJws(token, encryKey).getBody().get(key);
}
/**
* body ,json
*
* @param token
* @param encryKey
* @param key
* @param tClass
* @param <T>
* @return
*/
public static <T> T getValByT(String token, String encryKey, String key, Class<T> tClass) {
try {
String strJson = getVal(token, encryKey, key).toString();
return JSON.parseObject(strJson, tClass);
} catch (Exception ex) {
return null;
}
}
/**
*
*
* @param token
* @param encryKey
* @return
*/
public static boolean isExpiration(String token, String encryKey) {
try {
return getClaimsBody(token, encryKey)
.getExpiration()
.before(new Date());
} catch (ExpiredJwtException ex) {
return true;
}
}
public static String getSubject(String token, String encryKey) {
try {
return getClaimsBody(token, encryKey).getSubject();
} catch (Exception ex) {
return "";
}
}
}
필터 인증 token기본 적 인 JwtUtil 도구 가 있 습 니 다.springboot 프로젝트 에 사용 해 야 합 니 다.일반적으로 로그 인 권한 수여 token 인증 은 필 터 를 통 해 작 동 할 수 있 습 니 다.authenFilter 를 만 들 고 post 가 요청 한 token 을 검증 할 수 있 습 니 다.
public class AuthenFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest rq = (HttpServletRequest) servletRequest;
HttpServletResponse rp = (HttpServletResponse) servletResponse;
RpBase rpBase = new RpBase();
try {
// post
if (!rq.getMethod().equalsIgnoreCase("post")) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
String token = rq.getHeader("token");
if (StringUtils.isEmpty(token)) {
rpBase.setMsg(" token");
return;
}
//jwt
MoUser moUser = JwtUtil.getValByT(token, WebConfig.Token_EncryKey, WebConfig.Login_User, MoUser.class);
if (moUser == null) {
rpBase.setMsg("token ");
return;
}
System.out.println("token :" + moUser.getNickName());
filterChain.doFilter(servletRequest, servletResponse);
} catch (Exception ex) {
} finally {
if (!StringUtils.isEmpty(rpBase.getMsg())) {
rp.setCharacterEncoding("utf-8");
rpBase.setCode(HttpStatus.BAD_REQUEST.value());
rp.getWriter().write(JSON.toJSONString(rpBase));
}
}
}
}
사용자 정의 필터 AuthenFilter 가 유효 하 다 면 용기 에 등록 해 야 합 니 다.여 기 는 인 코딩 방식 을 통 해@WebFilter 주 해 를 통 해 용기 에 추가 할 수 있 습 니 다.
@Configuration
public class WebFilterConfig {
@Bean
public FilterRegistrationBean setFilter() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new AuthenFilter());
registrationBean.addUrlPatterns("/api/*");
registrationBean.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
return registrationBean;
}
}
addUrl Patterns 가 필터 역할 을 하 는 url 연결 과 일치 하 는 것 을 주의 하 십시오.수요 에 따라 정 합 니 다.효 과 를 검증 하기 위해 서 저 는 두 개의 인터페이스 getToken 과 t0 을 만 들 었 습 니 다.각각 token 과 post 조회 인 터 페 이 스 를 가 져 왔 습 니 다.코드 는 다음 과 같 습 니 다.
@RestController
public class TestController {
@PostMapping("/api/t0")
public String t0() throws MyException {
return UUID.randomUUID().toString();
}
@GetMapping("/token/{userName}")
public String getToken(@PathVariable String userName) {
MoUser moUser = new MoUser();
moUser.setUserName(userName);
moUser.setNickName(userName);
Map<String, Object> map = new HashMap<>();
map.put(WebConfig.Login_User, moUser);
return JwtUtil.getTokenByJson(map,
WebConfig.Token_EncryKey,
WebConfig.Token_SecondTimeOut);
}
}
최종 적 으로 헤드 를 통 해 token 값 을 전달 하여 t01 인 터 페 이 스 를 방문 하여 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.token 은 유효 시간 후 접근 에 실 패 했 습 니 다.token 을 새로 가 져 오고 t01 인 터 페 이 스 를 방문 하여 성공 적 인 정 보 를 얻 었 습 니 다.
git 주소:https://github.com/shenniubuxing3
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Node JS에서 액세스 토큰 및 새로 고침 토큰을 사용한 JWT 인증우리 모두는 모든 애플리케이션에서 가장 중요한 기능이 인증이라는 것을 알고 있습니다. 인증을 훨씬 더 안전하게 만들고 더 나은 사용자 경험을 제공하려면 앱에서 새로 고침 및 액세스 토큰 기반 인증을 사용해야 합니다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.