[AWS] Cognito를 사용하여 Google 로그인 구현하기

Sean park·2021년 5월 16일
1

AWS

목록 보기
1/1
post-thumbnail
post-custom-banner

웹 개발을 하다보면 한번쯤은 구현해 보게되는 기능중 하나가 바로 로그인 기능인데요. 로그인을 구현하는 방법은 여러가지가 있습니다. 이번에는 AWS에서 지원하는 Cognito를 이용하여 소셜 로그인중 Google 로그인을 내 서비스에 추가하는 방법에 대해 알아보겠습니다.

사용자 풀 생성

AWS Cognito는 User pool과 Identity pool 두 가지 pool을 지원합니다. 간단하게 살펴보도록 하겠습니다.

  • User pool : 사용자의 가입 및 로그인등 회원 관리를 할 수 있는 기능을 제공합니다. User pool을 이용하여 소셜 로그인등을 사용할 수 있습니다.
  • Identity pool : 로그인한 유저 혹은 익명의 사용자에게 다른 AWS 서비스를 사용할 수 있도록 유저에게 권한을 부여합니다.

Cognito를 이용하여 Google 로그인을 하기 위해서는 User pool이 필요하니, User pool을 사용해보도록 하겠습니다.

AWS의 Cognito 서비스에 접속하면 다음과 같은 화면을 볼 수 있습니다. 사용자 풀 관리 버튼을 클릭합니다.
버튼을 클릭하시고 다음 화면으로 이동해서 사용자 풀 생성 버튼을 클릭합니다. 그러면 아래와 같이 화면이 나오게 됩니다.
풀 이름을 설정해 주시고, 필요에 맞게 설정을 해주시면 됩니다. 저는 기본값 검토를 선택하겠습니다.
기본값 검토를 선택하면 아래와 같이 화면이 표시되는데 다른건 다 건너뛰고 앱 클라이언트 추가를 클릭 해줍니다.
앱 클라이언트는 무엇이죠? AWS에서 다음과 같다고 하네요.

앱은 사용자 풀 내에 있으며 사용자는 인증된 사용자가 없는 작업 (인증된 사용자가 없는 작업) 을 호출하는 권한이 있는 개체입니다. 예를 들어 잊어버린 암호를 등록, 로그인 및 처리하는 작업이 포함됩니다. 이러한 API 작업을 호출하려면 앱 클라이언트 ID와 클라이언트 암호 (선택 사항) 가 필요합니다. 권한이 있는 클라이언트 앱만 이러한 미인증 작업을 호출할 수 있도록 앱 클라이언트 ID 또는 암호를 보호하는 것은 사용자의 책임입니다.

앱 클라이언트는 간단히 말해 해당 User pool을 사용하는 앱, 즉 User pool을 이용하는 내 서비스 정도로 생각하면 됩니다. 나중에 설정할 로그인 redirect path, 정보를 가져올 OAuth scope 등을 앱 클라이언트 설정에서 하게 됩니다.

저는 다른 설정은 건들지 않고 앱 클라이언트 이름만 적어주고 앱 클라이언트를 생성하겠습니다. 앱 클라이언트를 생성하셨으면, 풀 설정으로 돌아가 풀 생성 버튼으로 User pool을 생성해줍니다.
User pool 생성이 완료되었다면, 왼쪽의 메뉴바에서 자격 증명 공급자를 클릭합니다.
저는 Google로 로그인을 할것이기 때문에 Google을 선택하겠습니다.
이제 Cognito가 자격 증명을 요청할 Google 프로젝의 정보를 입력해야 합니다. Google 프로젝트에서 Cognito의 redirect 정보를 입력해야 하기 때문에 Google 프로젝트도 냉큼 만들어 보겠습니다.

Google 프로젝트 생성


에...제가 이미 만들어둔 프로젝트들이 있어서 초기 화면을 보여드리기 어려울것 같습니다..(제 프로젝트는 소중하니까요..ㅎ) 구글 클라우드 플랫폼에 접속하셔서 프로젝트 만들기를 선택해주세요..프로젝트 노출 없이 프로젝트 만들기 화면에 접근하는 방법 아시면 댓글에 남겨주시면 반영하겠습니다 ㅠ

