본문 바로가기

Spring Boot

1. OAuth2.0 구글 로그인

의존성

 

프로젝트 만들 때 Security 에서 Oauth2 Client 체크해도 좋고

 

 

pom.xml에 넣어도 좋다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

 

 

 내가 만든 PrincipalService를 타면 안되고

Oauth 서비스를 타야함.

구글서버에 요청

로그인 페이지를 돌려준다.

 

로그인 되고나면 응답할 때 code를 주는 방식이 대표적이다. Server가 client에게 code를 돌려주면 인증 끝났다.

인증뿐만아니라 권한도 필요함..

이 code를 가지고 token을 요청할 수 있다. 응답으로 Access Token을 받고 나면 권한을 얻은 것이다.

구글서버에 요청하면

동의 화면이 뜬다. => scope를 체크하는 것이다. (어떤 어떤 데이터만큼 허락해서 서버에서 들고 와서 쓸 수 있다.)

즉 이 Access token 으로 scope만큼 자원서버한테 데이터를 요청할 수 있다. Access token, scope두개를 가지고 자원서버에 요청할 수 있다.

이때 access token하고 scope를 돌려준다. ??

 

security로그인이 되면 

 

구글, 페이스북 로그인 하면 

OAuthDetailService를 타게하면 된다.

 

구글, 페이스북은 마직막으로 리다이렉션해주는 정보 구성(회원정보)가 같음. 그래서 스프링이 이둘을 표준으로 해서 여기에 맞춰서 스프링이 제공해주고 있다. 

하지만 각 다른 포털사이트별로 마직막으로 리다이렉션해주는 정보 구성(회원정보)이가 다릅니다. 그래서 커스터마이징해서 맞춰줘야 한다. 리다이렉션 주소도 다를 수 있다. 이것도 맞춰야 한다.

 

 

 

OAuth Clinet를 쓰면 코드 받는것 , 토큰 날려서 자원받는거, 회원 정보에대한 모델 만든것

이런 것이 다 생략이 가능하다.

 

 

OAuthDetail만 구현하면 (OAuthDetailsService)만 만들면 회원정보 요청까지 모두 다 해줌

최종적으로 리다이렉션 할때마다 홈페이지마다 다름

 

구글하고 페이스북은 ? 똑같다.

->구글하고 페이스북이 표준으로 설정되어서 카카오랑 네이버가 점차적으로 맞춰가면 인터페이스가 되는것이다.

 

카카오랑 네이버로 이 라이브러리를 쓸려면 커스터마이징을 좀 해서 최종적으로 받는 값(회원 정보)을 고쳐줘야한다.

->그대로 쓰면 구글하고 페이스북에 쓰는 방식이 안먹힘

 

 

login.html의 <body>에 추가한다.

	<h1>Social Login</h1>
	<br />
	<!-- javascript:; 는 클릭해도 반응을 없게 하는 키워드 -->
	<a href="/oauth2/authorization/google" >
	<!-- 이 주소가 구글이 규칙으로 정해놓은 부분이라서 마지막/뒤에 provider을 수정할 수 있다. -->
	 <img
		src="https://pngimage.net/wp-content/uploads/2018/06/google-login-button-png-1.png"
		alt="google" width="357px" height="117px">
	</a>
	<br />
	<a href="/oauth2/authorization/facebook"> 
	<!-- facebook : provider // 규칙이라서 주소 적을 때 이 틀을 따라줘야 한다. 그러면 oauth가 낚아챈다. 그래서 provider로그인 화면을 받는다.-->
	 <img
		src="https://pngimage.net/wp-content/uploads/2018/06/login-with-facebook-button-png-transparent-1.png"
		alt="facebook" width="357px" height="117px">
	</a>

 

oauth clinet를 사용하면 컨트롤러를 만드는게 아니라

고정된 주소를 만들어두면 /oauth2/authorization/을 낚아채서

맨 끝에 google 이나 facebook을 보고 구분한다.

 

내 서버가 구글서버에대한 클라이언트가 되어야 한다.

새프로젝트 생성하고

 

OAuth 2.0 클라이언트 ID 만들 때 

 

동의 화면 구성 눌러서 스코프 설정으로 이동

 

 

스코프 설정

 

스코프 :

인증을 받고나서 토큰으로 자원서버에 요청할 수있는 정보들

 

승인된 자바스크립트 출처

