ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] SpringBoot Security 구글 로그인 (react, nginx)
    기초/SPRING 2022. 3. 27. 21:48

    *표시는 배경지식

    *인프런 강좌

    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/dashboard

     

    [구성도]

    더보기

    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 경로로 지정

    댓글

Designed by Tistory.