이전에 강의를 듣고 완성한 프로젝트를 복습겸 처음부터 다시 작성해보고 있는데, 개선할 사항들과 스프링 부트 업데이트로 인해 수정해야하는 코드들이 종종 눈에 띄어 기록해 놓는 것이 좋을 것 같아 다시 글을 쓰게 되었습니다.
💡 DI를 수행할 때 필드 직접 주입이 아닌 생성자 주입을 수행
- 인프런에서 들은 강의를 바탕으로 기존에 필드 직접 주입을 통해 DI 했던 방식에서 @RequiredArgsConstructor 어노테이션과 final 키워드를 사용한 생성자 주입 방식으로 변경하였습니다.
💡 스프링 버전 업데이트로 인해 스프링 시큐리티를 통한 로그인 시에 더 이상 WebSecurityConfigurerAdapter 클래스를 사용할 수 없으므로 이는 아래와 같이 수정하였음
package com.cos.blog.config;
@Configuration //빈등록 (IoC관리)
@EnableWebSecurity //security 필터 등록
@EnableGlobalMethodSecurity(prePostEnabled = true) //특정 주소로 접근하면 권한 및 인증을 미리 체크하겠다는 뜻
@RequiredArgsConstructor
public class SecurityConfig {
...
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/auth/**", "/js/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/loginForm")
.loginProcessingUrl("/auth/loginProc")
.defaultSuccessUrl("/");
return http.build();
}
}
💡 위와 관련하여 회원정보 수정 시에 세션 값을 직접 수정해주어야 하는 과정에서도 코드 작성 방법이 달라졌음.
package com.cos.blog.config;
@Configuration //빈등록 (IoC관리)
@EnableWebSecurity //security 필터 등록
@EnableGlobalMethodSecurity(prePostEnabled = true) //특정 주소로 접근하면 권한 및 인증을 미리 체크하겠다는 뜻
@RequiredArgsConstructor
public class SecurityConfig {
...
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
...
}
나머지 부분 코드는 동일
💡 카카오 로그인을 위해 구현한 코드들이 컨트롤러에 모여 있는 것을 서비스 단으로 옮겨주었음
package com.cos.blog.service;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder encoder;
private final AuthenticationManager authenticationManager;
@Value("${secrect.key}")
private String secrectKey;
...
@Transactional(readOnly = true)
public void kakaoLogin(String code) {
RestTemplate rt = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "51f6c7b1350fbf2b147798b81b8649a7");
params.add("redirect_uri", "http://localhost:8000/auth/kakao/callback");
params.add("code", code);
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(params, headers);
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);
ObjectMapper objectMapper = new ObjectMapper();
OAuthToken oauToken = null;
try {
oauToken = objectMapper.readValue(response.getBody(), OAuthToken.class);
} catch(JsonMappingException e) {
e.printStackTrace();
} catch(JsonProcessingException e) {
e.printStackTrace();
}
RestTemplate rt_ = new RestTemplate();
HttpHeaders headers_ = new HttpHeaders();
headers_.add("Authorization", "Bearer " + oauToken.getAccess_token());
headers_.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest =
new HttpEntity<>(headers_);
ResponseEntity<String> response_ = rt_.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoProfileRequest,
String.class
);
ObjectMapper objectMapper_ = new ObjectMapper();
KakaoProfile kakaoProfile = null;
try {
kakaoProfile = objectMapper_.readValue(response_.getBody(), KakaoProfile.class);
} catch(JsonMappingException e) {
e.printStackTrace();
} catch(JsonProcessingException e) {
e.printStackTrace();
}
User kakaoUser = User.builder()
.username(kakaoProfile.getKakao_account().getEmail() + "_" + kakaoProfile.getId())
.password(secrectKey)
.email(kakaoProfile.getKakao_account().getEmail())
.oauth("kakao")
.build();
User originUser = userRepository.findByUsername(kakaoUser.getUsername()).orElseGet(() -> {
return new User();
});
if(originUser.getUsername() == null)
join(kakaoUser);
Authentication authentication =
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(kakaoUser.getUsername(), secrectKey));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
'🚗 Backend Toy Project > 스프링 부트 게시판' 카테고리의 다른 글
[스프링부트 게시판] 24. Remember Me 기능 구현 (0) | 2022.06.29 |
---|---|
[스프링부트 게시판] 23. 로그인 실패 예외 처리 (0) | 2022.06.28 |
[스프링부트 게시판] 21. 댓글 구현 (2) | 2022.05.17 |
[스프링부트 게시판] 20. 카카오 로그인 (0) | 2022.05.16 |
[스프링부트 게시판] 19. 회원정보 수정 (0) | 2022.05.15 |