ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [내일배움캠프] 1월 5일 목요일 TIL 회고록
    카테고리 없음 2023. 1. 5. 23:48

    회고록을 이쁘게 써야하는데 내일 프로젝트 제출이라 정리를 하며 회고록을 쓸 수 없었어서 예쁘게 정리를 할 수 없을 것 같다.. ㅠㅠ

     

    어제 팀원분들이랑 시간도 부족하고 다들 실력이 충분하지 않아 Lv 2 과제까지 하기로 했었는데 구현을 하지 못하는게 너무 아쉬울 것 같아

    내가 혼자 만든 Lv.2 과제에 시큐리티 구현을 하려고 했다. 어제 밤 부터 구글링 및 강의 자료를 보면서 혼자 조금씩 만들어봤다.

     

    문제가 있었다 : 실행 한 후 로그인을 하려고 하니 "this.userdetailsservice" is null 익셉션이 나오면서 아무것도 안됐다. 

    시도 해봤다 :  UserDetailsServiceImpl 클래스도 수정해보고 UserDetailsImpl 클래스도 수정해보고 JwtUtils 도 수정해보고 해볼 거 다해보고 구글링도 엄청 했다..

    해결 했다 :  JwtUtils에서 맨 위를 보니 이렇게 되어있었다. userDetailService가 회색부분이고 사용하지 않는다고 나와 final을 붙였다.

    private UserDetailsServiceImpl userDetailsService;

    final을 넣었더니 사용하기 시작했다. 이거 때문인가 싶어서 실행시키고 postman에서 로그인을 해보니 정상적으로 로그인이 된다.

    게시글 작성 및 댓글 작성도 문제없이 잘 된다.

    private final UserDetailsServiceImpl userDetailsService;

    알게 된 점 : 꼭 final 을 붙이자!


    여러가지 자잘한 오류들을 고치며 내 프로젝트에서 구현이 잘 되서 팀 프로젝트에 적용했다.

    거의 다 구글링이나 강의자료를 보며 만든거라 잊어버리지 말자라는 마음으로 복붙하지 않고 다 만들었다.

    만드는데 자잘한 문제가 있었는데, 내가 만든 스프링 부트 버전은 3.0.1 이고 팀 프로젝트 스프링 부트 버전은 2.7.6이라서 

    코드가 조금 달라서 처음에 당황했었다 ㅋㅋㅋ

     

    스프링 3.0.1

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable();
    
        // 기본 설정인 session 방식은 사용하지 않고 JWT 방식을 사용허기 위한 설정 STATELESS : 세션 사용 x
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
        http.authorizeHttpRequests()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .requestMatchers("/user/**").hasRole("USER")
                .anyRequest().permitAll();
    
        http.formLogin().disable();
    
        http.httpBasic().disable();
    
        // UsernamePasswordAuthenticationFilter 에 도달하기 전에 커스텀한 필터를 먼저 동작시킨다.
        http.addFilterBefore(new JwtAuthFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class);
    
        return http.build();
    }

    스프링 2.7.6

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    
        // token을 사용하는 방식이기 때문에 csrf를 disable하게 설정합니다.
        http.csrf().disable();
    
        // 기본 설정인 session 방식은 사용하지 않고 JWT 방식을 사용하기 위한 설정입니다.
        // STATELESS : 세선 사용 x
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
        // 요청에 관한 사용권한 체크
        http.authorizeHttpRequests()
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/admin/**").hasRole("ADMIN")
                // 그 외 나머지 요청은 누구나 접근 가능
                .anyRequest().permitAll();
    
        // token 방식으로 인증 처리를 해야해서 disable 처리 했습니다.
        http.formLogin().disable();
    
        // rest api 만을 고려하여 기본 설정은 해제하였습니다.
        http.httpBasic().disable();
    
        // UsernamePasswordAuthenticationFilter 에 도달하기 전에 커스텀한 필터를 먼저 동작시킵니다.
        http.addFilterBefore(new JwtAuthFilter(jwtutil), UsernamePasswordAuthenticationFilter.class);
    
        return http.build();
    
    
    }

    3.0.1은 .requestMatchers 을 사용하고 2.7.6은 .antMatchers를 사용한다. 그 외에는 변한건 없었다 다행히


    문제가 있었다 : 코드를 실행 해 보면서 몇몇 부분을 수정하고 로그인을 했는데 콘솔 창에 Encoded password does not look like BCrypt 이게 출력되서 파파고로 변역해보니 암호화된 암호가 BCrypt처럼 보이지 않습니다 라고 나왔다. 분명 난 암호화하는 코드를 넣었는데 ..

     

    시도를 했다 : WebSecurityConfig 클래스에서 이 부분을

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    이렇게 바꿔 본 후 실행을 해봤지만 결과는 같았다.  UserService에서도 몇몇 부분 건드려 봤는데 결과는 같았다.

      @Bean
        public PasswordEncoder passwordEncoder() {
            return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }

    해결을 했다: 강의 자료에서 암호화한 것을 보면서 코드를 수정했다.

     

    수정 전 회원가입 기능

    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    signupRequestDto.setPassword(passwordEncoder.encode(signupRequestDto.getPassword()));

    수정 후에는 String password를 선언하고 바로 암호화 코드를 수행하게 만들었다. 

    String password = passwordEncoder.encode(signupRequestDto.getPassword());

    그리고 바로 user 객체에 담은 뒤 userRepository에 넣었다.

    User user = new User(signupRequestDto.getUsername(), password, role);
    userRepository.save(user);

     

    수정 전 로그인 기능

    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    if (passwordEncoder.matches(user.getPassword(), password))

    수정 후 로그인 기능

     String password = loginRequestDto.getPassword();
            if (!passwordEncoder.matches(password,user.getPassword())) {
                throw new IllegalArgumentException("비밀번호가 올바르지 않습니다");
            }

    이렇게 코드를 만드니 로그인 시 Encoded password does not look like BCrypt 출력이 되지 않았다.

     

    느낀 점 : 너무 어렵다..ㅠㅠ

     

    이 후에 자잘한 부분을 수정하고 기능 구현 테스트를 해봤는데 문제 없이 전부 잘 작동한다.

    내가 테스트 했을땐 문제가 없어 깃허브에 커밋을 했다. 팀원분들한테 내일 테스트 해달라고 말하고 문제가 생기면 다시 수정해야겠다.

    이제 좋아요 부분만 만들면 기능 구현은 전부 완료된다. 내일도 엄청 바쁠 것 같다. 강의자료 만들고 해야하니까..

    그래도 오래 걸렸지만 스프링 시큐리티 기능을 구현하니까 기분은 엄청 좋다.

Designed by Tistory.