ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • jwt 최종 정리
    공부/기본 2023. 11. 24. 16:32

    - 클라이언트와 서버 간의 정보 전달에 주로 사용되는 토큰 기반 인증 방식

    - 이를 통해 클라이언트는 보호된 자원에 접근할 수 있습니다

     

    1. 토큰 발급

    -  keyPairGenerator로 RSA알고리즘을 사용한 공개키/개인키  쌍을 생성, 이를 통해 JWT를 생성

    - 생성된 JWT에는 사용자 ID가 주제로 설정, 만료 시간도 설정됩

    - signWith 메소드를 통해 RSA알고리즘과 개인키를 사용하여 서명

    public class JwtTokenProvider {
        private KeyPairGenerator keyPairGenerator;
        private KeyPair keyPair;
        private PrivateKey privateKey;
    
        public JwtTokenProvider() throws Exception {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            keyPair = keyPairGenerator.genKeyPair();
            privateKey = keyPair.getPrivate();
        }
    
        public String generateToken(String ownerId) {
            Date now = new Date();
            Date expiryDate = new Date(now.getTime() + 5400000); // 토큰의 만료 시간 설정
    
            return Jwts.builder()
                    .setSubject(userId) // 토큰의 주제 설정
                    .setIssuedAt(new Date()) // 토큰의 발행 시간 설정
                    .setExpiration(expiryDate) // 토큰의 만료 시간 설정
                    .signWith(SignatureAlgorithm.RS256, privateKey) // 토큰 서명
                    .compact();
        }
    }

     

    2. 토큰 인증

    클라이언트가 서버에 요청을 보낼 때 jwt를 헤더에 포함하여 보냄

    서버는 이 토큰을 공개키로 검증

    밑에 코드는 jwt를 검증, 토큰이 유효한지 반환

    public class JwtTokenProvider {
        private PublicKey publicKey;
    
        public JwtTokenProvider() throws Exception {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            publicKey = keyPair.getPublic();
        }
    
        public boolean validateToken(String token) {
            try {
                Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    }

     

    3. 토큰 사용

    - 서버는 인증된 요청을 처리하기 위해 토큰에서 사용자 id 추출

    @GetMapping("/notification/list")
    public ResponseEntity<ApiResponse> getUserNotification(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        String userId = jwtTokenProvider.getUserIdFromToken(token);
    
        val response = userService.getUserNotification(userId);
        return ResponseEntity.ok(ApiResponse.success(ResponseMessage.SUCCESS_GET_USER_NOTIFICATIONS.getMessage(), response));
    }

     

     

     

     


     

    ex) 로그인을 하여 jwt를 발급 받고 이를 사용해 게시글을 작성하는 과정

     

    1. 로그인과 jwt 발급

    @PostMapping("/login")
    public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
    
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginRequest.getUsername(),
                        loginRequest.getPassword()
                )
        );
    
        SecurityContextHolder.getContext().setAuthentication(authentication);
    
        String jwt = jwtTokenProvider.generateToken(authentication);
        return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
    }

    사용자 로그인 요청 처리, 인증 성공하면 jwt생성하여 반환

     

    2. 게시글 작성

    @PostMapping("/posts")
    public ResponseEntity<?> createPost(@Valid @RequestBody PostRequest postRequest, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        String userId = jwtTokenProvider.getUserIdFromToken(token);
        
        Post post = new Post();
        post.setTitle(postRequest.getTitle());
        post.setContent(postRequest.getContent());
        post.setUserId(userId);
        
        postRepository.save(post);
        
        return ResponseEntity.ok("Post created successfully");
    }

     

    사용자의 게시글 작성 요청을 처리

    클라는 게시글 작성 요청을 보낼 때 jwt를 헤더에 포함하여 전송

    서버는 토큰 검증

    토큰에서 사용자 id를 추출하여 게시글의 작성자로 설정

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    '공부 > 기본' 카테고리의 다른 글

    Optional  (1) 2023.11.21
    회원가입 SHA-256  (2) 2023.11.20
    예외 클래스의 계층구조  (1) 2023.11.20
    Spring MVC 아키텍처  (0) 2023.11.20
    @ExecptionHandler 코드 조금 더 보고 공부하기  (0) 2023.11.20
Designed by Tistory.