Skip to content

[BE] 애플 로그인 구현 과정

Jeongmin edited this page Dec 14, 2023 · 5 revisions

비대칭 키 암호화

  • 암호화와 복호화를 위해 사용하는 키가 다르다.
  • smilekey1이라는 키로 암호화 했다면, 복호화 할 때에는 key1을 사용할 수 없다. key2라는 키로 복호화 해야 한다.
  • 애플 측은 본인들의 비밀키로 암호화 한 IdentityToken을 넘겨준다.
  • API 서버는 애플 측에 실시간으로 변하는 공개 키를 요청해서 IdentityToken을 복호화한다.

Apple Login 로직

traveline 로그인 로직

  1. 클라이언트는 앱에서 애플 서버에 로그인 요청 전송

  2. 요청 결과로 credential을 받는다

    cridential에는 5가지 값이 들어있다

    • user identifier
    • full name
    • email
    • authorization code
    • identity token
  3. 이 중 identity token을 API 서버에 보낸다.

    identity token은 발급 후 10분 뒤에 만료된다.

  4. API 서버는 apple 서버에 요청을 보내 공개 키 3개에 대한 정보를 담은 배열을 받아온다.

    GET https://appleid.apple.com/auth/keys

    image

  5. identity token의 헤더는 base64로 암호화되어있으므로 헤더를 복호화 한다.

  6. 복호화 한 헤더의 kid-alg 쌍을 4번에서 받아온 3개 키들의 kid-alg쌍과 비교한다.

    kid-alg쌍이 일치하는 키를 이용해 복호화에 사용할 공개키를 만든다.

  7. 공개 키는 apple이 제공한 key의 ne를 이용하여 만든다.

  8. 만든 공개키로 identity token을 복호화 한다.

  9. 복호화 한 토큰의 payload에 들어있는 정보를 확인한다.

    • 발행인이 apple이 맞는지
    • client id가 애플 개발자 계정에서 설정한 것과 일치하는지
    • 만료되지 않았는지 (만료 여부는 jwt 모듈로 디코딩 시 자동확인)

    위 3가지 요소를 통과해야 한다.

    payload의 sub 값은 사용자마다 고유한 값이다. (우리 서비스에서 resource_id로 이용하게 될 것이다.)

  10. 얻은 sub 값에 해당하는 resourc_id가 존재하는지 DB를 검색한다.

    있으면 사용자 정보를 받아오고, 없으면 사용자를 생성하여 정보를 받아온다.

  11. 사용자 id (우리 서비스 자체 uuid)를 넣은 access tokenrefresh token을 반환한다.

Apple Revoke 로직

traveline 탈퇴 로직

  1. 클라이언트 측에서는 Apple 서버에 로그인 요청을 보내고, 그 결과로 받은 idToken과 authorizationCode를 요청 body에 담아 보낸다.

    탈퇴를 하려는데 로그인 요청을 다시 보내는 이유

    • 탈퇴를 하려면 refresh token이나 access token 중 하나가 필요하다.

    • 이 두 토큰은 로그인 시 제공되는 identity token , authorization code 내의 정보를 알아야만 요청이 가능하다. 그리고 두 토큰의 유효기간은 굉장히 짧다. (10분, 5분)

      왜 회원가입 때 미리 받아두지 않았냐 → 유효기간이 짧기 때문…

  2. 로그인 상태를 확인한다. (가드)

  3. 가드에서 추출한 access token에 담겨있던 id를 받아온다.

  4. id를 이용해 유저의 resoure_id를 추출한다.

  5. idToken을 verify한다. (로그인 로직의 4 - 9번 과정)

  6. id를 이용해 추출한 resource_ididTokensub을 비교한다.

    subidentity token내의 회원 고유 불변값이라 가입 시 sub 값을 resource_id로 저장하기 때문이다.

  7. 애플에 access token과 refresh token을 요청한다. (revoke 요청에 필요하기 때문)

    요청하기 위해서는 authorization code, client id, client secret이 필요하다. client id는 identity token을 decode 하면 얻을 수 있고, client secret은 내가 직접 만들어야 한다.

    요청을 보낼 때 주의할 점이 있는데, 요청 헤더에 'Content-Type': 'application/x-www-form-urlencoded'를 설정하지 않으면 동작하지 않는다!!!!!!!!

  8. client secret을 만든다.

    client secret은 client id를 이용해서 만들고, 이 외에 apple team id, apple key id, p8 key가 필요하다.

    const payload = {
      iss: process.env.TEAM_ID,
      iat,
      exp,
      aud: 'https://appleid.apple.com',
      sub: clientId,
    }; 

    payload를 위와 같이 구성하되, 유효기간은 30일을 넘으면 안된다. (왜인지는 모르지만 오류가 난다고 한다.) iat과 exp는 각각 발행일자와 만료일자이다.

    header의 alg 값은 ES256으로, kid는 apple key id로 설정한 뒤 p8 key로 서명하면 된다.

  9. access token과 refresh token을 성공적으로 받았다면 revoke (탈퇴)를 요청해야 한다. 요청하기 위해서는 client id, client secret, access token과 refresh token 중 하나가 필요하다. 앞서 얻은 값들로 body를 구성하여 요청을 보낸다.

    요청을 보낼 때 주의할 점이 있는데, 요청 헤더에 'Content-Type': 'application/x-www-form-urlencoded'를 설정하지 않으면 동작하지 않는다!!!!!!!!

    200 응답이 오면 드디어 성공이다.

Clone this wiki locally