사전에 Spring Security 설정은 되어있어야 진행된다. 

SecurityContext sc = SecurityContextHolder.getContext();

//ID, PW, 권한을 설정합니다. PW는 null 이어도 상관없음
sc.setAuthentication(new UsernamePasswordAuthenticationToken(id, null, role)); // (id, pw, 권한)

//Spring security 세션에 등록
httpSession.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, sc);

 


Session을 이용한 로그인 처리~~~!! 

내부에서만 사용하거나 단순한 사이트로 굳이 Security 까지 추가할 필요가 없는 경우 사용하면 좋겠다. 

 

프로세스는 ~~~ 

모든 요청을 감시하는 Interceptor 생성! 

로그인에 성공하면 Session값을 설정하고 

요청이 올때마다 Interceptor가 Session 값이 있는지 확인 후 없다면 로그인페이지로 리턴시키걸로~ 

 

즈아~~ 시작! 

 

1.  Interceptor 생성 
요청이 들어오면 Session 지정해둔 Session 값을 확인하고 없다면 로그인페이지로 리다이렉트 처리한다. 

public class LoginInterceptor extends HandlerInterceptorAdapter {
	private static final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		
		if( request.getSession().getAttribute(Consts.AUTHORIZED) == null  ) {
			response.sendRedirect(request.getContextPath() +"/login");
			return false;
		}
		return true;
	}
}

 

2. Interceptor 등록! 
모든 요청을 검사하도록  .addPathPatterns("/**") 로 설정 후 
Js, css 파일 등이 들어있는 resource 디렉토리 하위는 무시하도록 exclude 처리한다. 
로그인을 위한 요청도 exclude 처리~~!! 

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter  {
	
	 @Override
	    public void addInterceptors(InterceptorRegistry registry) {
	        registry.addInterceptor(new LoginInterceptor())
	                .addPathPatterns("/**")
	                .excludePathPatterns("/resources/**")
	                .excludePathPatterns("/login/**"); 
	    }
	 
}

 

 

3. Login/out 세션작업~~!! 

(위치는 각자 로그인/아웃 파일에 작성!)

// Login 
// 비밀번호, 잠금여부 등등 모든 조건이 맞아 로그인에 성공하게되면 Session 값을 추가해준다. 
request.getSession().setAttribute(Consts.AUTHORIZED, Consts.AUTHORIZED_VALUE);

// Logout
// 로그아웃시 Session 값을 제거해준다. 
request.getSession().removeAttribute(Consts.AUTHORIZED); 

 

4. Session 시간 설정~ 

초단위 결과를 안쓰고 굳이 (60 * 60 * 24)로 쓴 이유는~ 보고 바로 알수있게 하기 위함~~

 시간 같은건 이렇게 해주면 같이 일하는 사람 편하겠죠?  ( 암산이 빠르면 필요없겠지만.. 나는 좋음.. ^^! ) 

public class SessionListener  implements HttpSessionListener{

	@Override
	public void sessionCreated(HttpSessionEvent session) {
		session.getSession().setMaxInactiveInterval(60 * 60 * 24);// 24 시간으로 설정
	}
	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
	}

}

 

 

Session 만료되면 자동으로 로그인페이지로 보내볼까??? 

시간 설정할때 보니 아래 있는 sessionDestroyed가 Session이 만료되면 호출된다고한다. 

요고요고 ~ ↓ 


	@Override
	public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
		 HttpSession session = httpSessionEvent.getSession();
		
	}


음~~

그럼 여기서 로그인 페이지로 redirect해주면 되겠군! 하고 생각할 수 있다. 

자~! 여기서 생각해봐야할건 

sessionDestroyed 메소드는 사용자의 요청으로 호출되는게 아니라

Session이 만료되었을때 호출 된다는 것이다. 

즉 ~ R e q u e s t 가 없 다 는 뜻 ! !  

요청(request)이 없으니 redirect 할곳도 없습니다~ ~!

