본문 바로가기
Vue.js

[Vue.js] 20. Google OAuth 2.0 사용하기 (3)

by 청양호박이 2021. 4. 14.

지난 시간에 이어서 Goolge OAuth 2.0을 web application에 적용하는 방법을 알아보겠습니다. 전체적인 단계는 아래의 
순서로 살펴보겠습니다.

 

  • Create user authorization credentials
  • web application에 적용해서 Login / Logout 구현하기
  • Token 전송 및 Google API 호출 / 사용하기

 

현재까지 진행된 단계를 살펴보면, Create user authorization credentials을 수행하였고 web application에서 Google OAuth로 Login 단계를 진행하여 해당 web application에서 개별 사용자의 접근 정보를 사용할 수 있도록 승인하는 부분까지 구현이 되었습니다. 

 

이를 통해서, Google에 개인 profile정보를 바로 받아와서 표출할 수 있었습니다. 이 부분까지 진해이 되었다면 web application의 Back-End의 접근을 위해서 다음 절차를 진행해야 합니다. 우선 전체적인 Google OAuth에 대한 인증 절차에 대해서 간단히 살펴보겠습니다. 

 

그림처럼 동작을 하는데... 하나하나 단계적으로 서술해보면 아래와 같습니다. 

 

  1. web application에 접속한 사용자가 화면에서 보이는 "Sign in with Google" 버튼을 클릭합니다.
  2. 해당 버튼은 Google에서 제공하는 child window를 띄우는데, 혹시 Google로그인이 안되어 있다면 로그인 창을 띄워주고... 로그인이 되어있을 경우에서 해당 web application에서 인증권한을 사용하기 위한 OAuth창을 띄워줍니다.
  3. 사용자는 해당 내용을 확인하여 승인을 합니다.
  4. Google은 승인의 결과로 해당 사용자의 BasicProfile과 ID Token을 web application에 전송해 줍니다.
  5. 이제 Front-End단 에서의 인증은 끝났습니다. Google에서부터 전달받은 ID Token으로 Back-End에 서비스 제공을 요청하게 됩니다. 
  6. Back-End에서는 전달받은 ID Token에 대해서 검증을 해야합니다. 이를 위해서, Google에 검증요청을 합니다.
  7. 검증이 완료되면, Google을 통해서 결과 및 PayLoad... 즉 사용자의 정보를 받아옵니다. 
  8. 이제 완벽하게 검증된 사용자로 인식이 되었고, Back-End에서는 application의 자체 Token을 발행하여 사용자에게 전달합니다.
  9. 향후, 사용자의 요청은 이 App Token을 통해서 서비스가 진행되게 됩니다.

 

기존에 1 ~ 4번까지는 구현이 완료되었습니다. 이제 차근차근 이후 순번에 대해서 구현해 보겠습니다. 

 

 

1. ID Token의 Back-End 전송


SPA로 구현한 web application에서 Google 로그인을 사용하는 경우 서버에서 현재 로그인 한 사용자를 식별해야 할 수 있습니다. 이렇게하려면 사용자가 성공적으로 로그인 한 후 HTTPS를 사용하여 사용자의 ID 토큰을 서버로 보냅니다. 그런 다음 서버에서 ID 토큰의 무결성을 확인하고 토큰에 포함 된 사용자 정보를 사용하여 세션을 설정하거나 새 계정을 만드는 절차로 진행되게 됩니다. 

 

따라서, Google OAuth 2.0 을 통해서 가져온 id token을 Back-End로 보내는 방법에 대해서 알아보겠습니다. 세부적인 방법은 Google Developers에서 가이드 하는 내용을 따라서 구핸해 보겠습니다. 가이드는 https post로 request하는 방식을 권고합니다. 현재는 Back-End가 http이기 때문에 추후에 https를 적용해보도록 하겠습니다. 가이드의 일환으로 Content-Type을 'application/x-www-form-urlencoded'로 하여 id token을 보내겠습니다. 

적용을 위한 세부내용은 아래의 이전글을 참조해주세요~ 

2021.04.08 - [SpringBoot] - [Spring Boot] 28. REST API (4) - POST method 와 Content-Type

 

[Spring Boot] 28. REST API (4) - POST method 와 Content-Type

일반적으로 Spring Boot에서 POST method로 개발한 Rest API를 제공한다고 하면, 보통은 json 형태의 data를 body에 넣어서 보내면 정상적으로 동작할 것이라고 생각합니다. 이런 POST 방..