기본적으로 모든 도메인은 CORS 정책이 걸려있어서 
다른 도메인에서 자바스크립트로 요청은 다 막음

 

 

승인된 리디렉션 URI 코드를 돌려받는 주소
요청하고나서 CODE값 받는 것

아래 주소는 내마음대로 적는것이 아니라 아래와같이 적는것이 규칙이다 마지막 / 뒤에 provider만 바꿀 수 있다.

http://localhost:8080/login/oauth2/code/goole

 

1. OAtuh로그인으로 받은 것과

2. 일반 로그인을 

예를 들어 쇼핑몰을 운영하려면 하나의 세션으로 관리해야한다.

 

application.yml    자동완성!

 

 

application.yml파일에  client-secret 이 노출되니까 나중에 git에 commit할 때 ignore할 거다.

 

 

사이트마다 scope가 달라요

facebook

publicprofile이라는 이름으로 있고

 

1.인증서

yml 파일 보안 신경쓰는법

여기에다가 중요한 정보를 적어두면 노출될 수 있는데
암호화 파일을 하나 만들어서 ex) bootsecurity.p12

열려고하면 인증서가 필요하게 만든다.

 

 

2.파일만들어서

외부 C드라이브에 파일을 만들어두고 
git에는 배포 안되게 연결만 해두는 것이다.

 


git 코드를 보고 되짚어봄

SecurityConfig에서 OAuth2.0을 사용해서 login 할때 설정을 적어준다.

 

두 가지로 로그인(내가 만든 로그인, 그리고 뭐 google 로그인)이 가능 그러면 세션이 두개 생긴다. 

 

로그인 어디로 해서 들어왔는지에 따라 구분하고 그럼 세션 따로 만들어지고 하면 ... 별로라서 합칠건데!!

 

 

 

implements OAuth2User도 하고 나면 아래 두 함수를 오버라이드 해야한다.

 

 

 

PrincipalOauth2UserService.java

 

 extends DefaultOAuth2UserService한다.

 

loadUser자동완성 오버라이드된다.

 

return super.loadUser(userRequest);

 

여기서 userRequest를 만드는게 핵심이다!

 

PrincipalDetail에 Oauth를 이용해서 로그인하고나면 받는 회원정보들을 저장한다.

 

받아온 회원정보를 분석해보자. console에 표시해 본다.

 

//회원정보
oAuth2User : 
Name: [114450571785918570047], ->프로바이더 아이디

Granted Authorities: [[ROLE_USER, SCOPE_htt~~~~~~~~~~~~~~~

User Attributes: [{

sub=114450571785918570047, -> 프로바이더 아이디
name=문선현, 
given_name=선현, 
family_name=문, 
picture=https:/~~~.jpg,

User Attributes: [{

sub=114450571785918570047, -> 프로바이더 아이디
name=문선현, 
given_name=선현, 
family_name=문, 
picture=https:/


// 내 스프링서버가 들고 있는 메모리 서버
userRequest ClientRegistration: 
ClientRegistration{

registrationId='google', 
clientId='553872203531-n7rubmfpj5o9db57vmnqu9no~~~~~~~,

clientSecret='NK9K_DrVwjWSVAHDty7Y6Qu3', 
clientAuthenticationMethod=org.springframewor~~~~~~~~~,

authorizationGrantType=org.springframework.security.oauth2.core.Auth

redirectUriTemplate='{baseUrl}/{action}/oauth2/code/{registrationId}',  // 로그인하고 나면 여기로 돌아옴.
scopes=[email, profile], 

providerDetails=org.springframework.security.oauth2.client.registration.ClientReg~~~~,

clientName='Google'}

 

주문시 주소  
sub=114450571785918570047 =>이거는 프로바이더아이디 

이런 회원정보를 파싱해서 자바 오브젝트로 만들어야겠지.. 
json으로 주지도 않았네.. 

 

User { 

id : 자동증가값 
username : 프로바이더_프로바이더아이디(스코프의 이메일값으로 하면 충돌남) 다른 API서버랑 충돌나지 않게 하기 위해서
password : 어쩌구저쩌구 -> 나만 알고 있는 값을 해쉬해서 넣기// null해도 상관없는데 그러면 사용자들이 null을 줄수도 있어서.. 안됨. userdetailservice 
email : 스코프의 이메일, 
provider : 프로바이더(google) 
providerId : 프로바이더아이디(번호값) 

}

 

내일마저..공부!