혹시~~~~ redirect 처리한다고 시간낭비하지 않기로 ..  ^^ 

 

보통 Session 만료 검사를 Interceptor에서 필터링으로 처리하는데 

우린 이미 interceptor 처리하고있으니~ 추가안해도 될듯

 

그래도~~~!! 

Session 만료되기 전 뭔가 알림을  설정하고자 한다면 

스크립트단에서 

setInterval 같은 함수를 이용해 10분 간격으로 체크!~

이벤트가 생기면 체크값을 초기화~ 이벤드가 없어서 5번째까지 온다면 

"세션이 10분 남았음"  표기를 해주는것도 방법일 듯 하다. ~ 

 

1. 로그인 페이지 만들기! 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
	<script src="https://developers.kakao.com/sdk/js/kakao.min.js"></script>
</head>
<body>

  
    <h1>로그인</h1>
    <hr>

    <form action="/user/login" method="post">
        <input type="text" name="username" placeholder="이메일 입력해주세요">
        <input type="password" name="password" placeholder="비밀번호">
        <button type="submit">로그인</button>
        
        
  		<a href="http://developers.kakao.com/logout"></a>
  		
    </form>
    
	<a href="https://kauth.kakao.com/oauth/authorize?client_id={클라이언트키}&redirect_uri={리다이렉트 url}&response_type=code">로그인</a>
	<a href="https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={클라이언트아이디}&scope=profile,account_email&state=Z3JNGXqbBZCtif_8D0hz5hWhuAeftMPNUIeCOW4_Kj4%3D&redirect_uri={리다이렉트 url}">동의</a>
    
    
    <script src="/resources/css/bower_components/jquery/dist/jquery.min.js"></script>
	<script src="/resources/css/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
	<script src="/resources/css/dist/js/adminlte.min.js"></script>
	<script src="/resources/js/utils/easy_ui/jquery.easyui.min.js"></script>
   

   
</body>
</html>


 

 

controller 

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.me.genie.service.KakaoService;

@Controller
public class KakaoController {
	
	@Autowired private KakaoService kakaoService;
	
	@RequestMapping("/login")
    public String home(@RequestParam(value = "code", required = false) String code, Model model) throws Exception{
        System.out.println("#########" + code);
        
        /******************************************************
         *  카카오 리턴 값들~
         *****************************************************/
        String access_Token = "";
        if(code != null ) { 
        	access_Token = kakaoService.getAccessToken(code);
        }
        if(access_Token != "") { 
        	System.out.println("###access_Token#### : " + access_Token);
        	HashMap<String, Object> userInfo = kakaoService.getUserInfo(access_Token);
        	System.out.println("###access_Token#### : " + access_Token);
        	System.out.println("###userInfo#### : " + userInfo.get("email"));
        	System.out.println("###nickname#### : " + userInfo.get("nickname"));
        	System.out.println("###profile_image#### : " + userInfo.get("profile_image"));
        }
       
        return "home";
    }
}

 

service 

package com.me.genie.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;

import org.springframework.stereotype.Service;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

@Service
public class KakaoService {