ayoteralab.tistory.com

실제 적용된 코드는 아래와 같습니다. 

 

[Controller]

	@RequestMapping(value = "tokenVerify", method = RequestMethod.POST)
	public ResponseEntity<?> tokenVerify(String idToken){
		System.out.println("RequestBody value : " + idToken);
	
		return null;
	}

[axios]

    tokenVerify() {
      const url = '/tokenVerify';
      const params = new URLSearchParams();
      params.append('idToken', this.idToken);
      axios.post(url, params).then((res) => {
        // eslint-disable-next-line
        console.log(res);
      }).catch((error) => {
        // eslint-disable-next-line
        console.log(error);
      }).then(() => {
        // eslint-disable-next-line
        console.log('tokenVerify End!!');
      });
    },

[결과]

idToken : 14138744xxx.....xxxsbg91fmj3.apps.googleusercontent.com

 



 

2. Back-End에서 받은 id token의 무결성 확인


위에서 구현한 Rest API를 통해서 id token을 받아왔다면, 반드시 무결성확인 절차를 거쳐야 합니다. 무결성 확인을 위해서는 아래의 값들을 검사하게 되는데,

 

  • ID Token이 Google을 통해 발행된 것이 맞는지 확인합니다.
  • ID Token의 aud 값 : 이 값은 web application의 client ID중 하나의 값과 같습니다. 이를 확인하는 이유는 Back-End 서버에 임의로 발급한 ID Token으로 정상적인 사용자의 데이터에 접근하는 것을 방지하기 위함 입니다.
  • ID Token의 iss 값 : accounts.google.com 이나 https://accounts.google.com과 같은지 확인합니다.
  • ID Token의 exp 값 : ID Token의 만료시간으로 해당 토큰이 만료되었는지를 확인합니다.

 

이런 값들의 확인작업을 수행하기 위해서 Google API Client Libraries 를 통한 개발이 가능합니다. Spring Boot에서 id token의 무결성을 확인하려면, GoogleIdTokenVerifier를 사용하면 됩니다. 그럼 세부적인 코드를 알아보도록 하겠습니다. 

 

[pom.xml 추가]

<!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client -->
<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.31.2</version>
</dependency>

이를 사용하기 위한 Library를 Maven Repository를 통해서 확인하여 pom.xml에 dependency를 추가해 줍니다. 이제 실질적인 Service 구성을 진행해 보겠습니다. 

 

[Service 구성]

	private final NetHttpTransport transport = new NetHttpTransport();
	private final JsonFactory jsonFactory = new GsonFactory();
	
	public int tokenVerify(String idToken) {
		
		System.out.println("idToken : " + clientId);
		
		GoogleIdTokenVerifier gitVerifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
				.setIssuers(Arrays.asList("https://accounts.google.com", "accounts.google.com"))
		        .setAudience(Collections.singletonList(clientId))
		        .build();
		
		GoogleIdToken git = null;
		
		try {
			git = gitVerifier.verify(idToken);
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		if (git == null) {
	        System.out.println("Google ID Token is invalid");
	    }else {
			Payload payload = git.getPayload();
			
			// Print user identifier & Get profile information from payload
			String userId = payload.getSubject();
			System.out.println("User ID: " + userId);
			String email = payload.getEmail();
			boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
			String name = (String) payload.get("name");
			String pictureUrl = (String) payload.get("picture");
			String locale = (String) payload.get("locale");
			String familyName = (String) payload.get("family_name");
			String givenName = (String) payload.get("given_name");
			
			System.out.println("email: " + email);
			System.out.println("name: " + name);
			System.out.println("locale: " + locale);
	    }
		return 0;
	}

GoogleIdTokenVerifier.verify( )를 통해서 Front-End에서 전달받은 ID Token을 parameter에 넣고 수행하면, 위에서 언급한 Google 서명, aud, iss, exp를 모두 확인한 결과를 리턴받고, 해당 결과의 PayLoad( )를 통해서 결과를 get할 수 있습니다.  

 

[결과]

User ID: 1095913456456456569372
email: ayoteralab@gmail.com (가칭입니다.)
name: AyoteraLab
locale: ko

이렇게 5 ~ 7에 대한 구현이 완료되었습니다. 이제 사용자에 대해서 application의 자체 Token 발행 및 사용자 DB등록 후 서비스제공 등에 대한 부분에 대해서 알아보겠습니다. 

 

- Ayotera Lab -

댓글