세션 저장, Spring Security 코드가 난무한 클론코딩 글들이 너무 많아 그냥 내가 쓰는 글이다...
GCP 설정 후
"http://accounts.google.com/o/oauth2/v2/auth" 엔드포인트로 client_id, redirect_uri, response_type, scope 4개의 필수 파라미터와 함께 GET 요청을 보내야 승인 매개변수(code)를 받아 올 수 있다.
scope 이리저리 만져보니 GCP에서 따로 승인 허가를 하지 않으면 '액세스 거부됨'하고 진행이 막히게 된다. 기본 예제에선 email과 profile로 작성한다고 한다.
파라미터 작업이 완성된 URL은 다음과 같다. 나는 이 부분은 프론트에서 작업할 거라 따로 구현하지 않았다.
"https://accounts.google.com/o/oauth2/v2/auth\
?client_id=(클라이언트 아이디) \
&redirect_uri=http://localhost:8080/api/oauth2/callback/google \
&response_type=code \
&scope=profile";
서버를 가동시키고 위 URL에 접속하면 계정 선택 페이지가 나오게 되는데
계정 선택을 하면 아까 설정한 "승인된 리디렉션 URI" (http://localhost:8080/api/oauth2/callback/google)로 리디렉션 된다.
프로젝트에 GET 매핑하지 않았다면 404 에러가 발생하니 얼른 구현하시길!
이때 code가 파라미터로 전해진다. 일단은 간단하게 매핑해주었다.
//...RequestMapping("/api/oauth2/")...
@GetMapping("callback/google")
public ResponseEntity<String> successGoogleLogin(@RequestParam("code") String accessCode){
return oAuthService.getGoogleAccessToken(accessCode);
}
참고로 GCP의 리디렉션 URI와 Application의 URI가 정확하게 일치해야 오류가 나지 않는다. Bad Request: redirect_uri_mismatch 오류가 난다면 이 부분을 확인하자.
access_token을 발급받으려면 "http://oauth2.googleapis.com/token" 엔드포인트에 client_id, client_secret, code, grant_type, redirect_uri 5개의 필수 파라미터와 POST 요청을 보내야 한다. 나는 post를 못보고 get으로 계속 보내면서 삽질했다.
@Service
@RequiredArgsConstructor
public class OAuthService {
private final String GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
@Value("${oauth2.google.client-id}")
private String GOOGLE_CLIENT_ID;
@Value("${oauth2.google.client-secret}")
private String GOOGLE_CLIENT_SECRET;
@Value("${oauth2.google.redirect-uri}")
private String LOGIN_REDIRECT_URL;
@Autowired
private final MemberRepository memberRepository;
public ResponseEntity<String> getGoogleAccessToken(String accessCode) {
RestTemplate restTemplate=new RestTemplate();
Map<String, String> params = new HashMap<>();
params.put("code", accessCode);
params.put("client_id", GOOGLE_CLIENT_ID);
params.put("client_secret", GOOGLE_CLIENT_SECRET);
params.put("redirect_uri", LOGIN_REDIRECT_URL);
params.put("grant_type", "authorization_code");
ResponseEntity<String> responseEntity=restTemplate.postForEntity(GOOGLE_TOKEN_URL, params,String.class);
if(responseEntity.getStatusCode() == HttpStatus.OK){
return responseEntity;
}
return null;
}
}
받아온 code를 사용해 POST 요청을 보내는 기능이다. 이때도 redirect_uri는 아까 설정한 "승인된 리디렉션 URI"이다. grant_type은 기본값이면서 왜 써야하는지 모르겠다.
다시 서버를 구동시켜 위 작업을 처음부터 다시 해보자.
정상적으로 access_token이 발급된 것을 확인할 수 있다!!
근데 어피치가 보고 있는 저 부분, 'id_token'이 뭘까?
여기까지 흐름은
ID 토큰 payload
바로 정체는..
계정의 정보가 담겨있는 JWT 토큰이다. RS256으로 암호화되어 있으니 프로젝트에서 디코딩 해서 사용하면 된다. 'sub'이 Google Open Authentication에서 제공하는 계정 유일 ID 이다! 그 외에도 이름, 사진, 이메일 등 기본 정보를 얻을 수 있다.
이 프로젝트에선 Google 액세스 토큰을 사용하지 않을 거지만 유저 정보를 알기 위해 이 작업을 했다. 디코딩해서 DB 저장하는 건 다음 시간에 ∠( ᐛ 」∠)_
백 개의 블로그보다 한 개의 공식 문서 최고!
'Project > 모면' 카테고리의 다른 글
[Spring Boot] 면접 질문 카테고리 분류하기 (0) | 2023.04.01 |
---|---|
도망친 곳엔 낙원은 없다 (0) | 2023.03.29 |
[Flutter / Dart] Flutter로 REST API 호출하기 (0) | 2023.03.26 |
[Dart] dart 기본 | 자료형, JSON, stream (0) | 2023.03.25 |
[UI/UX] 디자인 레퍼런스 사이트 (0) | 2023.03.21 |