스프링

 

 

 

0. 구글 개발자 설정

 

[SpringSecurity] 구글 로그인 연동하기 1 - 구글 서비스 등록

 

 

 

1. GoogleOAuthRequest

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class GoogleOAuthRequest {
	private String redirectUri;
	private String clientId;
	private String clientSecret;
	private String code;
	private String responseType;
	private String scope;
	private String accessType;
	private String grantType;
	private String state;
	private String includeGrantedScopes;
	private String loginHint;
	private String prompt;
}

 

 

 

2. GoogleOAuthResponse

import lombok.Data;

@Data
public class GoogleOAuthResponse {

	private String accessToken;
	private String expiresIn;
	private String refreshToken;
	private String scope;
	private String tokenType;
	private String idToken;

}

 

 

 

3. GoolgeVO

import lombok.Data;
import lombok.ToString;

/**
 * 
	iss=https://accounts.google.com, 
	
	azp=65465-scmetkg9rf7g0anodi1g4rfp434f81c7rfu.apps.googleusercontent.com,
	
	 
	aud=2383873471124-scmetkg9rf7g0ano5di431g24rf32pf81c7rfu.apps.googleusercontent.com, 
	
	sub=1012804324239237390221439, 
	
	email=honggidong@gmail.com,
	
	email_verified=true, 
	
	at_hash=Dv79dcE0q6Ydsadn2uxR5FJpHw, 
	
	name=홍길동, 

	picture=https://lh3.googleusercontent.com/a/AGNmyxZ-H_5vaMlSUoYZpdXFd134nFl63lJ-gCsJ7icmj3sA=s96-c, 
	
	given_name=길동, 
	
	
	family_name=홍, 
	
	locale=ko, 
	
	iat=16818033226, 
	
	exp=16813806826, 
	
	alg=RS4256, 
	
	kid=9697180428796829a92372e7949d1a9fff14231cd61b1e3, 
	
	typ=JWT

 *
 */

@Data
@ToString
public class GoolgeVO {

	private String id;
	
	private String email;
	
	private String name; 
	
	private String picture ; 
	
	private String given_name;
	
	private String family_name;
	
    private String oauth;
	
}

 

 

4.GoogleOAuthURL

public class GoogleOAuthURL {

	final static String GOOGLE_AUTH_BASE_URL = "https://accounts.google.com/o/oauth2/v2/auth";
	final static String GOOGLE_TOKEN_BASE_URL = "https://oauth2.googleapis.com/token";
	final static String GOOGLE_REVOKE_TOKEN_BASE_URL = "https://oauth2.googleapis.com/revoke";
	
	///login/oauth2/code/google
	final static String REDIRECT_URI = "http://localhost:8080/login/google/auth";
	
	final static String CLIENT_ID = "클라이언트 아이디";
	final static String CLIENT_SECRET = "클라이언트 시크릿";
	
	
	
	public static String url(){
		StringBuffer sb=new StringBuffer();
		sb.append(GOOGLE_AUTH_BASE_URL);
		sb.append("?client_id=");
		sb.append(CLIENT_ID);
		sb.append("&redirect_uri=");
		sb.append(REDIRECT_URI);
		sb.append("&response_type=code");
		sb.append("&scope=email profile openid https://www.googleapis.com/auth/drive.file");
		sb.append("&access_type=offline");
		
		return sb.toString();
	}
	
}

 

 

 

 

 

5.GoogleOAuthController

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.korea.webtoon.dao.MemberDAO;

@Controller
@RequestMapping("/login/google/")
public class GoogleOAuthController {




	@Autowired
	private  MemberDAO memberDao;
	
	

	/** 로그인페이지 로그인 첫 화면 요청 메소드 */
	@RequestMapping(value = "login.do", method = { RequestMethod.GET, RequestMethod.POST })
	public String join( Model model) {
		model.addAttribute("urlGoogle",GoogleOAuthURL.url());
		return "oauth/google/login";
	}
	
	

