-
[Spring] SpringBoot Security 폼 로그인 (react, nginx)기초/SPRING 2022. 3. 27. 21:35
*표시는 배경지식
*인프런 강좌
[구성도]
더보기nginx > 로그인 페이지 ( react:3000 )
>>> 로그인 >>> 로그인처리 ( springboot:8081 )
>>> 성공,실패 리다이렉트 >>> nginx 주소
*Spring Security 참고자료
https://spring.io/guides/topicals/spring-security-architecture
https://godekdls.github.io/Spring%20Security/authentication/
https://jeong-pro.tistory.com/205
더보기SecurityContextHolder : security가 인증한 내용 + SecurityContext를 포함하고 있고 현재스레드와 securityCotnext를 연결
로그인이 완료되면 시큐리티 session을 만드는데 Security session은 SecurityContextHolder에 저장
Session Object는 Authentication Type으로 저장되며 Authentication 내부에서 사용자정보를 UserDetails 인터페이스로 저장
UserDetailsService 인터페이스는 DB와 연결해 User정보를 체크
AuthenticationProvider 인터페이스에서는 UserDetailsService 에서 리턴한 정보와 사용자가 입력한 정보를 비교
구현할 객체
WebSecurityConfigurerAdapter Extends Class : 스프링 시큐리티 적용
UserDetails Implements Class : 사용자의 정보
UserDetailsService Implements Class : DB에서 사용자를 가져올 서비스
SecurityConfig Class
@Configuration @EnableWebSecurity //스프링 시큐리티 필터가 스프링 필터체인에 등록 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Bean public BCryptPasswordEncoder encodePassword() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http .authorizeRequests() .antMatchers("/comment/commentSave").authenticated() .antMatchers("/user/**").authenticated() .antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')") .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .anyRequest().permitAll() .and() .formLogin() .defaultSuccessUrl("/") .failureUrl("/login?error") .loginPage("/login") .loginProcessingUrl("/dologin") .and() .logout() .logoutSuccessUrl("/") .deleteCookies("JSESSIONID") .logoutUrl("/dologout"); } }
PrincipalDetails Class
public class PrincipalDetails implements UserDetails{ private static final long serialVersionUID = 1L; private UserInfo userInfo; // composition //일반로그인 public PrincipalDetails(UserInfo userInfo) { this.userInfo = userInfo; } //해당 User의 권한을 리턴하는 곳 @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> collect = new ArrayList<>(); collect.add(new GrantedAuthority() { @Override public String getAuthority() { return userInfo.getUserRole(); } }); return collect; } @Override public String getPassword() { return userInfo.getUserPassword(); } @Override public String getUsername() { return userInfo.getInsUserName(); } @Override public boolean isAccountNonExpired() { //계정이 만료되었는가? return true; } @Override public boolean isAccountNonLocked() { //계정이 잠금상태인가? return true; } @Override public boolean isCredentialsNonExpired() { //계정 비밀번호가 몇일이 지났나? return true; } @Override public boolean isEnabled() { //계정이 활성화 되있나?? return true; } }
PrincipalDetailsService Class
@Service public class PrincipalDetailsService implements UserDetailsService{ @Autowired private UserInfoRepository userInfoRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { if(username == null || username.equals("")) { throw new UsernameNotFoundException(username); } UserInfo userInfo = userInfoRepository.findByInsUserName(username); if(userInfo == null) { throw new UsernameNotFoundException(username); } return new PrincipalDetails(userInfo); } }
*react form 전송방식
import axios from "axios"; import qs from 'qs'; const axiosConfig = { headers:{ "Content-Type": "application/x-www-form-urlencoded" } } const axiosBody = { username:userNameValue, userpassword:userPasswordValue } axios .post("http://localhost/dologin", qs.stringify(axiosBody), axiosConfig) .then((response) => { console.log(response.data); }) .catch((error) => { alert('에러가 발생했습니다.'); }); };
json > form 전송타입으로 변경
Content-type 변경 : application/x-www-form-urlencoded
body 변환
qs사용 , qs.stringfy
*nginx.conf
location = / { proxy_pass http://127.0.0.1:3000/; } location = /login { proxy_pass http://127.0.0.1:3000/; } location = /registry { proxy_pass http://127.0.0.1:3000/; } location ~ .static/(js|css|media)/(.+)$ { proxy_pass http://127.0.0.1:3000; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location / { proxy_pass http://localhost:8081; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
react에서 페이지로 사용되는 location들은 절대경로로 지정
react build시 나오는 static / js,css,media파일들을 예외로 지정
나머지 경로를 Spring Boot 경로로 지정
'기초 > SPRING' 카테고리의 다른 글
[Spring] SpringBoot Security 구글 로그인 (react, nginx) (0) 2022.03.27 [Spring] SpringBoot Security 회원가입 (react, nginx) (0) 2022.03.23 [Spring] 기본개념정리 (수정중) (0) 2022.03.23 [Spring] 시큐어 코딩 가이드 (0) 2022.01.03 전자정부 프레임워크 변경사항 (0) 2022.01.03