JWT 생 성 토 큰

8216 단어 web
JWT 가 뭐야? 
     JSon web token (JWT) 은 네트워크 응용 환경 간 성명 전달 을 위 한 JSON 기반 개발 기준 (RFC 7519) 으로, 이 token 은 치밀 하고 안전 하 며 분포 식 사이트 의 단일 로그 인 (SSO) 장면 에 특히 적용 되도록 설계 되 었 다.JWT 의 성명 은 일반적으로 신분 제공 자 와 서비스 제공 자 간 에 인 증 된 사용자 신분 정 보 를 전달 하여 자원 서버 에서 자원 을 얻 을 수 있 도록 하고 다른 업무 논리 에 필요 한 성명 정 보 를 추가 할 수 있 으 며 이 token 은 인증 에 직접 사용 할 수도 있 고 암호 화 될 수도 있다.
왜 JWT 를 사용 합 니까?
기술 의 발전 에 따라 분포 식 웹 응용 이 보급 되면 서 session 을 통 해 사용자 의 로그 인 상 태 를 관리 하 는 비용 이 점점 높 아 지고 있 기 때문에 token 의 방식 으로 로그 인 신분 검 사 를 한 다음 에 token 을 통 해 redis 중의 캐 시 사용자 정 보 를 찾 습 니 다. 그 후에 jwt 가 출시 되면 서 검증 방식 은 더욱 간단 하고 편리 해 졌 습 니 다. redis 캐 시 를 통 해token 에 따라 저 장 된 사용자 정 보 를 직접 추출 하고 token 의 가용성 검사 에 따라 단일 로그 인 이 더욱 간단 합 니 다.모 바 일 앱 은 쿠키 가 없 기 때문에 Token 메커니즘 을 통 해 로그 인 후 인증 문 제 를 해결 합 니 다.
장점:
  • json 의 통용 성 때문에 JWT 는 C \ #, JavaScript, NodeJS, PHP 등 많은 언어 를 사용 할 수 있 습 니 다
  • .
  • payload 부분 이 있 기 때문에 JWT 는 자신 에 게 다른 업무 논리 에 필요 한 비 민감 한 정 보 를 저장 할 수 있다
  • 전송 이 편리 하고 jwt 의 구성 이 매우 간단 하 며 바이트 의 점용 이 매우 작 기 때문에 전송 이 매우 편리 하 다
  • 서버 에 세 션 정 보 를 저장 할 필요 가 없 기 때문에 사용 하기 쉬 운 확장
  •    
    1. 크로스 도 메 인 접근 지원: Cookie 는 크로스 도 메 인 접근 을 허용 하지 않 습 니 다. 이 점 은 Token 체제 에 존재 하지 않 습 니 다. 전 제 는 전 송 된 사용자 인증 정보 가 HTTP 헤드 를 통 해 전송 되 는 것 입 니 다.
    2. 무상 태 (서버 확장 가능): Token 메커니즘 은 서버 에서 session 정 보 를 저장 할 필요 가 없습니다. Token 자체 가 모든 로그 인 사용자 의 정 보 를 포함 하고 있 기 때문에 클 라 이언 트 의 쿠키 나 로 컬 미디어 에 상태 정 보 를 저장 해 야 합 니 다.서버 는 token 을 저장 하지 않 고 서버 의 압력 을 줄 일 필요 가 없습니다. 알고리즘 을 통 해 클 라 이언 트 가 보 내 온 token 을 분석 하여 데 이 터 를 얻 을 수 있 습 니 다.
    4. CDN 적용: 콘 텐 츠 배포 네트워크 를 통 해 서버 의 모든 자료 (예: javascript, HTML, 그림 등) 를 요청 할 수 있 으 며, 서버 는 API 만 제공 하면 됩 니 다.
    5. 결합 제거: 특정한 인증 방안 에 연결 할 필요 가 없습니다.Token 은 어디서 든 생 성 할 수 있 습 니 다. API 가 호출 될 때 Token 생 성 호출 을 하면 됩 니 다.
    6. 모 바 일 애플 리 케 이 션 에 더욱 적합 합 니 다. 클 라 이언 트 가 네 이 티 브 플랫폼 (iOS, Android, Windows 8 등) 일 때 쿠키 는 지원 되 지 않 습 니 다 (쿠키 용 기 를 통 해 처리 해 야 합 니 다). 이때 Token 인증 체 제 를 사용 하면 훨씬 간단 합 니 다.
    7. CSRF: 더 이상 Cookie 에 의존 하지 않 기 때문에 CSRF (크로스 오 버 사이트 위조 요청) 에 대한 예방 을 고려 할 필요 가 없습니다.
    8. 성능: 한 번 의 네트워크 왕복 시간 (데이터 베 이 스 를 통 해 session 정 보 를 조회) 은 HMACSHA 256 로 계 산 된 Token 검증 과 분석 을 하 는 것 보다 시간 이 많이 걸린다.
    9. 로그 인 페이지 를 위해 특별한 처 리 를 할 필요 가 없습니다. Protractor 를 사용 하여 기능 테스트 를 할 때 로그 인 페이지 를 위해 특별한 처 리 를 할 필요 가 없습니다.
    10. 표준화 기반: API 는 표준 화 된 JSON Web Token (JWT) 을 사용 할 수 있 습 니 다. 이 표준 은 이미 여러 백 엔 드 라 이브 러 리 (. NET, Ruby, Java, Python, PHP) 와 여러 회사 의 지원 (예 를 들 어 Firebase, Google, Microsoft) 이 존재 합 니 다.
     
     
    단점:
       1. JWT 는 상태 가 없 기 때문에 서버 에서 생 성 된 Token 의 실 효 를 제어 할 수 없고 제어 할 수 없습니다.   2. jwt 를 얻 으 면 로그 인 권한 이 있 기 때문에 jwt 는 누설 할 수 없습니다. 사 이 트 는 https 를 사용 하여 중간 공격 으로 jwt 를 훔 치 는 것 을 방지 하 는 것 이 좋 습 니 다. 
    전통 적 인 session 인증
        http 프로 토 콜 자체 가 무상 태 프로 토 콜 이라는 것 을 알 고 있 습 니 다. 이 는 사용자 가 Google 애플 리 케 이 션 에 사용자 이름과 비밀 번 호 를 제공 하여 사용자 인증 을 한다 면 다음 요청 시 사용 자 는 다시 한 번 사용자 인증 을 해 야 한 다 는 것 을 의미 합 니 다. http 협의 에 따라 저 희 는 어느 사용자 가 보 낸 요청 인지 알 수 없 기 때 문 입 니 다.그래서 우리 의 응용 프로그램 이 어느 사용자 가 보 낸 것 인지 식별 하기 위해 서 우 리 는 서버 에 사용자 가 로그 인 한 정 보 를 저장 할 수 밖 에 없습니다. 이 로그 인 정 보 는 응답 할 때 서버 에 전달 되 고 쿠키 로 저장 되 어 다음 요청 할 때 우리 에 게 보 내 는 응용 프로그램 을 알려 줍 니 다. 그러면 우리 의 영 어 는 요청 이 어느 사용자 에서 왔 는 지 식별 할 수 있 습 니 다.이것 이 바로 전통 적 인 sessino 인증 기반 이다.
           그러나 이러한 session 기반 인증 으로 인해 응용 자체 가 확장 되 기 어렵 습 니 다. 클 라 이언 트 를 사용 하지 않 아 도 증가 함 에 따라 독립 된 서버 는 더 많은 사용 자 를 불 러 올 수 없습니다. 이 럴 때 session 인증 응용 을 바탕 으로 하 는 문제 가 드 러 날 것 입 니 다.
     session 인증 에 나타 난 문제점
           Session: 모든 사용자 가 우리 의 응용 인증 을 거 친 후에 우리 의 응용 프로그램 은 서버 에서 한 번 기록 하여 사용자 가 다음 에 요청 한 감별 을 할 수 있 도록 해 야 합 니 다. 일반적으로 session 은 메모리 에 저장 되 고 인증 사용자 가 증가 함 에 따라 서버 의 비용 이 현저히 증가 할 것 입 니 다.
            확장 성: 사용자 인증 후 서버 에서 인증 기록 을 합 니 다. 인증 기록 이 메모리 에 저장 되면 사용자 가 다음 요청 을 할 때 이 서버 에 요청 해 야 권한 을 수 여 받 은 자원 을 얻 을 수 있 습 니 다. 이렇게 분포 식 응용 에서 응답 하 는 것 은 부하 이퀄 라이저 의 능력 을 제한 하고 응용 확장 성 을 제한 한 다 는 뜻 입 니 다.
            CSRF: 쿠키 를 기반 으로 사용 자 를 식별 하기 때문에 쿠키 가 캡 처 되면 사용 자 는 크로스 오 버 사이트 에서 위 조 를 요청 하 는 공격 을 받 기 쉽다.
    token 기반 인증 메커니즘
        token 기반 인증 체 제 는 http 프로 토 콜 과 유사 하 며, 서버 에서 사용자 의 인증 정보 나 세 션 정 보 를 보관 할 필요 가 없습니다.이것 은 기회 tokent 인증 체제 의 응용 이 사용자 가 어느 서버 에 로그 인 했 는 지 고려 할 필요 가 없다 는 것 을 의미한다. 이것 은 응용의 확장 에 편 의 를 제공 했다.
         흐름 이 이 렇 습 니 다.
  • 사용자 가 사용자 이름 비밀번호 요청 서버 사용
  • 서버 에서 사용자 정보 검증
  • 서버 가 인증 을 통 해 사용자 에 게 token
  • 을 보 냅 니 다.
  • 클 라 이언 트 는 token 을 저장 하고 요청 할 때마다 이 token 값 을 추가 합 니 다
  • 서버 에서 token 을 검증 하고 데 이 터 를 되 돌려 줍 니 다
  •       token 은 요청 할 때마다 서버 에 보 내야 합 니 다. 요청 헤더 에 저장 해 야 합 니 다. 또한 서버 는 CORS (크로스 소스 자원 공유) 정책 을 지원 해 야 합 니 다. 보통 서버 에서 이렇게 하면 됩 니 다. Access - Control - Allow - Origin: *
    흐름
    1. 사용자 인증.인증 방식 이 많 을 수 있 습 니 다. 스스로 인증 하거나 sso.
    2. 인증 후 서버 구조 JWT.
    3. JWT 를 클 라 이언 트 에 되 돌려 주 고 클 라 이언 트 가 저장 합 니 다.
    4. 클 라 이언 트 가 서버 에 접근 하고 JWT 를 가 져 옵 니 다.
    5. 서버 측 에서 JWT 가 정확 하고 시간 을 초과 하지 않 았 는 지 판단 하고 정상 적 이 며 아래로 흐른다.그렇지 않 으 면 권한 수여 로 넘 어 갑 니 다.
    서버 쪽
    1. jwt 생 성
    1.1 jwt 생 성 시기, 인증 후 인증 결과 로 돌아 가기 전.
    1.2. Payload (많은 번역 은 직역 이 고 이해 에 도움 이 되 지 않 습 니 다) 에서 속성 을 어떻게 디자인 하 는 지 이것 은 가 독성 에 비교적 중요 합 니 다.
    JWT 의 기준 에 따 르 면 이러한 clams 는 다음 과 같은 세 가지 유형 으로 나 눌 수 있다.
    a. Reserved clams (보류) 의 의 미 는 프로 그래 밍 언어의 보존 글자 처럼 JWT 표준 에 규정된 claim 에 속한다.JWT 표준 에 정 해진 claim 은 다음 과 같다.
    iss (Issuser): 이 JWT 의 발급 주 체 를 대표 합 니 다.
    sub (Subject): 이 JWT 의 주체, 즉 모든 사람 을 대표 합 니 다.
    aud (Audience): 이 JWT 의 수신 대상 을 대표 합 니 다.
    exp (Expiration time): 이 JWT 의 만 료 시간 을 대표 하 는 시간 스탬프 입 니 다.
    nbf (Not Before): 시간 스탬프 입 니 다. 이 JWT 가 효력 이 발생 하 는 시작 시간 을 대표 합 니 다. 이 시간 전에 JWT 를 검증 하 는 것 이 실패 할 것 임 을 의미 합 니 다.
    iat (Issued at): 이 JWT 의 서명 시간 을 대표 하 는 시간 스탬프 입 니 다.
    jti (JWT ID): JWT 의 유일한 표지 입 니 다.
    b. Public claims
    c. Private clams, 이것 은 사용자 정의 claim 을 가리킨다.예 를 들 어 앞의 그 구조 예 에서 admin 과 name 은 모두 자체 적 인 claim 에 속한다.이러한 클 레 임 과 JWT 표준 에 규정된 클 레 임 의 차 이 는 JWT 가 규정 한 클 레 임 이다. JWT 의 수신 자 는 JWT 를 받 은 후에 이런 기준의 클 레 임 을 어떻게 검증 하 는 지 알 고 있다.반면 private clams 는 수신 자 에 게 이러한 claim 에 대해 검증 과 규칙 을 명 확 히 알려 주지 않 는 한 검증 하지 않 는 다.
     자바 코드
    1. 의존 도 추가
                io.jsonwebtoken             jjwt             0.6.0  
     
    2. jwt 도구 클래스
    @ConfigurationProperties("jwt.config")
    public class JwtUtil {
    	// 
        private String key ;
        //    
        private long ttl ;
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public long getTtl() {
            return ttl;
        }
    
        public void setTtl(long ttl) {
            this.ttl = ttl;
        }
    
       
        /**
         *   JWT
         * @param id   id
         * @param subject     
         * @param roles    key-value   
         * @return
         */
        public String createJWT(String id, String subject, String roles) {
        	//signWith(SignatureAlgorithm.HS256, key)       ,   。     
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            JwtBuilder builder = Jwts.builder().setId(id)
                    .setSubject(subject)
                    .setIssuedAt(now)
                    .signWith(SignatureAlgorithm.HS256, key)
                    .claim("roles", roles);
            if (ttl > 0) {
            	//      
                builder.setExpiration( new Date( nowMillis + ttl));
            }
            return builder.compact();
        }
    
        /**
         *   JWT
         * @param jwtStr
         * @return
         */
        public Claims parseJWT(String jwtStr){
            return  Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(jwtStr)
                    .getBody();
        }
    
    }
    

     
    2. 테스트
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class DemoApplicationTests {
    
    	@Autowired JwtUtil jwtUtil;
    	
    	@Test
    	public void testJwt() {
    		//  token
    		String createJWT = jwtUtil.createJWT("1", "sj", "admin");
    		System.out.println(createJWT);
    		//
    	}
    	@Test
    	public void testgetJwt() {
    		//  token  
    		String token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwic3ViIjoic2oiLCJpYXQiOjE1NDgyMTc4ODgsInJvbGVzIjoiYWRtaW4ifQ.FnOVnfz69gH9ovTkw2AEvHvKSBKxdvAZvGV4nYFLKGk";
    		try {
    			Claims parseJWT = jwtUtil.parseJWT(token);
    			System.out.println(parseJWT.getId()+parseJWT.getSubject()+parseJWT.get("roles"));
    		} catch (Exception e) {
    			System.out.println("    !");
    		}
    		
    		
    	}
    
    }
    

    좋은 웹페이지 즐겨찾기