	/**
	 * Authentication Code를 전달 받는 엔드포인트
	 **/
	@GetMapping("auth")
	public String googleAuth(Model model, @RequestParam(value = "code") String authCode)
			throws JsonProcessingException {

		// HTTP Request를 위한 RestTemplate
		RestTemplate restTemplate = new RestTemplate();

		// Google OAuth Access Token 요청을 위한 파라미터 세팅
		GoogleOAuthRequest googleOAuthRequestParam = GoogleOAuthRequest.builder().clientId(GoogleOAuthURL.CLIENT_ID)
				.clientSecret(GoogleOAuthURL.CLIENT_SECRET).code(authCode).redirectUri("http://localhost:8080/login/google/auth")
				.grantType("authorization_code").build();

		// JSON 파싱을 위한 기본값 세팅
		// 요청시 파라미터는 스네이크 케이스로 세팅되므로 Object mapper에 미리 설정해준다.
		ObjectMapper mapper = new ObjectMapper();
		mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
		mapper.setSerializationInclusion(Include.NON_NULL);

		// AccessToken 발급 요청
		ResponseEntity<String> resultEntity = restTemplate.postForEntity(GoogleOAuthURL.GOOGLE_TOKEN_BASE_URL, googleOAuthRequestParam,
				String.class);

		// Token Request
		GoogleOAuthResponse result = mapper.readValue(resultEntity.getBody(), new TypeReference<GoogleOAuthResponse>() {});



		// ID Token만 추출 (사용자의 정보는 jwt로 인코딩 되어있다)
		String jwtToken = result.getIdToken();
		String requestUrl = UriComponentsBuilder.fromHttpUrl("https://oauth2.googleapis.com/tokeninfo")
				.queryParam("id_token", jwtToken).encode().toUriString();

		String resultJson = restTemplate.getForObject(requestUrl, String.class);

		Map<String, String> userInfo = mapper.readValue(resultJson, new TypeReference<Map<String, String>>() {});
		
		System.out.println("userInfo  정보  " +userInfo.toString());
		
		
		GoolgeVO googleVO=new GoolgeVO();
		googleVO.setId("google_"+userInfo.get("kid"));
		googleVO.setEmail(userInfo.get("email"));
		googleVO.setName(userInfo.get("name"));
		googleVO.setPicture(userInfo.get("picture"));
		googleVO.setOauth("google");
	
		//DB 에 저장 및 업데이트 처리
        memberDao.saveOauthGoole(googleVO);
		
		
		model.addAllAttributes(userInfo);
		model.addAttribute("token", result.getAccessToken());
		System.out.println(userInfo);

		return "oauth/google/loginSuccess";

	}

	/**
	 * 토큰 무효화
	 **/
	@GetMapping("revoke/token")
	@ResponseBody
	public Map<String, String> revokeToken(@RequestParam(value = "token") String token) throws JsonProcessingException {

		Map<String, String> result = new HashMap<>();
		RestTemplate restTemplate = new RestTemplate();
		final String requestUrl = UriComponentsBuilder.fromHttpUrl(GoogleOAuthURL.GOOGLE_REVOKE_TOKEN_BASE_URL)
				.queryParam("token", token).encode().toUriString();

		System.out.println("TOKEN ? " + token);

		String resultJson = restTemplate.postForObject(requestUrl, null, String.class);
		result.put("result", "success");
		result.put("resultJson", resultJson);

		return result;

	}

}

 

 

 

 

6.login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>google OAuth</title>
<style type="text/css">
#container{width:500px}
.sns_join a.google{border-color:#eb6155}
.sns_join a{display:block;margin-top:10px;width:100%;height:50px;border:1px solid #000;font-size:15px;line-height:50px;text-align:center;background:#fff}
.sns_join a.google>.icon{background:url(https://cdn.jsdelivr.net/gh/braverokmc79/ouath2-img@v1.0.0/images/icon_google.png) no-repeat 0 0;background-size:18px auto}
.sns_join a>.icon{display:inline-block;margin:0 auto;padding-left:29px;width:188px;color:#666;font-size:15px;letter-spacing:-1px;line-height:20px;text-align:left}
</style>
</head>
<body>

	
	<div id="container">
		<div class="sns_join">
			<a class="google" href="${urlGoogle}" id="googleLoginBtn"> <span class="icon">구글 로그인</span>
			</a>
		</div>
	</div>
	
</body>
	
<script>
 	const onClickGoogleLogin = (e) => {
 		window.location.replace('${src}')
 	}
	const googleLoginBtn = document.getElementById("googleLoginBtn");
	googleLoginBtn.addEventListener("click", onClickGoogleLogin) 
</script>
</html>

 

 

 

 

 

7.loginSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Google Login 완료</h1>
	<div>${token}</div>
	<div>${email}</div>
	<div>
		<img src="${picture}"></img>
	</div>


	<div>
		<a href="/">홈</a>
	</div>
</body>
</html>

 

 

 

 

db 저장 참조

 

	<insert id="saveOauthGoole">
		MERGE INTO WEBTOON_USER
		  USING DUAL ON (EMAIL = #{email} )
     WHEN MATCHED THEN
		  	UPDATE SET OAUTH = #{oauth} 
	 WHEN NOT MATCHED THEN
		    INSERT  (USER_IDX, NAME, ID,  EMAIL,  OAUTH) 
		                     VALUES( seq_user_idx.nextVal,
									#{name},
									#{id},
									#{email},
									#{oauth} 
									)	
	
	</insert>

 

 

 

 

스프링 네이버 로그인 처리, Sns Naver 연동 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

모든 악을 저지르지 말고 모든 선을 행하여 내 마음을 정(淨)하게 하는 이것이 제불(諸佛)의 가르침이다. -법구경

댓글 ( 4)

댓글 남기기

작성