2.스프링 시큐리티[회원가입 만들기]

SecurityConfig

@EnableWebSecurity에 의해 스프링 시큐리티 필터가 스프링 필터 체인에 등록된다.

BCryptPasswordEncoder는 String으로 되어있는 패스워드를 암호화해준다.
이를 빈으로 등록했기 때문에 스프링 컨테이너 안에서 Autowired나 생성자 주입 등으로 자유롭게 주입해서 쓸 수 있다.

WebSecurityConfigurerAdapter에서 Override한 configure()를 이용하여 인증, 인가를 설정할 수 있다.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder(); //<- 비밀번호 암호화를 해준다.
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();//<-사이트간 위조 방지 disable

        http.authorizeRequests()
                .antMatchers("/api/diary/**").authenticated()// api/diary/ 로 시작하는 url 은 인증 필요
                .anyRequest().permitAll() // 그외에는 다 허용
                .and()
                .formLogin()// 로그인이 필요하면
                .loginPage("/loginForm");// loginForm 뷰로 이동.
    }
}

LoginController

url이 “/join”이고 post 요청이면, 회원 가입 dto 내의 패스워드를 BCryptPasswordEncoder에 의해 암호화한다. 저장이 완료되면 로그인 폼으로 다시 리다이렉트한다.

단, join()에서 이미 있는 엔티티인지 확인하는 로직이 없기 때문에 키 제약 위반 등의 예외가 발생한다.

@Controller
public class LoginController {

    private final WriterService writerService;

    private final BCryptPasswordEncoder bCryptPasswordEncoder;
		
		public LoginController(WriterService writerService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.writerService = writerService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

		@PostMapping("/join")
    public String join(UserJoinRequestDTO dto) {
        logger.info("writer join");

        String encodedPassword = bCryptPasswordEncoder.encode(dto.getPassword());
        writerService.saveWriterWithSecurity(dto.getName(), dto.getEmail(), encodedPassword, Role.User);

        return "redirect:/loginForm";
    }
}

아래는 실제 mysql에 저장된 테스트 결과다.
패스워드가 암호화된다.


GlobalExceptionHandler (403 에러 캐치)

인증되지 않았을 때의 상태인 403 에러(Forbidden)를 캐치하는 메서드를 추가하였다.

@ControllerAdvice
public class GlobalExceptionHandler {
	  //허가되지 않은 접근일때 캐치
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ExceptionHandler(AccessDeniedException.class)
    public ModelAndView handle403() {
        logger.info("not authorized");
        return new ModelAndView("403");
    }
}

좋은 웹페이지 즐겨찾기