        public String getAccessToken (String authorize_code) {
            String access_Token = "";
            String refresh_Token = "";
            String reqURL = "https://kauth.kakao.com/oauth/token";

            try {
            	/***************************************
            	 * 요청을 보낼 값 셋팅 
            	 **************************************/
            	 URL url = new URL(reqURL);
                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                 conn.setRequestMethod("POST");
                 conn.setDoOutput(true);// POST 요청을 위해 기본값이 false인 setDoOutput을 true로

                 
                 /***************************************
             	 * POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송 
             	 **************************************/
                 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
                 StringBuilder sb = new StringBuilder();
                 sb.append("grant_type=authorization_code");
                 sb.append("&client_id=82693748acf2adcab6a974138e807eea");  // 발급받은 key
                 sb.append("&redirect_uri=http://localhost:8080/login");     // 설정해 놓은 경로
                 sb.append("&code=" + authorize_code);
                 bw.write(sb.toString());
                 bw.flush();

                 /***************************************
              	 * 결과 코드가 200이라면 성공 
              	 **************************************/
                 int responseCode = conn.getResponseCode();
                 System.out.println("responseCode : " + responseCode);


                 /***************************************
               	 * 결과 데이터 (JSON타입의 Response) 메세지 읽어오기 
               	 **************************************/
                 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                 String line = "";
                 String result = "";
                 while ((line = br.readLine()) != null) {
                     result += line;
                 }

                 /***************************************
            	 * Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성 
            	 **************************************/
                 JsonParser parser = new JsonParser();
                 JsonElement element = parser.parse(result);

                 /***************************************
             	 * 파싱된 데이터 읽어오기  
             	 **************************************/	
                 access_Token = element.getAsJsonObject().get("access_token").getAsString();
                 refresh_Token = element.getAsJsonObject().get("refresh_token").getAsString();

                 System.out.println("access_token : " + access_Token);
                 System.out.println("refresh_token : " + refresh_Token);

                 
                 /***************************************
              	 * 스트림은 사용 후 꼭 닫아주기! 
              	 **************************************/	
                 br.close();
                 bw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return access_Token;
        }
        
        
        public HashMap<String, Object> getUserInfo (String access_Token) {

        	 /***************************************
          	 * 사용자마다 정보가 다를 수 있기에 HashMap타입으로 선언 
          	 **************************************/	
            HashMap<String, Object> userInfo = new HashMap<String, Object>();
            String reqURL = "https://kapi.kakao.com/v2/user/me";
            try {
            	
            	/***************************************
              	 * 요청을 보낼 값 셋팅 
              	 **************************************/
                URL url = new URL(reqURL);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");

                /***************************************
              	 * 요청에 필요한 Header에 포함될 내용 
              	 **************************************/
                conn.setRequestProperty("Authorization", "Bearer " + access_Token);
                
                /***************************************
              	 *결과 코드가 200이라면 성공 
              	 **************************************/
                int responseCode = conn.getResponseCode();
                System.out.println("responseCode : " + responseCode);

                
                /***************************************
              	 *결과 데이터 (JSON타입의 Response) 메세지 읽어오기 
              	 **************************************/
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = "";
                String result = "";
                while ((line = br.readLine()) != null) {
                    result += line;
                }
                br.close();
                System.out.println("response body : " + result);

                
                /***************************************
            	 * Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성 
            	 **************************************/
                JsonParser parser = new JsonParser();
                JsonElement element = parser.parse(result);
                
                
                /***************************************
             	 * 파싱된 데이터 읽어오기  
             	 **************************************/	
                JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
                JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();

                String nickname = properties.getAsJsonObject().get("nickname").getAsString();
                String profile_image = properties.getAsJsonObject().get("profile_image").getAsString();
                String email = kakao_account.getAsJsonObject().get("email").getAsString();

                userInfo.put("nickname", nickname);
                userInfo.put("email", email);
                userInfo.put("profile_image", profile_image);
                
                
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
               
            }

            return userInfo;
        }
}

 

오늘은 카카오톡 연동 가이드를 작성해본다~ 

가이드로 사용할거라 시큐리티 없이 기능만 작성해둔다! 

시작!! 

 

1. 카카오톡 개발자 사이트 접속 후 계정 생성!  (developers.kakao.com/)

 

2. 로그인하면 나오는 화면인데 내 어플리케이션 메뉴에 들어가 어플리케이션을 추가한다! 

 

 

3. 플러스 모양 버튼이 나오면 아래와 같은 창이 뜬다. 내용 입력해주기~ 

 

 

4. 프로젝트를 생성하면  사용할 키들이 발급된다.

 

 

5. 카카오로그인 메뉴로 가서 리다이렉트 URL 을 설정해준다.

 

6. 사용자에게 받을 동의항목을 설정해준다. 사용자의 이메일을 받고 싶다면 아래의 이미지처럼 이메일도 추가해야한다.

이제 카카오톡은 이메일 없이도 회원가입이 가능해서 이점 유의하기! 

 

<이전포스팅>

 

[Google 로그인] #2 FRONT 코드작성!

지난 포스팅에서 로그인 기능을 사용할 준비를 했다면 이제 직접 구현해보자! < 지난 포스팅! > [Google 로그인] #1 개발자 콘솔 가입! 1. 구글 개발자 콘솔에 로그인한다. console.developers.google.com/ Googl

genie-dev.tistory.com

 

Spring maven 환경에서 사용할

가이드 용도로 작업한거라 간단하게 기능만 짤라서 구현한 내용임! 

(시큐리티 적용 X)

 

순서는 이렇다~ 

1. 로그인페이지에서 구글 로그인 

2. 결과로 리턴받은 토큰을 서버로 전송 

3. 토큰을 이용해서 서버단에서 다시한번 사용자 정보 요청 

4. 프론트에서 넘어온 정보와 서버단에서 가져온 사용자 정보가 일치하는지 확인

5. 로그인 처리 or 내가 원하는 다른 작업을 진행하면 된다. 

 

pom.xml ( 필요한 기능들을 추가해준다. ) 

