-
Notifications
You must be signed in to change notification settings - Fork 0
[BE] 애플 로그인 구현 과정
- 암호화와 복호화를 위해 사용하는 키가 다르다.
-
smile
을key1
이라는 키로 암호화 했다면, 복호화 할 때에는key1
을 사용할 수 없다.key2
라는 키로 복호화 해야 한다. - 애플 측은 본인들의 비밀키로 암호화 한
IdentityToken
을 넘겨준다. - API 서버는 애플 측에 실시간으로 변하는 공개 키를 요청해서
IdentityToken
을 복호화한다.
-
클라이언트는 앱에서 애플 서버에 로그인 요청 전송
-
요청 결과로 credential을 받는다
cridential에는 5가지 값이 들어있다
- user identifier
- full name
- authorization code
- identity token
-
이 중 identity token을 API 서버에 보낸다.
identity token은 발급 후 10분 뒤에 만료된다.
-
API 서버는 apple 서버에 요청을 보내 공개 키 3개에 대한 정보를 담은 배열을 받아온다.
-
identity token의 헤더는 base64로 암호화되어있으므로 헤더를 복호화 한다.
-
복호화 한 헤더의
kid-alg
쌍을 4번에서 받아온 3개 키들의kid-alg
쌍과 비교한다.kid-alg
쌍이 일치하는 키를 이용해 복호화에 사용할 공개키를 만든다. -
공개 키는 apple이 제공한 key의
n
과e
를 이용하여 만든다. -
만든 공개키로 identity token을 복호화 한다.
-
복호화 한 토큰의 payload에 들어있는 정보를 확인한다.
- 발행인이 apple이 맞는지
- client id가 애플 개발자 계정에서 설정한 것과 일치하는지
- 만료되지 않았는지 (만료 여부는 jwt 모듈로 디코딩 시 자동확인)
위 3가지 요소를 통과해야 한다.
payload의 sub 값은 사용자마다 고유한 값이다. (우리 서비스에서
resource_id
로 이용하게 될 것이다.) -
얻은 sub 값에 해당하는
resourc_id
가 존재하는지 DB를 검색한다.있으면 사용자 정보를 받아오고, 없으면 사용자를 생성하여 정보를 받아온다.
-
사용자
id
(우리 서비스 자체 uuid)를 넣은access token
과refresh token
을 반환한다.
-
클라이언트 측에서는 Apple 서버에 로그인 요청을 보내고, 그 결과로 받은 idToken과 authorizationCode를 요청 body에 담아 보낸다.
탈퇴를 하려는데 로그인 요청을 다시 보내는 이유
-
탈퇴를 하려면 refresh token이나 access token 중 하나가 필요하다.
-
이 두 토큰은 로그인 시 제공되는 identity token , authorization code 내의 정보를 알아야만 요청이 가능하다. 그리고 두 토큰의 유효기간은 굉장히 짧다. (10분, 5분)
왜 회원가입 때 미리 받아두지 않았냐 → 유효기간이 짧기 때문…
-
-
로그인 상태를 확인한다. (가드)
-
가드에서 추출한
access token
에 담겨있던id
를 받아온다. -
id
를 이용해 유저의resoure_id
를 추출한다. -
idToken
을 verify한다. (로그인 로직의 4 - 9번 과정) -
id
를 이용해 추출한resource_id
와idToken
의sub
을 비교한다.sub
은identity token
내의 회원 고유 불변값이라 가입 시sub
값을resource_id
로 저장하기 때문이다. -
애플에 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'
를 설정하지 않으면 동작하지 않는다!!!!!!!! -
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로 서명하면 된다. -
access token과 refresh token을 성공적으로 받았다면 revoke (탈퇴)를 요청해야 한다. 요청하기 위해서는 client id, client secret, access token과 refresh token 중 하나가 필요하다. 앞서 얻은 값들로 body를 구성하여 요청을 보낸다.
요청을 보낼 때 주의할 점이 있는데, 요청 헤더에
'Content-Type': 'application/x-www-form-urlencoded'
를 설정하지 않으면 동작하지 않는다!!!!!!!!200 응답이 오면 드디어 성공이다.