기초/SPRING
[Spring] SpringBoot Security 구글 로그인 (react, nginx)
장동규
2022. 3. 27. 21:48
*표시는 배경지식
*인프런 강좌
[구성도]
더보기
Nginx 80 >> react 3000 로그인페이지 접속
react로그인에서 구글로그인 접속
구글 redi
구글로그인 이후 react 조회페이지로 이동
*Oauth2
applcation.yml Oauth2 추가
더보기
spring:
security:
oauth2:
client:
registration:
google:
client-id: [id]
client-secret: [pw]
scope:
- email
- profile
redirect-uri: http://localhost/login/oauth2/code/google
redirect주소를 nginx포트로 변경
SecurityConfig
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
private PrincipalOauth2UserService principalOauth2UserService;
@Bean
public BCryptPasswordEncoder encodePassword() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/user/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.defaultSuccessUrl("/")
.failureUrl("/login?error")
.loginPage("/login")
.loginProcessingUrl("/dologin")
.and()
.logout()
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.logoutUrl("/dologout")
.and()
.oauth2Login()
.loginPage("/login")
.userInfoEndpoint()
.userService(principalOauth2UserService);
}
}
PrincipalDetails Class
public class PrincipalDetails implements OAuth2User{
private static final long serialVersionUID = 1L;
private UserInfo userInfo; // composition
private Map<String, Object> attributes;
public PrincipalDetails(UserInfo userInfo, Map<String, Object> attributes) {
this.userInfo = userInfo;
this.attributes = attributes;
}
//해당 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 Map<String, Object> getAttributes() {
// TODO Auto-generated method stub
return this.attributes;
}
@Override
public String getName() {
return null;
// return this.attributes.get("sub").toString();
}
}
PrincipalOauth2UserService Class
@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService{
@Autowired
private UserInfoRepository userInfoRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
// TODO Auto-generated method stub
OAuth2User oAuth2user = super.loadUser(userRequest);
String provider = userRequest.getClientRegistration().getClientId(); //google
String providerid = oAuth2user.getAttribute("sub"); // 12355657568678
String username = provider+"_"+providerid; //google_123456678899
String role = "ROLE_USER";
UserInfo userInfo = userInfoRepository.findByInsUserName(username);
if(userInfo == null) {
userInfo = UserInfo.builder()
.insUserName(username)
.userRole(role)
.provider(provider)
.providerid(providerid)
.build();
userInfoRepository.save(userInfo);
}
return new PrincipalDetails(userInfo, oAuth2user.getAttributes());
}
}
*UserInfo null체크를 통해 저장하는 로직은 사용자를 자동등록해주는 로직이다.
*react 구글요청
window.location.href = '/oauth2/authorization/google';
*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 경로로 지정