		<!--  새로 추가  -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-core</artifactId>
		    <version>2.12.1</version>
		</dependency>
		
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.12.1</version>
		</dependency>
		
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-annotations</artifactId>
		    <version>2.12.1</version>
		</dependency>
		
		<dependency>
		    <groupId>org.codehaus.jackson</groupId>
		    <artifactId>jackson-mapper-asl</artifactId>
		    <version>1.9.13</version>
		</dependency>
				
		
		<dependency>
		    <groupId>com.google.code.gson</groupId>
		    <artifactId>gson</artifactId>
		    <version>2.8.6</version>
		</dependency>
		
		<dependency>
	     <groupId>com.google.api-client</groupId>
	     <artifactId>google-api-client</artifactId>
	     <version>1.31.2</version>
	   </dependency>
	   
		<dependency>
		    <groupId>com.google.api-client</groupId>
		    <artifactId>google-api-client-jackson2</artifactId>
		    <version>1.20.0</version>
		</dependency>
	  

 

VO 생성 ( 내가 받을 내용을 작성하면 되는데 테스트용이므로 간단하게 작성했다.)

public class UserVO {
	private String email;
	private String token;
	
	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	} 
	
}

 

Controller 생성 ( 요청을 받을 컨트롤러를 작성한다)

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


import com.me.genie.service.GoogleService;
import com.me.genie.vo.UserVO;

import java.io.IOException;

@Controller
public class GoogleController {
	
	@Autowired GoogleService googleService;
	
