소셜 로그인 마지막인 구글 로그인.
https://cloud.google.com/identity-platform/docs/use-rest-api?hl=ko
먼저, 프로젝트를 생성한다.
그리고 OAuth 동의 화면을 찾아 이동!
User Type은 외부로 선택.
네이버에서는 검수 요청을 안 하면 내 계정만 됐는데, 그 부분을 해결할 수 있을 것 같다.
그런데 OAuth 동의 화면(첫 번쨰 화면) 에서 계속 뭔가 오류가 있어서 넘어가지지가 않았다..
찾아봤는데 딱히 해결 방법이 안 나오는...
그래서 그냥 다른 계정으로 다시 프로젝트 만들었더니 됐다.
대체 왜지?.... 이유는 아직도 모른다..^^
다음으로 사용자에게 정보를 받을 범위를 추가한다.
나는 이메일만 받아오면 돼서 2개만 체크했다.
세 번째에서는 로그인 가능한 사용자 이메일 추가.
정말 실제로 사용하는 것처럼 누구나 로그인하게 하려면 네이버처럼 따로 요청해야 한다.
그래도 100개까지는 추가 가능하니까 공부 단계에서는 만족!
앱 게시까지 하면 동의 부분은 끝.
이제 익숙한 과정.
사용자 ID를 발급받아야 한다.
클라이언트 ID와 클라이언트 보안 비밀번호를 발급받았으면 기본 설정은 끝!
여기까지 오는 게.. 굉장히 험난했던 것 같은.....
가장 먼저 할 것은 역시나 버튼 이미지 다운 받기
구글은 로고 사용이 카카오나 네이버보다 더 까다로운 것 같다.
변형하려면 꼭 가이드 참고하기.
https://developers.google.com/identity/branding-guidelines?hl=ko
1. 인가 코드 받아오기
컴포넌트 만들고 redirec할 주소를 연결한다.
{
path: '/google-login',
name: 'google',
component: () => import('@/components/GoogleLogin.vue')
},
googleLogin() {
const url = 'https://accounts.google.com/o/oauth2/v2/auth';
location.href = `${url}?client_id=${this.googleLoginParams.client_id}&redirect_uri=${this.googleLoginParams.redirect_uri}&response_type=${this.googleLoginParams.response_type}`;
},
넘겨줘야 할 param들은 data에 정의해두고 가져와서 연결했다.
googleLoginParams: {
client_id: process.env.VUE_APP_GOOGLE_CLIENT_ID,
redirect_uri: process.env.VUE_APP_GOOGLE_REDIRECT_URI,
response_type: 'code',
scope: 'email',
}
- client_id: 구글에서 발급받은 client ID
- redirect_uri: 구글에서 설정한 Redirect URI
- response_type: 'code'로 고정
- scope: 받아올 내용
카카오에서는 scope를 넘겨주지 않아도 알아서 동의한 값만 받아올 수 있었는데, 구글은 꼭 넘겨주어야 한다.
2. 토큰 받아오기
조금 전에 받아온 인가 코드를 활용해서 post 요청을 보낸다.
인가코드를 post요청으로 서버에 넘기고, 서버에서 다시 post으로 토큰 받아온 후 클라이언트에 반환.
이번에도 data에 정의해두고 매개변수를 넘겼다.(URL에 붙여서)
tokenParams: {
client_id: process.env.VUE_APP_GOOGLE_CLIENT_ID,
client_secret: process.env.VUE_APP_GOOGLE_CLIENT_SECRET_PW,
code: this.$route.query.code,
grant_type : 'authorization_code',
redirect_uri: 'http://localhost:8080/google-login',
},
...
await axios.post(this.$store.state.url+'googlelogin', new URLSearchParams(this.tokenParams).toString())
.then(response => {
console.log(response);
// this.token.access_token = response.data.result.access_token;
// this.token.refresh_token = response.data.result.refresh_token;
})
.catch(error => {
console.log(error);
})
- client_id: 구글에서 발급받은 client id
- client_secret: 구글에서 발급받은 client secret pw
- code: 인가 코드
- grant_type: 'authorization_code'로 고정
- redirect_uri: 구글에서 설정한 Redirect URI
서버: 컨트롤러 > 서비스로 넘기고, 서비스에서 post 요청
try {
URI uri = new URI("https://oauth2.googleapis.com/token?"+params);
Object response = restTemplate.postForObject(uri, null, Object.class);
if (response != null) {
rModel.setState(true);
rModel.setMessage("구글 로그인에 성공했습니다.");
rModel.setResult(response);
} else {
rModel.setState(false);
rModel.setMessage("구글 로그인 응답을 받지 못했습니다.");
}
} catch (URISyntaxException e) {
rModel.setState(false);
rModel.setMessage("잘못된 URI 형식입니다.");
} catch (HttpClientErrorException | HttpServerErrorException e) {
rModel.setState(false);
rModel.setMessage("구글 로그인 중 서버 응답 오류: " + e.getStatusCode() + " " + e.getStatusText());
} catch (Exception e) {
rModel.setState(false);
rModel.setMessage("구글 로그인 중 오류가 발생했습니다: " + e.getMessage());
}
3. 로그인한 사용자 정보 받아오기
이번에도 역시 서버 측에서 get 요청을 해야 한다.
헤더 설정하여 서버로 보내고, 서버에서 받아서 처리한다.
헤더 설정 안 하고 보내서 엄청 헤맸다.
네이버에서 헤더 설정한 거랑 똑같이 해주면 되는데..😥
const userConfig = {
headers: {
'Authorization' : `Bearer ${this.token.access_token}`,
}
}
await axios.get(this.$store.state.url+'googlelogin', userConfig)
.then(response => {
console.log(response);
this.$store.commit('setSnsUserId', response.data.result.id)
this.$store.commit('setSnsUserEmail', response.data.result.email)
this.userinfo.id = response.data.result.id;
axios.post(this.$store.state.url + 'dup', this.userinfo)
.then(response => {
if(response.data.result.length == 0) {
this.$router.push({name: 'sns'})
} else {
sessionStorage.setItem('id', this.userinfo.id);
this.getUserinfo();
}
})
.catch(error => {
console.log(error);
})
})
.catch(error => {
console.log(error);
Swal.fire({
title: '로그인에 실패했습니다.',
icon: 'error'
});
})
try {
URI uri = new URI("https://www.googleapis.com/userinfo/v2/me");
// 헤더 설정
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", header);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity<Object> response = restTemplate.exchange(uri, HttpMethod.GET, entity, Object.class);
if (response.getBody() != null) {
rModel.setState(true);
rModel.setMessage(" 구글 로그인에 성공했습니다.");
rModel.setResult(response.getBody());
} else {
rModel.setState(false);
rModel.setMessage("구글 로그인 응답을 받지 못했습니다.");
}
} catch (URISyntaxException e) {
rModel.setState(false);
rModel.setMessage("잘못된 URI 형식입니다.");
} catch (Exception e) {
rModel.setState(false);
rModel.setMessage("구글 로그인 중 오류가 발생했습니다: " + e.getMessage());
}
최초 로그인일 경우 추가 정보 입력을 위해 회원가입 진행하고,
기존에 가입한 회원의 로그인일 경우 바로 일반 로그인과 같은 로직으로 로그인 처리.
'서버 > SprintBoot' 카테고리의 다른 글
[스프링부트(Spring Boot)] 소셜 로그인 로그아웃(네이버 로그아웃) (0) | 2023.09.18 |
---|---|
[스프링부트(Spring Boot)] 소셜 로그인 로그아웃(카카오 로그아웃) (0) | 2023.09.15 |
[스프링부트(Spring Boot)] 소셜 로그인(네이버 로그인) (0) | 2023.09.13 |
[스프링부트(Spring Boot)] 소셜 로그인(카카오 로그인) (1) | 2023.09.12 |
[스프링부트(Spring Boot)] sms 본인인증 ( Vue + Spring Boot ) (2) | 2023.09.11 |