애플로그인 구현 중 삽질한 EU

controlZ·2023년 8월 2일
2
post-thumbnail

삽질 계기

웹뷰 형태의 앱 👉🏻 플러터 앱으로 변경하는 과정에서 애플 로그인 로직이 변경되어야 한다는 결론에 도달하게되었고, 로직을 변경하는 과정에서 여러 삽질을 하게 되었ㄷㅏ..

애플 로그인 구현 과정

애플 로그인 구현에 있어서 아주 무책임하고 간단하게만 말해본다면 다음의 과정이 필요하다.

  1. Apple Developer 사이트에서 애플 로그인 관련 설정 및 키 값 발급
  2. 애플 로그인 로직 작성

애플 공식 문서를 보며 생각해본 플로우는 다음과 같았다.

이 중 내가 구현해야할 부분은 API-server 부분으로, 먼저 apple에 authorization code가 valid한지 요청을 보내야했다.

공식 문서를 찬찬히 살펴보면 authorization code를 검증하기 위해서 apple에 보내야 할 데이터 파라미터는 다음과 같다고 나온다.

  1. client_id
  2. client_secret
  3. code
  4. grant_type
  5. redirect_uri

1) client_id
apple developer 사이트 > 계정 > 프로그램 리소스 > 인증서, 식별자 및 프로파일(Certificates, Identifiers & Profiles) > 식별자(Identifiers) 탭에 있는 Bundle ID가 client_id이다.

2) client_secret
사실 이 부분에서 좀 많이 헤메긴 했다.(사실 애플 로그인을 주제로 글을 작성한 이유도 다른 분들은 저처럼 헤매지 마시라고..) 암튼 client_secret의 경우 애플이 요구하는 형식에 맞춰 개발자가 만들어야한다. 아래처럼(지금보면 꽤나 친절했던건가) 잘 나와있다.

Create the client secret
JSON Web Token (JWT) is an open-standard (RFC 7519) that defines a way to transmit information securely. Sign in with Apple requires JWTs to authorize each validation request. Create the token, then sign it with the private key you downloaded from Apple Developer.

{
    "alg": "ES256",
    "kid": "ABC123DEFG"
}
{
    "iss": "DEF123GHIJ",
    "iat": 1437179036,
    "exp": 1493298100,
    "aud": "https://appleid.apple.com",
    "sub": "com.mytest.app"
}

나같은 경우 nestjs로 작업을 했기 때문에 user-auth.service.ts 파일에 client_secret을 만드는 메서드를 만들어두었다.

여기서 잠깐 !

  • APPLE_KEY_ID는 인증서, 식별자 및 프로파일(Certificates, Identifiers & Profiles) 콘솔의 Keys 탭에 들어가면 있는 Key ID 값을 사용하면 된다.
  • APPLE_CLIENT_ID의 경우 위에서 말한대로 Bundle ID에 해당하며,
  • APPLE_TEAM_ID는 인증서, 식별자 및 프로파일(Certificates, Identifiers & Profiles) 콘솔의 오른쪽 상단 or 인증서, 식별자 및 프로파일(Certificates, Identifiers & Profiles) > 식별자(Identifiers) 탭에 있는 App ID Prefix에 해당한다.
  • p8파일은 처음에 Keys 탭에서 키 값 셋팅할 때 다운로드 가능하다. 처음인가 두번째까지만 다운로드 가능하고 그 뒤로는 다운 못 받으니깐 처음에 저장해서 잘 가지고 있어야한다.

암튼 다시 또 본론으로 돌아가서

3) code
앱에서 보내주는 우리가 애플 서버로 보내서 검증할 authorizaiton code이다.

4) grant_type
우린 authorization code를 검증할거니깐 grant_type은 authorization_code라고 하면된다.

5) redirect_uri
사실 얘 때문에도 시간을 많이 잡아먹었는데, 웹뷰 형태의 앱이었다면 redirect_uri가 있기에 apple developer에서 등록해주고, 등록된 redirecr uri 값을 함께 보내줘야했겠지만 플러터로 만든 앱이기 때문에 redirect uri 그런 개념이 없다. 그래서 따로 등록해줄 필요도 authorization code를 verify할 때 보낼 필요도 없다.

이제보니 애플에서 나름 네모박스로 표시해가면서 강조(?)하고 있었네...

암튼 위의 과정을 거쳐 어떤 형태의 데이터를 보내야하는지 살펴보긴 했다.

그럼 마지막, 'nestjs에서 어떤식으로 요청 보낼건데?'

아래 코드처럼 nestjs의 httpService를 사용해서 form data형식의 데이터를 보내고자 하였다.

처음엔 FormData()를 사용했는데 계속 에러가 났다. 오랜 삽질 끝에 FormData() 대신 URLSearchParams()를 사용하니깐 에러가 사라졌다 ㄲ ㅑ 악 !!

마지막으로 삽질 요인을 정리해보자면 👀

  1. client_secret 셋팅
  2. redirect_uri 처리
  3. nestjs에서 httpService를 사용한 form-data 처리

이렇게 정리해볼 수 있을 것 같다.

결론 : 다른 사람들은 나처럼 오래 헤매이지 않았으면 좋겠다 🥲

읽으시면서 '잘못된 것 같은데?' or '이건 보완되면 좋을 것 같다' 하시는 내용은 언제든지 댓글 남겨주시면 감사하겠습니다아

2개의 댓글

comment-user-thumbnail
2024년 1월 30일

안녕하세요! 혹시 FLUTTER_APPLE_CLIENT_ID는 정확히 어떤 데이터인지 여쭤봐도 될까요?

1개의 답글