	/**
	 * Authentication Code를 전달 받는 엔드포인트
     * 구글 개발자 사이트에서 리턴url로 적었을 경우만 가져옴
     * 백엔드에서 받는 방법도 보여주고자 작성함
	 * @throws IOException 
	 * @throws JsonProcessingException
	 * @throws JsonMappingException
	 **/
	@RequestMapping(value = "/google/auth")
	public String googleAuth(Model model, @RequestParam(value = "code") String authCode) throws IOException{
		// 구글이 리턴해준 코드가 들어온다.
		System.out.println("AUtho code : " + authCode);
		googleService.getToken(authCode);
		return "/home";
	}
	
	
	/**
	 * 프론트로부터 ajax 요청을 받는다.
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/google/userinfo", produces = "application/json")
	@ResponseBody 
	public Map<String, Object> revokeToken(UserVO user) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("res", googleService.tokenCheck(user));
		return result;

	}

}

 

Service ( 비즈니스 로직처리할 서비스 구현)

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;

import org.springframework.stereotype.Service;


import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;

import com.me.genie.service.GoogleService;
import com.me.genie.vo.UserVO;

@Service
public class GoogleService {
	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";
	final static String GOOGLE_GET_USER_INFO_URL = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=";
	final static String clientId = "나의 클라이언트키";
	final static String clientSecret = "비밀키";
	
	 private static final HttpTransport transport = new NetHttpTransport();
	 private static final JsonFactory jsonFactory = new JacksonFactory();
	
	 /**
	 * 백엔드단에서 토큰을 얻어온다.
	  * @param authCode
	  * @return access_Token
	  * @throws IOException
	  */
	public String getToken(String authCode) throws IOException {
		
		/**************************************
         * Access 토큰을 가져오기 위한 설정
         *************************************/
		URL url = new URL(GOOGLE_TOKEN_BASE_URL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setDoOutput(true);

        
        /**************************************
         * 파라메터 설정
         *************************************/
        StringBuffer sbf = new StringBuffer();
        sbf.append("code=");sbf.append(authCode);
        sbf.append("&client_id=");sbf.append(clientId);
        sbf.append("&client_secret=");sbf.append(clientSecret);
        sbf.append("&redirect_uri=");sbf.append("http://localhost:8080/google/auth");
        sbf.append("&grant_type=");sbf.append("authorization_code");
        String  parameterString = sbf.toString();
		
        
        /**************************************
         * 요청을 보내고 받을 스트림 생성
         *************************************/
		BufferedOutputStream bous = new BufferedOutputStream(conn.getOutputStream());
		bous.write(parameterString.getBytes()); 
		bous.flush(); 
		bous.close();
		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		
		/**************************************
         * 받아온 데이터를 sb에 저장
         *************************************/
		StringBuilder sb = new StringBuilder(); 
		String line;
		while ((line = br.readLine()) != null) { 
			sb.append(line); 
		}
		
		/**************************************
         * 받아온 데이터에서 토큰 추출
         *************************************/
		String access_Token ="";
		if (conn.getResponseCode() == 200) { 
            JsonParser parser = new JsonParser();
            JsonElement element = parser.parse(sb.toString());
            access_Token = element.getAsJsonObject().get("access_token").getAsString();
            System.out.println("access_token : " + access_Token);
            
            if(access_Token!=null) {
                /***사용자 정보 요청 **/
            	userinfo(access_Token);
            }
		}
		return access_Token;
	}
	
	/**
	 * access_token 이용하여 사용자 정보를 가져온다.
	 * @param access_token
	 */
	public void userinfo(String access_token) {
		try { 
			
			/**************************************
	         * 사용자 정보를 가져오기 위한 셋팅
	         *************************************/
	        URL url = new URL(GOOGLE_GET_USER_INFO_URL+access_token);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET"); 
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			conn.setDoOutput(true);
			
			
			/**************************************
	         * 요청을 보내고 받을 스트림 생성
	         *************************************/
			BufferedOutputStream bous = new BufferedOutputStream(conn.getOutputStream());
			bous.flush(); 
			bous.close();
			
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuilder sb = new StringBuilder(); String line;
	  
			while ((line = br.readLine()) != null) { 
				sb.append(line); 
			}
			 
			/**************************************
	         * 받아온 데이터에서 출력
	         *************************************/
			if (conn.getResponseCode() == 200) { 
				System.out.println(sb.toString()); 
			}
			
		} catch (Exception e) {
			System.out.println("ERROR. . . PLEASE CHECK ... [GoogleService.userinfo]");
			e.printStackTrace();
		}
	}
	
	/**
	 * 사용자단에서 가져온 토큰값으로 
	 * 유효한사용자인지, 요청온 이메일은 맞는지 확인한다.
	 * @param user
	 * @return 유효여부
	 */
	public boolean tokenCheck(UserVO user) {
		boolean res = false;
		try {
			
			/**************************************
	         * 사용자 정보를 가져오기 위해 구글에서 
	         * 제공하는 설정 셋팅
	         *************************************/
			GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
			    .setAudience(Collections.singletonList(clientId))
			    .build();
		
			/**************************************
	         * 프론트 단에서 로그인 후 받아온 코드 설정 후 
	         * 사용자 정보를 가져온다.
	         *************************************/
			GoogleIdToken idToken = verifier.verify(user.getToken());
			
			// 사용자 정보가 존재하는지 확인
			if (idToken != null) {
			  // 사용자 정보가 담긴 데이터를 가져온다.
			  Payload payload = idToken.getPayload();
		
			  // 사용자 고유 ID 가져온다.
			  String userId = payload.getSubject();
			  System.out.println("User ID: " + userId);
		
			  // 그외 사용자 정보를 가져온다.
			  String email = payload.getEmail();
			  String name = (String) payload.get("name");
			  String pictureUrl = (String) payload.get("picture");
			  String locale = (String) payload.get("locale");
			  String familyName = (String) payload.get("family_name");
			  String givenName = (String) payload.get("given_name");
			  
			  /**************************************
	          * 프론트 단에서 로그인을 시도한 이메일과, 코드를 통해 가져온 정보가 일치하는지 확인한다. 
	          *************************************/
			  if(user.getEmail().equals(email)) { 
				  res = true; 
			  }
			  
			} else {
			  System.out.println("Invalid ID token.");
			}
			
		} catch (Exception e) {
			System.out.println("ERROR. . . PLEASE CHECK ... [GoogleService.userinfo]");
			e.printStackTrace();
		}
		return res;
	}
}

 

home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
	<script src="https://apis.google.com/js/platform.js" async defer></script>
	<meta name="google-signin-client_id" content="{발급받인 클라이언트 아이디}.apps.googleusercontent.com"></meta>
</head>
<body>

  
    <h1>로그인</h1>
    <hr>