프로젝트 만들기를 선택했다면 프로젝트 이름을 입력한뒤 만들기를 클릭합니다.
프로젝트를 생성하셨으면, 왼쪽 메뉴바에서 API 및 서비스 -> 사용자 인증 정보를 클릭합니다. 그런 다음 사용자 인증 정보 만들기를 클릭한뒤 OAuth 클라이언트 ID를 선택합니다.
그런 다음 환경에 맞게 설정해주신 후 생성한 클라이언트 ID 설정으로 접속합니다.
클라이언트 설정 화면에 접속하신 뒤, 위와 같이 redirect 설정을 해주어야 합니다. 이는 Cognito가 Google 프로젝트를 통해 로그인을 할 수 있도록 인증된 URI라는 것을 알려주는 것입니다. 승인된 자바스크립트 원본에는 아래와 같은 형태로 작성해줍니다.

  • https://<my-domain>.auth.<region>.amazoncognito.com

my-domain에는 자신의 서비스 도메인을 입력하면 됩니다. 'test.com'이라는 도메인을 구입하였다고 한다면, 'test'를 입력하고 region에는 자신의 AWS region을 입력하시면 됩니다. region은 ap-northeast-2와 같이 되어있습니다.

승인된 리디렉션 URI도 동일하게 입력해줍니다. 형식은 아래와 같습니다.

  • https://<my-domain>.auth.<region>.amazoncognito.com/oauth2/idpresponse

정보를 모두 입력하고 저장하였다면, 다시 Cognito로 이동합니다.

Cognito에 Google 연동


Cognito로 돌아와 방금 만든 Google 프로젝트의 정보를 입력해줍니다. Google 프로젝트 정보는 클라이언트 ID 설정 화면(redirect 입력 화면)에서 확인할 수 있습니다. Cognito화면에 알맞게 정보를 입력해줍니다.

  • Google 앱 ID : 클라이언트 ID
  • 앱 보안 : 클라이언트 보안 비밀

인증 범위는 예시로 나와있는 profile email openid는 필수값으로 예시와 동일하게 입력해주시고 추가적으로 필요한 정보가 있다면, Google 프로젝트에서 필요한 Scope를 입력해주시면 됩니다. 각 인증 범위 값은 스페이스 한 칸 ' '으로 구분됩니다.

정보를 모두 입력했다면 Google 활성화 버튼을 클릭합니다.
이제 User pool을 이용해 자격을 증명해줄 공급자(Google)을 설정 했으니, 로그인 하여 가져올 정보를 설정하는 일만 남았네요!

앱 클라이언트 설정으로 이동해서 Cognito가 로그인 후 redirect할 콜백 URL을 입력해줍니다.
콜백 URL도 입력해주었다면, 변경 내용을 저장하고 도메인 이름을 설정해주겠습니다.
후...생각보다 복잡한듯 보이지만 한번 하고나면 쉬울거에요. 거의 다 왔으니 조금만 더 해봅시다!
도메인 이름 등록화면에서 자신의 서비스 도메인을 입력해줍니다!
이제와서 하는 이야기지만...Cognito는 도메인 없이 Local로 테스트 하는것이 불가능 합니다...공부 목적이라면 무료 도메인을 구해서 진행해주세요 (Hoxy.. Local로 하시는 방법이 있다면 댓글로 태클 씨게 박아주세요 저도 공부하게요 ㅎㅎ)

자 도메인까지 등록했으면 이제 진짜 가져올 정보만 등록해주면 끝납니다.

사용자 지정 속성 등록

저는 Google의 Access token을 가져오기 위해 사용자 지정 속성을 등록했습니다. 기본 유저 정보만 필요하신 분들은 생략해도 됩니다.

속성 탭으로 이동해서 사용자 지정 속성을 추가해줍니다.
화면과 같이 자신의 서비스에 필요한 값을 추가해줍니다.

속성 매핑


