스프링 시큐리티 로그인 코드 분석

2023. 4. 6. 12:20WEB

    @PostMapping("/login")
    //-RequestBody는 요청본문(http프로토콜의 요청방식) 사용자가 입력한데이터가 본문에 들어어고 본문을 받는것?
    //-프론트에서 로그인 버튼을 누르면 검증후 성공시 ajax 방식으로 form 데이터를 보낸다. 보낸것이 MemberFormDTO에 매팽됨.
    public ResponseEntity<?> login(@RequestBody MemberFormDto memberFormDto) throws Exception {
        Authentication authentication; // 스프링 시큐리티 로그인 객체 불러오기

        try { // 스프링 시큐리티를 이용한 로그인 확인.

            //authentication 이란 인증된 사용자의 정보를 담는 시큐리티 객체
            //-스프링 시큐리티의 인증을 처리하는 인터페이스는 authenticationManager이다.
            //-autowired 를 통해 authenticationManager의 구현객체인 ProviderManager을 주입한다.

            authentication = authenticationManager.authenticate( //-프론트에서 받은 이메일과 비번을 인증하는 메소드이다.
                    //인증의 과정은 다음과 같다. 메소드 안에서는 UserDetailsService를 구현한 객체가 주입되고
                    //(여기서 구현 객체는 CustomUserDetailsService이다.) 구현 객체의 loadUserByUsername에서 인증된다.

                    new UsernamePasswordAuthenticationToken( //사용자가 입력한 username과password를 담는 객체
                            memberFormDto.getEmail(),
                            memberFormDto.getPassword()
                    ) //정상적으로 인증되었다면 실행된다.
            );
        } catch (BadCredentialsException e) { //틀렸다면 throw된 예외를 catch한다.
            ResponseDTO responseDTO = new ResponseDTO();
            responseDTO.setError("ID나 PASSWORD가 틀립니다.");  //응답 dto에 에러메세지를 담아서 응답한다.
            return ResponseEntity.badRequest().body(responseDTO); //-비동기 방식 에러메시지 보내기
        }

        // SecurityContextHolder란 단일 사용자의 인증 정보를 저장하고 관리하는 컨테이너고 세션과 비슷하지만 각각의 스레드에서 단일 사용자만
        // 저장하는 차이가 있다. (접속이 끊어지면 스레드도 삭제된다)
        SecurityContextHolder.getContext().setAuthentication(authentication); //컨테이너에 사용자의 인증 정보를 넣는다.
        UserDetails userDetails = (UserDetails) authentication.getPrincipal(); //유저 정보를 가져와서 USERDetails 로 형변환한다.
        //Princpal은 '인증된' 사용자의 정보를 담는 객체이다. 하지만 getPrincipal() 메소드는 Object 타입으로 리턴되기때문에
        //실제로 사용할경우 UserDetails 사용자 정보를 담는 객체로 형변환을 한 후 사용해야한다.

        String token = tokenProvider.create(userDetails);  //사용자 정보에 해당하는 토큰을 만들고
        MemberFormDto responseMemberFormDto = new MemberFormDto();
        responseMemberFormDto.setToken(token);

        return ResponseEntity.ok(responseMemberFormDto); //비동기 방식으로 클라이언트 http바디에 토큰과 맴버dto를 보낸다.

        //간단 정리
        //로그인시 서버에서 사용자가 입력한 정보를 인증하고 인증이 완료되면
        //인증 정보에 따라서 토큰을 만든다 제작된 토큰은 클라이언트의 http body에 전송되고
        //사용자의 인증이 필요할때마다 서버에게 토큰을 보낸다.
        //서버는 받은 토큰을 SecurityContextHolder 에서 검증한다.
    }

조장님이 쓰신것에 주석을 달아보았다.

'WEB' 카테고리의 다른 글

JWT 발급부분 코드분석  (0) 2023.04.06
클라이언트의 요청 방식  (0) 2023.04.02
서버와 클라이언트  (0) 2023.04.01