    <form action="/user/login" method="post">
        <input type="text" name="username" placeholder="이메일 입력해주세요">
        <input type="password" name="password" placeholder="비밀번호">
        <button type="submit">로그인</button>
        
        <!-- 구글 로그인  -->
		<div class="g-signin2" data-onsuccess="onSignIn"></div>
		<!-- 구글 아웃 -->
		<a href="#" onclick="signOut()">구글 로그아웃</a>
        
        
  		
    </form>
	
    
    <script src="/resources/css/bower_components/jquery/dist/jquery.min.js"></script>
	<script src="/resources/css/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
	<script src="/resources/css/dist/js/adminlte.min.js"></script>
	<script src="/resources/js/utils/easy_ui/jquery.easyui.min.js"></script>
    <script>
	function onSignIn(googleUser) { 
		
    	var profile = googleUser.getBasicProfile(); 
		/*
    	console.log('ID: ' + profile.getId()); // 이건 백엔드로 보내면 안됨! 보안의 위험이 있음. 
    	console.log('Name: ' + profile.getName()); 
    	console.log('Image URL: ' + profile.getImageUrl()); 
    	console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
		console.log(googleUser.getAuthResponse().id_token); // 서버에 던질땐 보안을 위해 이값으로 던져준다.
		*/
		
		var email = profile.getEmail();
		var token = googleUser.getAuthResponse().id_token;
    	$.ajax({
    	    url:'/google/userinfo', 
    	    type:'post', 
    	    data:{'token': token, 'email': email}, 
    	    success: function(data) {
    	        if(data.res) { 
	    	        alert("OK");
       	        } else {
       	        	alert("비정상로그인 접근입니다.");
           	    }
    	    },
    	    error: function(err) {
    	        //서버로부터 응답이 정상적으로 처리되지 못햇을 때 실행
    	    }
    	});
    }
	 
	function signOut() { 
    	var auth2 = gapi.auth2.getAuthInstance(); 
    	auth2.signOut().then(function () {
        	 self.location="로그아웃할 url"; 
        }); 
   	 } 
  	</script>

   
</body>
</html>


 

+ Recent posts