A, JWT 소개
1. JWT 무엇입니까
JSON 웹 토큰 (JWT)는 (특히 착륙 한 지점에 분산 된 사이트, JSON 기반 개발 표준 (7519 RFC는), 토큰은 컴팩트하고 안전하도록 설계되어 네트워크 응용 프로그램 실행 환경 사이를 통과하기 위해 문을입니다 SSO) 시나리오. JWT의 진술은 일반적으로 서버 자원을 얻기 위해 인증 된 사용자의 ID 정보를 제공하기 위해 신원 제공자와 서비스 제공자 사이에 사용됩니다, 당신은 또한 몇 가지 추가 비즈니스 로직을 다른 필요한 정보 문, 또한 토큰을 추가 할 수 있습니다 직접 인증에 이용 될 수는 암호화 될 수있다.
2 ,, 토큰 기반 인증 메커니즘
HTTP 프로토콜과 유사하게 사용자의 인증 정보 또는 세션 정보를 유지하기 위해 서버를 필요로하지 않는 무 토큰 기반 인증 메커니즘입니다. 응용 프로그램에서 어떤 서버 사용자가 로그인을 고려하는 인증 메커니즘 tokent 기회를 필요로하지 않습니다.이 응용 프로그램은 편리한 확장 기능을 제공합니다이 수단
이러한 프로세스는
- 사용자는 사용자 이름과 암호를 사용하여 서버를 요청
- 사용자 정보의 인증 서버
- 서버는 토큰을 확인하여 사용자에게 전송
- 클라이언트 저장 토큰, 토큰 및 요청에 따라 추가 값
- 데이터 서버 인증 토큰, 및 반환
이 토큰은 서버에 각 요청과 함께 전송해야하며,이 외에도 서버가 CORS (교차 리소스 공유) 전략을 지원하기 위해, 요청 헤더에 보관해야합니다, 우리는 일반적으로 그것을 액세스 제어 - 허용 서버를 -Origin : *
3 JWT 구성
JWT는 세 부분으로 구성되어, 정보의이 세 조각 JWT 텍스트 문자열로 링크를 구성한다. 이처럼
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U
우리 호 부하 (평면에 담지 항목 유사한 페이로드)의 두 번째 부분의 머리 (헤더), 세 번째 부분을 호출 첫 번째 부분은 비자 (서명) 인
머리글
JWT 헤드에 의해지지 두 가지 정보 :
- 유형 선언, 여기 JWT입니다
- 암호화 알고리즘의 주장은 일반적으로 HMAC SHA256 직접 사용
이 같은 다음 JSON 헤드를 완료
-
{
-
'typ':'JWT',
-
'alg':'HS256'
-
}
이어서 헤드 Base64로 암호화 (대칭을 해독 할 수있는 암호화 된) 제 1 부분을 구성
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
plyload
로드 로컬 스토리지는 유효 정보이다. 이름은 항공기 수행 등의 제품에 특별히 의미, 이러한 효과적인 정보는 세 부분으로 구성
- 표준 신고서
- 공공 문
- 개인 성명
등록 상표 문 (하지 않는 것이 좋습니다 필수 사용)
- ISS : JWT 발행
- 서브 : 사용자에 대한 JWT
- AUD : 수신 측 JWT
- 특급 : JWT 만료 시간을 만료 날짜는 시간의 문제보다 커야합니다
- NBF : 시간이 JWT 전에 정의는 무엇을 사용할 수 없습니다
- IAT : 시간의 문제 JWT
- JTI : JWT 고유 ID, 주로 재생 공격을 방지하기 위해, 한 번 토큰으로 사용된다
공공 문 :
공개 선언은 정보, 필요한 정보 또는 다른 비즈니스 요구 사항을 추가 할 수있는 사용자에 대한 일반 정보를 추가 할 수 있지만 클라이언트의 일부를 해독 할 수 있기 때문에, 민감한 정보를 추가하지 않는 것이 좋습니다;
개인 성명
64 기수가 일부 정보는 텍스트 정보의 이름으로 분류 될 수 있다는 것을 의미 대칭 암호 해독되기 때문에 개인 성명, 소비자 정의 함수 선언의 공급자이며, 일반적으로 민감한 정보를 저장하지 않는 것이 좋습니다.
페이로드를 정의
-
{
-
"sub": "1234567890",
-
"name": "John Doe",
-
"admin": true
-
}
64 기수 후, 얻어진 부분을 암호화 JWT
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
서명
세 번째 부분은 JWT 비자 정보는,이 비자 정보는 세 부분으로 구성되어 있습니다 :
- 헤더 (64 기수 후)
- 페이로드 (64 기수 후)
- secred
이 부분은 요구 스트링을 형성 할 "". base64로 페이로드 헤더와 암호화 된 암호화베이스 64을 사용하고, 암호화 된 헤더 조성물 암호화 첨가 비밀 선언하고, 제 3 부분은 JWT를 구성
-
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
-
var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
완전한 문자열로이 세 부분으로 연결, 최종 JWT를 구성하는 "."
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
참고 : 비밀은 서비스 측면에서도 발행 JWT, 서버 측에 저장되어있는 비밀은 서버의 개인 키하므로 고객이되면 어떤 시나리오에 공개해서는 안, 발행 및 JWT의 JWT를 인증하는 데 사용됩니다 이 비밀, 그것은 클라이언트가 JWT 자체 서명 할 수 있음을 의미 종료
신청
-
一般是在请求头里加入Authorization,并加上 Bearer 标注:
-
fetch('api/user/1', {
-
headers: {
-
'Authorization': 'Bearer ' + token
-
}
-
})
장점 :
- JWT가 교차 언어를 지원할 수 있도록 때문에 JSON의 다양성으로, C #, 자바 스크립트, NodeJS, PHP와 다른 언어처럼 사용할 수 있습니다
- 페이로드 부분의 때문에, JWT 비즈니스 로직은 자신의 민감하지 않은 일부 기타 필요한 정보를 저장할 수
- 수송의 용이성, JWT 구성은 그래서 교통에 매우 쉽게, 아주 간단한, 작은 점유 바이트
- 이 응용 프로그램을 확장하기 쉽습니다 그래서, 세션 정보를 저장하기 위해 서버를 필요로하지 않는다
안전 관련
- 일부 클라이언트 캔 해독의 일부이기 때문에 우리는 JWT의 페이로드 부분에 민감한 정보를 저장하지 말아야
- 비밀 개인 키를 보호합니다. 개인 키는 매우 중요하다
- 당신은 https 프로토콜을 사용하시기 바랍니다 할 수있는 경우
인터넷에서 정보,
특정보기 https://blog.csdn.net/u014799292/article/details/88365086
둘째, 전투
먼저 항아리 패키지에 도입
<의존성>
<의 groupId> io.jsonwebtoken </의 groupId>
<artifactId를> jjwt </ artifactId를>
<version>은 0.9.0 </ 버전>
</ 의존성>
도구의 새로운 JWT
공용 클래스 JwtTokenUtil {
최종 정적 문자열 = TOKEN_HEADER 공개 "권한 부여";
공공 정적 문자열 TOKEN_PREFIX 최종 = "무기명";
개인 정적 비밀 최종 문자열 = "jwtsecrettest";
개인 정적 ISS 최종 문자열 = "레오파드";
공공 정적 최종 긴 만료 = 3600L; // 만료 시간 일시간
공공 정적 최종 오래 EXPIRATION_REMEMBER = 604800L; // 칠일의 만료 후 나에게 시간을 기억을 선택
/ *
* 생성 토큰 방법
파라미터 : 사용자 이름
* @param isRemenberMe
* /
공공 정적 문자열 createToken (위에서 언급 한 ID 문자열, 문자열 사용자 이름, 부울 isRemenberMe) {
긴 만료 = isRemenberMe EXPIRATION_REMEMBER : 만료;?
// 문자열 encryId = RCUtils.(ID)를 encry_string;
반환 Jwts.builder (). signWith (SignatureAlgorithm.HS512, SECRET)
.setIssuer (ISS)
.setId (ID)
.setSubject (사용자 이름)
.setIssuedAt (새 Date ())
.setExpiration (새 날짜 (에 System.currentTimeMillis () + 만료 * 1000))
.compact ();
}
/ **
* 토큰에서 사용자 이름을 가져
파라미터 : 토큰
* @return
* @throws BusinessExpection
* /
문자열 getUserName 메서드 (문자열 토큰) BusinessExpection가 발생합니다 공공 정적 {
반환 getTokenBody (토큰) .getSubject를 ();
}
/ **
*에서 취득한 ID 토큰, 복호화 프로세스는하면서
* @param 토큰
* @return
* @throws BusinessExpection
* /
공공 정적 스트링 getObjectId (문자열 토큰) BusinessExpection {발생
복귀 getTokenBody (토큰) .getId ()
}
/ **
*왔다 만료
파라미터 : 토큰
* @throws 비정상적인 ExpiredJwtException를 캡처 만 판단 할 수 만료
* @return
* @throws BusinessExpection
* /
@Deprecated
isExpiration (문자열 토큰) 부울 공용 static 발생 BusinessExpection {
. 반환 getTokenBody (토큰) .getExpiration () 전에 (새 Date ());
}
/ *
*获取토큰信息,同时也做校验处理
*
* /
공공 정적 주장 getTokenBody (문자열 토큰)이 발생 BusinessExpection {
시도 {
Jwts.parser를 (반환)
.setSigningKey (비밀)
.parseClaimsJws (토큰)
.getBody () ;
} 캐치 (ExpiredJwtException이 만료) {
//过期
새로운 BusinessExpection (EmBussinsError.TOKEN_EXPIRED)를 던져;
} 캐치 (없는 SignatureException 전자) {
//无效하는
새로운 BusinessExpection (EmBussinsError.INVALID_REQUEST)를 던져;
} 캐치 (MalformedJwtException malformedJwt) {
//无效하는
새로운 BusinessExpection (EmBussinsError.INVALID_REQUEST)를 던져;
}
}
}
baseAction에서 통합 GET 토큰 값
사용자가 로그온 토큰을 반환 생성의 첫 단계.
@Controller
@RequestMapping ( "/ admin"입니다)
공용 클래스 AdminController이 BaseAction를 {확장
( "/ 로그인") @RequestMapping
@ResponseBody
공공 ResultType 로그인 (HttpServletRequest의 요청, HttpServletResponse를 응답) {
문자열 이름 = request.getParameter ( "이름");
문자열 패스 = request.getParameter ( "통과");
문자열 토큰 = JwtTokenUtil.createToken ( "10", 사용자 이름, 거짓);
response.setHeader (JwtTokenUtil.TOKEN_HEADER, JwtTokenUtil.TOKEN_PREFIX 토큰 +);
ResultType.creat ( "sussess")을 반환;
}
( "/ adminLoginOut") @RequestMapping
@ResponseBody
공개 ResultType adminLoginOut (HttpServletRequest의 요구)가 발생 BusinessExpection {
문자열 userId를 GETUSERID = (요청);
ResultType.creat ( "성공")을 반환;
}
}
시험은 GET 토큰 암호화의 성공 후 반환 정보 헤더 종류입니다
사용자 테스트에 로그인했다
오류가 토큰을 수행하지 않을 때
물론,이 오류가 모든 테스트는 간단한 있도록 작성 후 여기에 나는 사용자 정의 할 수 있습니다. 주요 기능은 테스트하는
토큰 전달, OK (확인)
작업이 성공적으로 완료되면 토큰과 토큰 인증이 성공적으로 수행한다.