시작하며
자체 로그인에 비해 간편하고 책임이 덜하며, 좋은 UX도 지닌 OAuth는 최근 소프트웨어 생태계에서 많이 사랑 받고 있는데요! 이를 활용하면 간편하게 회원가입 기능을 만들 수 있을 뿐더러 일부 정보를 제공 받아 온보딩 스탭을 건너뛴다던가, 약관 동의도 원클릭으로 편리하게 진행할 수 있죠.
다만, 실무에서 사용하다 보면 OAuth 제공자별로 각각의 구현 방식 및 제공해주는 API 기능들이 천차만별이라 OAuth 의존적인 로그인 로직을 만들다보면 여러 문제가 발생할 수 있습니다. 따라 OAuth를 새로 도입한다면 도입 전에 신중하게 고려해야 하지만 직접 연동해보기 전까진 이 OAuth가 우리 서비스에 맞는 지 알 턱이 없죠.
이 글에서는 특히 네이버 OAuth를 도입할 경우 생길 수 있는 매우 디테일한, 뚜껑 열기 전까지는 모를 수 있는 문제상황들을 나열합니다.
로그인
개인정보 필수 동의를 하더라도 정보가 비어있을 수 있음
온보딩 플로우 간소화를 위해서 필요한 정보를 필수 동의 항목으로 넣는 경우가 많습니다. 다만, 네이버 계정 자체에 해당 정보가 기입되지 않았을 경우 동의해도 빈 값이 올 수 있습니다.
휴대전화번호 등 가입 시 당연히 받을 것으로 예측되는 정보들도 비어있는 경우가 꽤 많습니다. (전화번호 기준 대략 1000개의 계정 중 4~5개 내외로 파악됩니다.) 따라 네이버를 통해 제공받는 모든 정보는 비어있을 수 있음을 가정하고 별도의 온보딩 플로우를 제작해야 합니다.
API 호출을 위해 접근 토큰 관리 필요
네이버는 명시적으로 유저가 로그인 버튼을 눌러서, naver 로그인을 수행한 경우 해당 유저에 대한 정보 조회 api등을 호출 할 수 있는 인증 정보가 담긴 access_token과 access_token을 재발급 받을 수 있는 refresh_token을 줍니다.
이 토큰들이 있어야 해당 유저의 회원 정보 조회, 약관 동의 내역 조회 등을 호출할 수 있습니다.
문제는 이 refresh_token의 만료 기한이 1년이라는 건데, 1년이 지나기 전에 명시적으로 갱신을 시키거나, 재취득하지 못한다면 naver api를 사용할 수가 없습니다.
다행히 갱신 시를 기점으로 refresh_token의 유효기간이 연장되기 때문에, 한번 취득한 refresh_token을 재 때 갱신만 시켜준다면 무한 갱신은 가능합니다.
따라 아래 3가지 중 하나의 전략을 선택해야 합니다.
최초 로그인 시 제외하고 naver api를 사용하지 않기 (token 자체를 쓸 일 없게 설계)
보통의 로그인대행은 oauth provider에게 unique_id 취득 정도만 하고 이를 트리거로 자체 jwt를 발행합니다. 이 이상의 서비스(약관동의 대행, 회원 탈퇴 시 oauth 채널 연결 끊기 등)를 사용하지 않는다면 토큰 관리를 하지 않아도 됩니다.
서버에서 refresh_token의 만료 기한을 보유하고 있고, 1년이 다되어가는 토큰들을 스케줄러를 통해 갱신 시키기
특정 주기로 데이터베이스 내의 토큰들을 스캔하여 만료가 임박한 토큰들은 재발급 요청을 보내는 방식입니다. 다만 로직 상 각각 refresh api를 호출해야 하여 조금 무거워질 수 있습니다.
refresh_token이 만료된 경우 강제로 재로그인 시켜 버리기
만약 naver api를 사용해야하는 시점에서 토큰이 만료됐을 경우 유저를 로그아웃 시키고, 다시 네이버 로그인 버튼을 누르게 해 refresh_token을 재취득 하는 방법입니다. 다만 ux적으로 굉장히 이상한 그림이 나옵니다. 가령 회원탈퇴를 눌렀는데 refresh_token이 만료된 경우 탈퇴는 안되고 로그아웃이 되버립니다. 유저는 재로그인 한 후 탈퇴를 다시 눌러야 정상 탈퇴됩니다.
약관동의대행
네이버 유저의 약관 동의를 직접 해줄 수 없음
naver 약관동의대행은 말그대로 대행입니다. 약관에 관련된 전적인 요소를 네이버에서 책임지고 대신 행해준다는 것이고, 반대로 말하면 네이버 유저에 대해서는 자체 서비스가 지닌 약관 동의에 대한 책임을 네이버에 위임하여 잃게 됩니다.
이러한 상황이 왜 일어나는 지 좀 더 구체적으로 말씀드리자면,
만약 이렇게 자체적 약관 동의 체계를 가지고 있다면, 유저의 약관동의에 대한 정보가 이미 수집되어 쌓여있거나, 서비스 내에서 약관을 재동의하는 플로우가 존재할 것 입니다. 이 때 만약 유저가 마케팅 수신 정보를 비동의 했다고 했을 때, 네이버 측에서 관리하는, 네이버 로그인 시 유저가 동의한 약관 내용을 직접 동기화 할 수 없습니다.
네이버 로그인을 하면 위와 같이 약관 동의 입력이 뜰 테고, 유저의 접근 토큰을 활용해 약관 조회를 할 경우 아래와 같은 응답을 받을 수 있습니다.
{
"result": "success",
"accessToken": "{input accessToken}",
"agreementInfos": [
{
"termCode": "{TERMCODE}",
"clientId": "{CLIENTID}",
"agreeDate": "HH:MI:SS.sss AM MM/DD/YYYY"
},
{
"termCode": "서비스 이용 약관",
"clientId": "{CLIENTID}",
"agreeDate": "HH:MI:SS.sss PM MM/DD/YYYY"
}
] // 동의 하지 않은 항목은 오지 않음
}
이 값을 기반으로 서비스 내부에서 관리 중인 유저별 약관 동의 db에 동기화를 함으로써 약관동의 대행이 이루어 질 것입니다. 다만 이때, 유저가 다른 채널을 통해 약관을 동의 했을 경우 네이버 측에 전달해 동의를 했음을 알릴 방법이 존재하지 않습니다.
결국 두 선택지가 남게 되는데 각각 단점이 존재합니다.
네이버 로그인한 유저의 경우 다른 채널 없이 무조건 네이버를 통해야만 약관을 동의할 수 있게 설계한다.
이렇게 할 경우 oauth 다연결 정책은 사용할 수 없습니다. 한 계정에 여러 인증 채널이 들어가게 되면 로그인이 네이버를 통하지 않더라도 될 것이고, 네이버를 통한 약관 동의를 플로우적으로 담보하기 힘들기 때문이죠. 또한 서비스 내부에서 약관 관리 로직을 넣는 경우 굉장히 세심히 설계 해야 합니다. 약관이 변경되어 재동의가 필요할 때, 네이버 로그인 유저에 한해서는 서비스 자체적인 약관 재동의 플로우 대신 네이버 재로그인을 통해서 약관을 받을 수 있게 연결되도록 설계해야 합니다. 다만, 네이버는 약관이 변동되어도 재로그인 시 동의 창을 다시 띄워주지 않아서 이를 식별하고 강제로 띄우게 하는 설계가 필요합니다. (이 문제는 본문의 다른 헤더에서 자세히 다룹니다.)
네이버 약관 동의는 오직 동의를 추가적으로 받는 보조 창구로 쓴다.
말 그대로 네이버 측에서는 동의한 약관만 받아서 서비스에 반영하는 방식입니다. 네이버 로그인 시 동의하지 않아도, 동의하지 않았다는 것을 반영하진 않습니다. 잠재된 문제가 엄청 많이 생길 수 있어 추천하진 않습니다. 가령
- 사용자가 서비스에서 약관에 동의했지만, 네이버에서 다시 약관 동의 팝업이 뜨면서 동의를 해제하는 경우, 법적으로 사용자 동의 상태가 불분명 해짐.
- 네이버 약관 동의를 참고하지 않는다면, 서비스 내부 약관 동의 기록과 네이버 동의 기록이 다를 수 있음.
- 개인정보 처리 방침 변경 시 네이버에서 동의 해제했더라도 서비스에서는 반영되지 않으면 문제가 됨
동의 항목이 바뀌어도 자동으로 재동의 창이 뜨지 않음
2025.03.06 기준으로 달라질 수 있습니다.
기존에 로그인을 한 유저가 다시 로그인을 했을 때, 약관 동의 항목이 달라진 경우에 한해, 동의 창이 자동으로 뜨지 않고 바로 넘어갑니다. (개인정보 제공이 바뀐 건 다시 뜹니다)
상식적으로는 동의 항목이 바뀌면 정보동의 창이 재노출 되는 게 맞는 것 같습니다만, 약관동의대행에 한해서는 다시 트리거 해주지 않더라고요.
따라서 해당 동의항목 창을 강제로 트리거 해서 띄울 필요가 있는데
auth_type 을 ‘reprompt’로 로그인 api를 재호출한 경우 인증요청을 다시 받을 수 있습니다. 서버에서 약관 동의 변동 사항이 존재하고, 접속한 유저가 동의하지 않은 경우 해당 페이지로 강제 리다이렉트 시키는 식으로 해서 동의를 받을 수 있습니다.