이제 왼쪽에 매뉴 다 있으니까 알아서 찾아 오세요! 원래 강하게 크는겁니다!....죄송합니다 왼쪽 사이드 바에서 속성 매핑 버튼을 클릭해주세요 ㅎ (사실 화면 캡쳐하기 귀찮아서...ㅎ)

속성 매핑 화면으로 이동했다면 위와 같이 화면이 보일거에요. 저희는 Google을 등록했으니 Google 탭을 클릭해줍시다. Google 탭으로 이동하면 Google로 부터 제공 받을수 있는 값들이 나열되어 있는데요 필요한 값을 체크해 주시고 사용자 풀 속성에서 알맞은 값을 선택해줍니다.

읭? 왜 Google 속성에는 있는데 사용자 풀 속성에는 없지? 하는 값들이 있습니다. access_token과 같은 값인데요. 사용자 풀 속성에 없는 값을은 기본 제공하는 속성이 아니기 때문에 위에 있는 '사용자 지정 속성 등록'을 참고해주세요. 사용자 지정 속성앞에 있는 custom::은 자동으로 입력되니 신경쓰지 않으셔도 좋습니다.

여기서 또 특이한 점이 있는데요. Username(구글 사용자 이름)은 반대로 사용자 풀 속성에는 있는데 Google 속성에는 보이지 않습니다. Username은 sub이라는 값으로 Cognito에서 제공하는데요. 이는 자격 증명 공급자 별로 다르기 때문에 AWS를 참고하시기 바랍니다.

참고 링크 : https://docs.aws.amazon.com/ko_kr/cognito/latest/developerguide/cognito-user-pools-specifying-attribute-mapping.html

자 속성 매핑까지 끝났다면 로그인을 시도해볼까요?

Cognito google 로그인

모든 설정이 완료되었으면 아래 경로로 접속합니다.

  • https://<my-domain>.auth.<region>.amazoncognito.com/login?response_type=token&client_id=<cognito_client_id>&redirect_uri=https://<my-domain>/

위와 같이 화면이 표시되면 잘 따라오셨습니다! 정상적으로 수행되었다면, 등록해두었던 자신의 서비스 redirect 경로에 fragment로 설정했던 속성값이 담겨오게 됩니다. 만일 로그인 화면이 나오나 위와같이 안되거나, 정상적으로 redirect되지 않을 경우 redirect URL을 잘 살펴보시기 바랍니다. 저는 대부분 redirect URL이 문제였었네요..ㅠ


지금까지 Cognito를 이용한 Google 로그인 방법에 대해 알아보았습니다. 오류가 있거나, 잘못된 내용은 남겨주시면 수정하겠습니다. 감사합니다.


보너스

이 cognito에서 주는 token값이 JWT 형태로 오게되는데 찾아보면 푸는 방법이 나오지만 삽질했던 경험이 있어 token decode 코드도 첨부합니다.

 router.post('/verifyToken', async (req, res) => {
  let idToken = req.body.token;
  const publicKeys = await axios({
    url: `https://cognito-idp.<region>.amazonaws.com/<user-pool-ID>/.well-known/jwks.json `,
    method: 'get',
    credentials: 'True',
  })
  .then(res => {
    return res.data;
  })
  .catch(err => {
    console.log(err.response.data);
  })

  if (idToken && typeof idToken === 'string') {
    const header = decodeTokenHeader(idToken);
    const jwk = getJsonWebKeyWithKID(header.kid, publicKeys.keys);
    const pem = jwkToPem(jwk);
    
    let verifiedToken = jwt.verify(idToken, pem, {algorithms: ['RS256']}, function(err, decodedToken) {
      return decodedToken;
    });
})

function decodeTokenHeader(token) {
  const [headerEncoded] = token.split('.');
  const buff = new Buffer(headerEncoded, 'base64');
  const text = buff.toString('ascii');
  return JSON.parse(text);
}

function getJsonWebKeyWithKID(kid, jsonWebKeys) {
  for (let jwk of jsonWebKeys) {
      if (jwk.kid === kid) {
          return jwk;
      }
  }
  return null;
}
profile
제 코드가 세상에 보탬이 되면 좋겠습니다.
post-custom-banner

0개의 댓글