제3의 서비스에 계정 관리를 맡기는 방식.
교재에서는 권한 부여 코드 승인 타입으로 리소스 오너 정보를 취득한다.
교재의 그림과 설명이 묘하게 맞지 않아 이해하기 힘들었다. 결국 구글링에 들어갔다.

(이미지 출처 : https://itwiki.kr/w/OAuth)
\token POST 요청을 보낸다구글 클라우드 콘솔을 통해 구글 로그인 기능을 사용해본다.

동의 과정을 마치고 사용자 인증 정보 관리 등 필요한 내용을 체크하고 작성하다보면 OAuth 클라이언트를 생성할 수 있다.
클라이언트 id와 클라이언트 보안 비밀번호를 가지고 구현해보자.
의존성을 추가하고, 가장 먼저 쿠키 관리 클래스를 생성한다.
쿠키 추가, 쿠키 삭제, 직렬화, 역직렬화 메서드를 구현한다.
참고 : https://www.inflearn.com/questions/67208/serialize-desserialize%EC%9D%98-%EB%9C%BB
자바에서의 직렬화 : https://velog.io/@whitebear/자바-직렬화-확실히-알고-가기
교재를 따라 진행하다보니 아래와 같은 코드가 많이 보인다.
User user = userRepository.findByEmail(email)
.map(entity -> entity.update(name))
.orElse(User.builder()
.email(email)
.nickname(name)
.build());
이 코드는 Java의 Optional을 활용한 것으로(map, orElse 등) 정확히 이해하는 데 어려움을 겪고 있어 관련 학습을 한 뒤에 다시 진행하기로 했다.
학습 완료!
위 코드는 userRepository에서 findVyEmail()을 실행 후(Optional<User> 반환), 값이 있으면 entity(User)를 업데이트, 값이 null일 때는 User.build()를 실행해 유저를 생성하는 코드다. 강의를 듣고 보니 이해가 된다!
당연히 한 번에 이해하려는 생각은 없었고, 어떻게 동작하는지 맛보기로 휘리릭 볼 생각이었는데 신경쓸게 정말 많다. 책으로는 확실히 한정된 정보만 보게되니까 앞뒤 맥락을 이해하려 소비되는 시간도 많다. 기본적으로 방대한 내용이라는 건 알고 있었지만, 직접 타이핑해보니 바로 이해가 되지는 않는다. 그림으로 정리해보는 것도 나쁘지 않을 것 같다.
리프레시 토큰을 만들어 사용하고 있으므로 정상적인 흐름이라면 /api/token API를 호출해 새 액세스 토큰을 발급받아야한다.
그런데 의도적으로 액세스토큰을 삭제했을 때, API가 호출되지 않았다. 인증 실패 전에 인증 단계에서 재발급을 하려면 어떻게 해야할까?
백엔드단에서 삽질을 하다가 js 파일을 살펴보니... 여기서 해결해야겠다는 결론이 났다.
// HTTP 요청을 보내는 함수
function httpRequest(method, url, body, success, fail) {
fetch(url, {
method: method,
headers: { // 로컬 스토리지에서 엑세스 토큰 값을 가져와 헤더에 추가
Authorization: 'Bearer' + localStorage.getItem('access_token'),
'Content-Type': 'application/json',
},
body: body,
}).then((response) => {
if(response.status === 200 || response.status === 201) {
return success();
}
const refresh_token = getCookie('refresh_token');
if(response.status === 401 && refresh_token) {
fetch('/api/token', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + localStorage.getItem('access_token'),
'Content-Type': 'application/json',
},
body: JSON.stringify({
refreshToken: getCookie('refresh_token'),
}),
})
.then((res) => {
if(res.ok) {
return res.json();
}
})
.then((result) => { // 재발급이 성공하면 로컬 스토리지값을 새로운 액세스 토큰으로 교체
localStorage.setItem('access_token', result.accessToken);
httpRequest(method, url, body, success, fail);
})
.catch(error => fail());
} else {
return fail();
}
});
}
기존에 작성해둔 코드에 이미 401에러가 났을 때 /api/token을 호출하는 로직이 있었다!
따라치면서 잘 이해하지 못했던 게 화근이다. 이걸로 몇시간을 고민했다.
근데 왜 작동을 하지 않은거지? 리프레시 토큰도 제대로 있는데?
console.log()를 찍어보니...

찾을 수 없다. 설마설마... getCookie 함수를 다시 살펴봤다.
// 쿠키를 가져오는 함수
function getCookie(key) {
var result = null;
var cookie = document.cookie.split(";");
cookie.some(function(item) {
item = item.replace(" ", "");
var dic = item.split("=");
if(key === dic[0]) {
result = dic[1];
return true;
}
});
}
그렇다. result를 return해주지 않고 있었다. 이런 바보같은 실수는 언제쯤 안하려는지!
당연하게도 return값을 추가해주니 정상적으로 액세스 토큰을 발급받았다.
문제 해결!😂