Merge remote-tracking branch 'origin/master'

This commit is contained in:
KNKIM 2021-08-17 11:15:08 +09:00
commit 5a7fd69462
18 changed files with 818 additions and 545 deletions

24
pom.xml
View File

@ -191,7 +191,29 @@
<artifactId>jackson-dataformat-xml</artifactId> <artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.0</version> <version>2.9.0</version>
</dependency> </dependency>
<!-- NAVER LOGIN (DIGITALSHIP JSYOO 2021.08.12) -->
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>2.8.1</version>
</dependency>
<!-- 제이슨 파싱 (DIGITALSHIP JSYOO 2021.08.12)-->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<!-- GOOGLE LOGIN (DIGITALSHIP JSYOO 2021.08.12) -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<!-- 바코드 ZXing (DIGITALSHIP KNKIM 2021.06.25)--> <!-- 바코드 ZXing (DIGITALSHIP KNKIM 2021.06.25)-->
<dependency> <dependency>
<groupId>com.google.zxing</groupId> <groupId>com.google.zxing</groupId>

View File

@ -0,0 +1,90 @@
package nlib.cmm.snslogin;
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;
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getResponseType() {
return responseType;
}
public void setResponseType(String responseType) {
this.responseType = responseType;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getAccessType() {
return accessType;
}
public void setAccessType(String accessType) {
this.accessType = accessType;
}
public String getGrantType() {
return grantType;
}
public void setGrantType(String grantType) {
this.grantType = grantType;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getIncludeGrantedScopes() {
return includeGrantedScopes;
}
public void setIncludeGrantedScopes(String includeGrantedScopes) {
this.includeGrantedScopes = includeGrantedScopes;
}
public String getLoginHint() {
return loginHint;
}
public void setLoginHint(String loginHint) {
this.loginHint = loginHint;
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
}

View File

@ -0,0 +1,49 @@
package nlib.cmm.snslogin;
public class GoogleOAuthResponse {
private String accessToken;
private String expiresIn;
private String refreshToken;
private String scope;
private String tokenType;
private String idToken;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(String expiresIn) {
this.expiresIn = expiresIn;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getTokenType() {
return tokenType;
}
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
public String getIdToken() {
return idToken;
}
public void setIdToken(String idToken) {
this.idToken = idToken;
}
}

View File

@ -0,0 +1,81 @@
package nlib.cmm.snslogin;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.stereotype.Controller;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
public class KakaoController {
private final static String K_CLIENT_ID = "e74d25210853313dd1fead4c6c1f06ec";
public static String getAuthorizationUrl(HttpSession session,String K_REDIRECT_URI) {
String kakaoUrl = "https://kauth.kakao.com/oauth/authorize?" + "client_id=" + K_CLIENT_ID + "&redirect_uri="
+ K_REDIRECT_URI + "&response_type=code";
return kakaoUrl;
}
public static JsonNode getAccessToken(String autorize_code,String K_REDIRECT_URI) {
final String RequestUrl = "https://kauth.kakao.com/oauth/token";
final List<NameValuePair> postParams = new ArrayList<NameValuePair>();
postParams.add(new BasicNameValuePair("grant_type", "authorization_code"));
postParams.add(new BasicNameValuePair("client_id", K_CLIENT_ID)); // REST API KEY
postParams.add(new BasicNameValuePair("redirect_uri",K_REDIRECT_URI));
// 리다이렉트 URI
postParams.add(new BasicNameValuePair("code",autorize_code)); // 로그인 과정중 얻은 code
final HttpClient client = HttpClientBuilder.create().build();
final HttpPost post = new HttpPost(RequestUrl);
JsonNode returnNode = null;
try {
post.setEntity(new UrlEncodedFormEntity(postParams));
final HttpResponse response = client.execute(post);
// JSON 형태 반환값 처리
ObjectMapper mapper = new ObjectMapper();
returnNode = mapper.readTree(response.getEntity().getContent());
} catch (UnsupportedEncodingException e){
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace(); }
finally {
// clear resources
} return returnNode;
}
public static JsonNode getKakaoUserInfo(JsonNode accessToken) {
final String RequestUrl = "https://kapi.kakao.com/v2/user/me";
final HttpClient client = HttpClientBuilder.create().build();
final HttpPost post = new HttpPost(RequestUrl);
// add header
post.addHeader("Authorization", "Bearer " + accessToken);
JsonNode returnNode = null;
try {
final HttpResponse response = client.execute(post);
// JSON 형태 반환값 처리
ObjectMapper mapper = new ObjectMapper();
returnNode = mapper.readTree(response.getEntity().getContent());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// clear resources
} return returnNode;
}
}

View File

@ -0,0 +1,29 @@
package nlib.cmm.snslogin;
import com.github.scribejava.core.builder.api.DefaultApi20;
public class NaverLoginApi extends DefaultApi20{
protected NaverLoginApi(){
}
private static class InstanceHolder{
private static final NaverLoginApi INSTANCE = new NaverLoginApi();
}
public static NaverLoginApi instance(){
return InstanceHolder.INSTANCE;
}
@Override
public String getAccessTokenEndpoint() {
return "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code";
}
@Override
protected String getAuthorizationBaseUrl() {
return "https://nid.naver.com/oauth2.0/authorize";
}
}

View File

@ -0,0 +1,102 @@
package nlib.cmm.snslogin;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
public class NaverLoginBO {
/* 인증 요청문을 구성하는 파라미터 */
//client_id: 애플리케이션 등록 발급받은 클라이언트 아이디
//response_type: 인증 과정에 대한 구분값. code로 값이 고정돼 있습니다.
//redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩). 애플리케이션을 등록할 Callback URL에 설정한 정보입니다.
//state: 애플리케이션이 생성한 상태 토큰
private final static String CLIENT_ID = "jefkoYhSfrQ3TtZz5mTp";
private final static String CLIENT_SECRET = "E2qAGaLEaG";
private static String REDIRECT_URI = "";
private final static String SESSION_STATE = "oauth_state";
/* 프로필 조회 API URL */
private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me";
public void setRedirect_url(String REDIRECT_URI) {
this.REDIRECT_URI = REDIRECT_URI;
}
/* 네이버 아이디로 인증 URL 생성 Method */
public String getAuthorizationUrl(HttpSession session) {
/* 세션 유효성 검증을 위하여 난수를 생성 */
String state = generateRandomString();
/* 생성한 난수 값을 session에 저장 */
setSession(session,state);
System.out.println(getSession(session));
/* Scribe에서 제공하는 인증 URL 생성 기능을 이용하여 네아로 인증 URL 생성 */
OAuth20Service oauthService = new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(REDIRECT_URI)
.state(state) //앞서 생성한 난수값을 인증 URL생성시 사용함
.build(NaverLoginApi.instance());
return oauthService.getAuthorizationUrl();
}
/* 네이버아이디로 Callback 처리 및 AccessToken 획득 Method */
public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state) throws IOException{
/* Callback으로 전달받은 세선검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인 */
String sessionState = getSession(session);
if(StringUtils.pathEquals(sessionState, state)){
OAuth20Service oauthService = new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(REDIRECT_URI)
.state(state)
.build(NaverLoginApi.instance());
/* Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득 */
OAuth2AccessToken accessToken = oauthService.getAccessToken(code);
return accessToken;
}
return null;
}
/* 세션 유효성 검증을 위한 난수 생성기 */
private String generateRandomString() {
return UUID.randomUUID().toString();
}
/* http session에 데이터 저장 */
private void setSession(HttpSession session,String state){
session.setAttribute(SESSION_STATE, state);
}
/* http session에서 데이터 가져오기 */
private String getSession(HttpSession session){
return (String) session.getAttribute(SESSION_STATE);
}
/* Access Token을 이용하여 네이버 사용자 프로필 API를 호출 */
public String getUserProfile(OAuth2AccessToken oauthToken) throws IOException{
OAuth20Service oauthService =new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(REDIRECT_URI).build(NaverLoginApi.instance());
OAuthRequest request = new OAuthRequest(Verb.GET, PROFILE_API_URL, oauthService);
oauthService.signRequest(oauthToken, request);
Response response = request.send();
return response.getBody();
}
}

View File

@ -58,8 +58,6 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/inform/**") .antMatchers("/inform/**")
.antMatchers("/alert/**") .antMatchers("/alert/**")
.antMatchers("/code/**") .antMatchers("/code/**")
.antMatchers("/test/**")
.antMatchers("/login/**")
; ;
} }
@ -69,6 +67,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/login/login*.do").permitAll() .antMatchers("/login/login*.do").permitAll()
.antMatchers("/login/logout*.do").permitAll() .antMatchers("/login/logout*.do").permitAll()
.antMatchers("/login/naver*.do").permitAll() .antMatchers("/login/naver*.do").permitAll()
.antMatchers("/login/google*.do").permitAll()
.antMatchers("/login/kakao*.do").permitAll()
.antMatchers("/member/*.do").permitAll() .antMatchers("/member/*.do").permitAll()
.antMatchers("/member/*.ajax").permitAll() .antMatchers("/member/*.ajax").permitAll()
.antMatchers("/userInfo/*.do").permitAll() .antMatchers("/userInfo/*.do").permitAll()

View File

@ -1,39 +1,66 @@
package nlib.user.web; package nlib.user.web;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache; import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest; import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping; 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.RequestParam;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.UriComponentsBuilder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.github.scribejava.core.model.OAuth2AccessToken;
import nlib.cmm.snslogin.GoogleOAuthResponse;
import nlib.cmm.snslogin.KakaoController;
import nlib.cmm.snslogin.NaverLoginBO;
import nlib.user.service.LoginService; import nlib.user.service.LoginService;
import nlib.util.StringUtil; import nlib.util.StringUtil;
/** /**
* <pre> * <pre>
* @Class Name : LoginController.java * &#64;Class Name : LoginController.java
* *
* @Description : 스프링 시큐리티를 이용한 로그인 처리 컨트롤러 * &#64;Description : 스프링 시큐리티를 이용한 로그인 처리 컨트롤러
* *
* *
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021) * &#64;프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
* *
* </pre> * </pre>
* *
* @ ------------ -------- --------------------------- * @ ------------ -------- --------------------------- @ 수정일 수정자 수정내용 @
* @ 수정일 수정자 수정내용 * ------------ -------- --------------------------- @ 2021. 7. 9. KNKIM 최초 생성
* @ ------------ -------- ---------------------------
* @ 2021. 7. 9. KNKIM 최초 생성
* *
* *
* @author 이씨플라자 * DIGITALSHIP KNKIM * @author 이씨플라자 * DIGITALSHIP KNKIM
@ -42,14 +69,22 @@ import nlib.util.StringUtil;
* *
*/ */
@Controller @Controller
public class LoginController public class LoginController {
{
private static final Logger log = LoggerFactory.getLogger(LoginController.class); private static final Logger log = LoggerFactory.getLogger(LoginController.class);
/* NaverLoginBO */
private NaverLoginBO naverLoginBO;
private String apiResult = null;
@Autowired
private void setNaverLoginBO(NaverLoginBO naverLoginBO) {
this.naverLoginBO = naverLoginBO;
}
@Resource(name = "loginService") @Resource(name = "loginService")
private LoginService loginService; private LoginService loginService;
/** /**
* 로그인 정보 입력 화면을 출력한다. * 로그인 정보 입력 화면을 출력한다.
* *
@ -60,25 +95,141 @@ public class LoginController
* @return * @return
*/ */
@RequestMapping("/login/loginForm.do") @RequestMapping("/login/loginForm.do")
public String loginForm( public String loginForm(HttpServletRequest req, @RequestParam(required = false) String error,
HttpServletRequest req @RequestParam(required = false) String logout, Model model, HttpSession session) {
, @RequestParam(required=false) String error if (error != null) {
, @RequestParam(required=false) String logout model.addAttribute("error", String.format("ID와 비밀번호를 확인하여 주시기 바랍니다. %s", error));
, ModelMap model) {
if(error != null) {
model.addAttribute("error" , String.format("ID와 비밀번호를 확인하여 주시기 바랍니다. %s", error));
} }
if(logout != null) { if (logout != null) {
model.addAttribute("logout" , String.format("로그아웃하였습니다 %s", logout)); model.addAttribute("logout", String.format("로그아웃하였습니다 %s", logout));
} }
// 네이버 로그인 URL 생성
/* 네이버아이디로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
naverLoginBO.setRedirect_url("http://nlib.nculture.org/nlib/login/naverCallback.do");
String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
// 구글 로그인 URL 생성
String googleUrl = "https://accounts.google.com/o/oauth2/v2/auth?"
+ "client_id=879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com"
+ "&redirect_uri=http://nlib.nculture.org/nlib/login/googleCallback.do"
+ "&response_type=code"
+ "&scope=email%20profile%20openid"
+ "&access_type=offline";
// 카카오 로그인 URL 생성
String k_redirect_url="http://nlib.nculture.org/nlib/login/kakaoCallback.do";
String kakaoUrl = KakaoController.getAuthorizationUrl(session,k_redirect_url);
model.addAttribute("naverUrl", naverAuthUrl);
model.addAttribute("googleUrl", googleUrl);
model.addAttribute("kakaoUrl", kakaoUrl);
return "nlib/login/loginForm"; return "nlib/login/loginForm";
} }
// 네이버 로그인 성공시 callback호출 메소드
@RequestMapping(value = "/login/naverCallback.do", method = { RequestMethod.GET, RequestMethod.POST })
public String naverCallback(Model model, @RequestParam String code, @RequestParam String state, HttpSession session)
throws IOException, ParseException {
OAuth2AccessToken oauthToken;
oauthToken = naverLoginBO.getAccessToken(session, code, state);
// 로그인 사용자 정보를 읽어온다.
apiResult = naverLoginBO.getUserProfile(oauthToken);
JSONParser parser = new JSONParser();
Object obj = parser.parse(apiResult);
JSONObject jsonObj = (JSONObject) obj;
JSONObject response_obj = (JSONObject) jsonObj.get("response");
String email = (String) response_obj.get("email");
model.addAttribute("result", apiResult);
/* 네이버 로그인 성공 페이지 View 호출 */
return "naverSuccess";
}
// 구글 로그인 콜백
@RequestMapping(value = "/login/googleCallback.do")
public String googleCallback(@RequestParam(value = "code") String authCode, HttpSession session, Model model,
HttpServletRequest request) throws Exception {
String code = request.getParameter("code");
HttpHeaders headers = new HttpHeaders();
RestTemplate restTemplate = new RestTemplate();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("code", code);
parameters.add("client_id", "879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com");
parameters.add("client_secret", "F6T-ZV9jibLhKtcugxPUtBlN");
parameters.add("redirect_uri", "http://nlib.nculture.org/nlib/login/googleCallback.do");
parameters.add("grant_type", "authorization_code");
HttpEntity<MultiValueMap<String,String>> rest_request = new HttpEntity<>(parameters,headers);
URI uri = URI.create("https://www.googleapis.com/oauth2/v4/token");
ResponseEntity<String> resultEntity;
resultEntity = restTemplate.postForEntity(uri, rest_request, String.class);
// JSON 파싱을 위한 기본값 세팅
// 요청시 파라미터는 스네이크 케이스로 세팅되므로 Object mapper에 미리 설정해준다.
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
mapper.setSerializationInclusion(Include.NON_NULL);
// 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).toUriString();
String resultJson = restTemplate.getForObject(requestUrl, String.class);
Map<String, String> userInfo = mapper.readValue(resultJson, new TypeReference<Map<String, String>>() {
});
System.out.println(userInfo.get("email"));
model.addAttribute("token", result.getAccessToken());
return "redirect:/";
}
@RequestMapping(value = "/login/kakaoCallback.do")
public ModelAndView kakaoCallback(@RequestParam("code") String code, HttpServletRequest request, HttpServletResponse response, HttpSession session)
throws Exception {
ModelAndView mav = new ModelAndView();
// 결과값을 node에 담아줌
String k_redirect_url="http://nlib.nculture.org/nlib/login/kakaoCallback.do";
JsonNode node = KakaoController.getAccessToken(code,k_redirect_url);
// accessToken에 사용자의 로그인한 모든 정보가 들어있음
JsonNode accessToken = node.get("access_token");
// 사용자의 정보
JsonNode userInfo = KakaoController.getKakaoUserInfo(accessToken);
String kemail = null;
String kname = null;
String kgender = null;
String kbirthday = null;
String kage = null;
String kimage = null;
// 유저정보 카카오에서 가져오기Get properties
JsonNode properties = userInfo.path("properties");
JsonNode kakao_account = userInfo.path("kakao_account");
kemail = kakao_account.path("email").asText();
kname = properties.path("nickname").asText();
kimage = properties.path("profile_image").asText();
kgender = kakao_account.path("gender").asText();
kbirthday = kakao_account.path("birthday").asText();
kage = kakao_account.path("age_range").asText();
session.setAttribute("kemail", kemail);
session.setAttribute("kname", kname);
session.setAttribute("kimage", kimage);
session.setAttribute("kgender", kgender);
session.setAttribute("kbirthday", kbirthday);
session.setAttribute("kage", kage);
mav.setViewName("main");
return mav;
}// end kakaoLogin()
/** /**
* 로그인을 처리한다. * 로그인을 처리한다. (스프링 시큐리티 로그인 수행)
* (스프링 시큐리티 로그인 수행)
* *
* @param req * @param req
* @param res * @param res
@ -88,21 +239,20 @@ public class LoginController
* @return * @return
*/ */
@RequestMapping("/login/login.do") @RequestMapping("/login/login.do")
public String login( public String login(HttpServletRequest req, HttpServletResponse res,
HttpServletRequest req @RequestParam(required = false) String username, @RequestParam(required = false) String password,
, HttpServletResponse res ModelMap model) {
, @RequestParam(required=false) String username
, @RequestParam(required=false) String password
, ModelMap model) {
String redirectUrl = loginService.login(req, username, password); String redirectUrl = loginService.login(req, username, password);
// 정상적으로 로그인된 경우 // 정상적으로 로그인된 경우
if(StringUtil.isEmpty(redirectUrl)) { if (StringUtil.isEmpty(redirectUrl)) {
RequestCache cache = new HttpSessionRequestCache(); RequestCache cache = new HttpSessionRequestCache();
SavedRequest savedRequest = cache.getRequest(req, res); SavedRequest savedRequest = cache.getRequest(req, res);
if(savedRequest == null) redirectUrl = "/"; if (savedRequest == null)
else redirectUrl = savedRequest.getRedirectUrl(); redirectUrl = "/";
else
redirectUrl = savedRequest.getRedirectUrl();
} }
log.debug("login.do > RequestCache : url=" + redirectUrl); log.debug("login.do > RequestCache : url=" + redirectUrl);
@ -110,11 +260,8 @@ public class LoginController
return "redirect:" + redirectUrl; return "redirect:" + redirectUrl;
} }
/** /**
* 로그아웃 후의 처리를 담당한다. * 로그아웃 후의 처리를 담당한다. 스프링 시큐리티에서 로그아웃이 수행된 , 호출된다.
* 스프링 시큐리티에서 로그아웃이 수행된 , 호출된다.
* *
* @param req * @param req
* @return * @return
@ -123,16 +270,4 @@ public class LoginController
public String logout(HttpServletRequest req) { public String logout(HttpServletRequest req) {
return null; return null;
} }
/**
* 네이버 로그인
* @param session
* @return
* @throws Exception
*/
@RequestMapping(value="/login/naverLoginResultPopup.do")
public String naverLoginResult(HttpSession session) throws Exception{
return "nlib/popup/naverLoginResultPopup";
}
} }

View File

@ -2,6 +2,7 @@
package nlib.user.web; package nlib.user.web;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
@ -10,6 +11,7 @@ import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -17,14 +19,40 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.util.UriComponentsBuilder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.github.scribejava.core.model.OAuth2AccessToken;
import nlib.cmm.snslogin.GoogleOAuthResponse;
import nlib.cmm.snslogin.KakaoController;
import nlib.cmm.snslogin.NaverLoginBO;
import nlib.info.service.InformService; import nlib.info.service.InformService;
import nlib.restful.service.DataApiReqVO; import nlib.restful.service.DataApiReqVO;
import nlib.restful.service.DataApiResVO; import nlib.restful.service.DataApiResVO;
@ -53,6 +81,7 @@ import nlib.user.service.NlibLoginVO;
* @version 1.0 * @version 1.0
* *
*/ */
@Controller @Controller
public class MemberController { public class MemberController {
@Resource(name="memberService") @Resource(name="memberService")
@ -61,6 +90,15 @@ public class MemberController {
@Resource(name="informService") @Resource(name="informService")
private InformService informService; private InformService informService;
/* NaverLoginBO */
private NaverLoginBO naverLoginBO;
private String apiResult = null;
@Autowired
private void setNaverLoginBO(NaverLoginBO naverLoginBO) {
this.naverLoginBO = naverLoginBO;
}
/* 이메일 메시지 및 템플릿 정보 */ /* 이메일 메시지 및 템플릿 정보 */
//템플릿 파일경로 //템플릿 파일경로
@Value("#{properties['mailing.sender.membership.template']}") @Value("#{properties['mailing.sender.membership.template']}")
@ -74,34 +112,12 @@ public class MemberController {
@Value("#{properties['mailing.sender.membership.name']}") @Value("#{properties['mailing.sender.membership.name']}")
private String senderName; private String senderName;
public ModelMap selectMemberJoiningInfo(HttpServletRequest req) {
return null;
}
public ModelMap certificateMember(HttpServletRequest req) { public ModelMap certificateMember(HttpServletRequest req) {
return null; return null;
} }
public ModelMap insertMemberInfo(HttpServletRequest req) {
return null;
}
public ModelMap sendEmailForMemberJoining(HttpServletRequest req) { public ModelMap sendEmailForMemberJoining(HttpServletRequest req) {
return null; return null;
} }
public ModelMap searchIdForm(HttpServletRequest req) {
return null;
}
public ModelMap searchId(HttpServletRequest req) {
return null;
}
public ModelMap initPassword(HttpServletRequest req) {
return null;
}
public ModelMap changePassword(HttpServletRequest req) { public ModelMap changePassword(HttpServletRequest req) {
return null; return null;
} }
@ -122,28 +138,46 @@ public class MemberController {
return null; return null;
} }
@RequestMapping(value="/member/naverSignResultPopup.do")
public String naverSignResult(HttpSession session) throws Exception{
return "nlib/popup/naverSignResultPopup";
}
@RequestMapping(value="/member/selectMemberJoiningInfo.do") @RequestMapping(value="/member/selectMemberJoiningInfo.do")
public String selectMemberJoiningInfo(HttpServletRequest req,ModelMap model) { public String selectMemberJoiningInfo(HttpServletRequest req,ModelMap model) {
DataApiReqVO reqVO = new DataApiReqVO();
DataApiResVO resVO = new DataApiResVO();
resVO = informService.selectTermsInfo(reqVO);
System.out.println(resVO.getInfo().get("terms"));
model.addAttribute("result",resVO);
return "/nlib/member/selectMemberJoiningInfo"; return "/nlib/member/selectMemberJoiningInfo";
} }
@RequestMapping(value="/member/snsCertForm.do") @RequestMapping(value="/member/snsCertForm.do")
public String snsCertForm(HttpSession session) throws Exception{ public String snsCertForm(HttpSession session, Model model) throws Exception{
// 네이버 로그인 URL 생성
/* 네이버아이디로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
naverLoginBO.setRedirect_url("http://nlib.nculture.org/nlib/member/naverCallback.do");
String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
// 구글 로그인 URL 생성
String googleUrl = "https://accounts.google.com/o/oauth2/v2/auth?"
+ "client_id=879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com"
+ "&redirect_uri=http://nlib.nculture.org/nlib/member/googleCallback.do"
+ "&response_type=code"
+ "&scope=email%20profile%20openid"
+ "&access_type=offline";
// 카카오 로그인 URL 생성
String k_redirect_url="http://nlib.nculture.org/nlib/member/kakaoCallback.do";
String kakaoUrl = KakaoController.getAuthorizationUrl(session,k_redirect_url);
model.addAttribute("naverUrl", naverAuthUrl);
model.addAttribute("googleUrl", googleUrl);
model.addAttribute("kakaoUrl", kakaoUrl);
return "nlib/member/snsCertForm"; return "nlib/member/snsCertForm";
} }
@RequestMapping(value="/member/insertMemberInfoForm.do") @RequestMapping(value="/member/insertMemberInfoForm.do")
public String insertMemberInfoForm(NlibLoginVO vo,HttpSession session,ModelMap model ) throws Exception{ public String insertMemberInfoForm(HttpServletRequest request,NlibLoginVO vo,HttpSession session,ModelMap model ) throws Exception{
Map<String, ?> flashMap =RequestContextUtils.getInputFlashMap(request);
if(flashMap != null)
{
vo.setId(String.valueOf(flashMap.get("email")));
}else {
return "forward:/member/selectMemberJoiningInfo.do";
}
model.addAttribute("loginVO",vo); model.addAttribute("loginVO",vo);
return "nlib/member/insertMemberInfoForm"; return "nlib/member/insertMemberInfoForm";
} }
@ -286,4 +320,127 @@ public class MemberController {
System.out.println(request.getAttribute("initPasswordPhoneNum")); System.out.println(request.getAttribute("initPasswordPhoneNum"));
return "nlib/member/initPassword"; return "nlib/member/initPassword";
} }
/**
* 회원가입 SNS 네이버인증
* @param model
* @param code
* @param state
* @param session
* @return
* @throws IOException
* @throws ParseException
*/
@RequestMapping(value = "/member/naverCallback.do", method = { RequestMethod.GET, RequestMethod.POST })
public String naverCallback(Model model, @RequestParam String code, @RequestParam String state, HttpSession session,RedirectAttributes rttr)
throws IOException, ParseException {
OAuth2AccessToken oauthToken;
oauthToken = naverLoginBO.getAccessToken(session, code, state);
// 로그인 사용자 정보를 읽어온다.
apiResult = naverLoginBO.getUserProfile(oauthToken);
JSONParser parser = new JSONParser();
Object obj = parser.parse(apiResult);
JSONObject jsonObj = (JSONObject) obj;
JSONObject response_obj = (JSONObject) jsonObj.get("response");
String email = (String) response_obj.get("email");
rttr.addFlashAttribute("email",email);
/* 네이버 로그인 성공 페이지 View 호출 */
return "redirect:/member/insertMemberInfoForm.do";
}
/**
* 회원가입 SNS 구글인증
* @exception Exception
*/
@RequestMapping(value = "/member/googleCallback.do")
public String googleCallback(@RequestParam(value = "code") String authCode, HttpSession session, Model model,
HttpServletRequest request,RedirectAttributes rttr) throws Exception {
String code = request.getParameter("code");
HttpHeaders headers = new HttpHeaders();
RestTemplate restTemplate = new RestTemplate();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
parameters.add("code", code);
parameters.add("client_id", "879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com");
parameters.add("client_secret", "F6T-ZV9jibLhKtcugxPUtBlN");
parameters.add("redirect_uri", "http://nlib.nculture.org/nlib/member/googleCallback.do");
parameters.add("grant_type", "authorization_code");
HttpEntity<MultiValueMap<String,String>> rest_request = new HttpEntity<>(parameters,headers);
URI uri = URI.create("https://www.googleapis.com/oauth2/v4/token");
ResponseEntity<String> resultEntity;
resultEntity = restTemplate.postForEntity(uri, rest_request, String.class);
// JSON 파싱을 위한 기본값 세팅
// 요청시 파라미터는 스네이크 케이스로 세팅되므로 Object mapper에 미리 설정해준다.
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
mapper.setSerializationInclusion(Include.NON_NULL);
// 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).toUriString();
String resultJson = restTemplate.getForObject(requestUrl, String.class);
Map<String, String> userInfo = mapper.readValue(resultJson, new TypeReference<Map<String, String>>() {
});
rttr.addFlashAttribute("email",userInfo.get("email"));
return "redirect:/member/insertMemberInfoForm.do";
}
/**
* 회원가입 SNS 카카오인증
* @param code
* @param request
* @param response
* @param session
* @return
* @throws Exception
*/
@RequestMapping(value = "/member/kakaoCallback.do")
public String kakaoCallback(@RequestParam("code") String code, HttpServletRequest request, HttpServletResponse response, HttpSession session
,RedirectAttributes rttr)
throws Exception {
ModelAndView mav = new ModelAndView();
// 결과값을 node에 담아줌
String k_redirect_url="http://nlib.nculture.org/nlib/member/kakaoCallback.do";
JsonNode node = KakaoController.getAccessToken(code,k_redirect_url);
// accessToken에 사용자의 로그인한 모든 정보가 들어있음
JsonNode accessToken = node.get("access_token");
// 사용자의 정보
JsonNode userInfo = KakaoController.getKakaoUserInfo(accessToken);
String kemail = null;
String kname = null;
String kgender = null;
String kbirthday = null;
String kage = null;
String kimage = null;
// 유저정보 카카오에서 가져오기Get properties
JsonNode properties = userInfo.path("properties");
JsonNode kakao_account = userInfo.path("kakao_account");
kemail = kakao_account.path("email").asText();
kname = properties.path("nickname").asText();
kimage = properties.path("profile_image").asText();
kgender = kakao_account.path("gender").asText();
kbirthday = kakao_account.path("birthday").asText();
kage = kakao_account.path("age_range").asText();
session.setAttribute("kemail", kemail);
session.setAttribute("kname", kname);
session.setAttribute("kimage", kimage);
session.setAttribute("kgender", kgender);
session.setAttribute("kbirthday", kbirthday);
session.setAttribute("kage", kage);
mav.setViewName("main");
rttr.addFlashAttribute("email",kemail);
return "redirect:/member/insertMemberInfoForm.do";
}// end kakaoLogin()
} }

View File

@ -65,6 +65,7 @@
<bean id="antPathMater" class="org.springframework.util.AntPathMatcher" /> <bean id="antPathMater" class="org.springframework.util.AntPathMatcher" />
<bean id="defaultTraceHandler" class="egovframework.rte.fdl.cmmn.trace.handler.DefaultTraceHandler" /> <bean id="defaultTraceHandler" class="egovframework.rte.fdl.cmmn.trace.handler.DefaultTraceHandler" />
<bean id="naverLoginBO" class="nlib.cmm.snslogin.NaverLoginBO" />
<!-- MULTIPART RESOLVERS --> <!-- MULTIPART RESOLVERS -->
<!-- regular spring resolver --> <!-- regular spring resolver -->

View File

@ -34,20 +34,11 @@
<html> <html>
<head> <head>
<title>LoginTest</title> <title>LoginTest</title>
<meta name ="google-signin-client_id" content="879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com">
<script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.2.js" charset="utf-8"></script>
<script src = "//developers.kakao.com/sdk/js/kakao.min.js"></script> <script src = "//developers.kakao.com/sdk/js/kakao.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css"> <script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.2.js" charset="utf-8"></script>
<script src="https://apis.google.com/js/api:client.js"></script> <script src="https://apis.google.com/js/api:client.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script> <script>
window.snsLogin = function(email){
$("#username").val(email);
$("#password").val("password");
var f=document.loginForm;
f.action="/nlib/login/login.do";
f.submit();
}
function signUp(){ function signUp(){
location.href="/nlib/member/selectMemberJoiningInfo.do"; location.href="/nlib/member/selectMemberJoiningInfo.do";
} }
@ -55,148 +46,19 @@
location.href="/nlib/member/searchIdForm.do"; location.href="/nlib/member/searchIdForm.do";
} }
</script> </script>
<style type="text/css">
#GgCustomLogin {
display: inline-block;
background: white;
color: #444;
width: 222px;
height: 49px;
border-radius: 5px;
border: thin solid #888;
box-shadow: 1px 1px 1px grey;
white-space: nowrap;
}
#GgCustomLogin {
cursor: pointer;
}
span.label {
font-family: serif;
font-weight: normal;
}
span.icon {
background: url('/nlib/images/nlib/sign-in/g-normal.png') transparent 5px 50% no-repeat;
display: inline-block;
vertical-align: middle;
width: 42px;
height: 42px;
}
span.buttonText {
display: inline-block;
vertical-align: middle;
padding-left: 10px;
padding-right: 42px;
font-size: 14px;
width:140px;
font-weight: bold;
/* Use the Roboto font that is loaded in the <head> */
font-family: 'Roboto', sans-serif;
}
</style>
</head> </head>
<body> <body>
<form id="loginForm" name="loginForm" method="post"> <br>
<input type="hidden" id="username" name="username"> <!-- 네이버 로그인 화면으로 이동 시키는 URL -->
<input type="hidden" id="password" name="password"> <!-- 네이버 로그인 화면에서 ID, PW를 올바르게 입력하면 callback 메소드 실행 요청 -->
<div id="naver_id_login" style="text-align:center"><a href="${naverUrl}" ><img width="223" src="${pageContext.request.contextPath}/images/nlib/sns/naver_login_btn.png"/></a></div>
<div id = "naver_id_login"></div> <div id="googleLogin" style="text-align:center"><a href="${googleUrl}" ><img width="223" src="${pageContext.request.contextPath}/images/nlib/sns/google_login_btn.png"/></a></div>
<div id="kakao_id_login" style="text-align: center"> <a href="${kakaoUrl}" > <img width="223" src="${pageContext.request.contextPath}/images/nlib/sns/kakao_login_btn.png" /></a> </div>
<a id="kakao-login-btn"></a> <br>
<a href="http://developers.kakao.com/logout"></a> <div style="text-align:center">
<ul> <input type="button" onclick="signUp();" value="회원가입">
<div id="GgCustomLogin"> <input type="button" onclick="findInfo();" value="ID|비밀번호찾기">
<a href="javascript:void(0)"> </div>
<span class="icon"></span>
<span class="buttonText">구글아이디로 로그인</span>
</a>
</div>
</ul>
<input type="button" onclick="signUp();" value="회원가입">
<input type="button" onclick="findInfo();" value="ID|비밀번호찾기">
<input type="hidden" name="authKey" id="authKey" value="yjhOJW0gKZ13f0/mofcEeA==" /> <br />
<input type="hidden" name="page" id="page" value="1" /> <br />
<input type="hidden" name="rows" id="rows" value="10" /> <br />
<input type="hidden" id="email" name="email" value="" />
</form>
<script type="text/javascript">
//----------네이버--------------
var naver_id_login = new naver_id_login("jefkoYhSfrQ3TtZz5mTp", "http://www.example.com/nlib/login/naverLoginResultPopup.do"); // Client ID, CallBack URL 삽입
// 단 'localhost'가 포함된 CallBack URL
var state = naver_id_login.getUniqState();
naver_id_login.setButton("green", 6, 48);
naver_id_login.setDomain("http://www.example.com/nlib/login/loginForm.do"); // URL
naver_id_login.setState(state);
naver_id_login.setPopup();
naver_id_login.init_naver_id_login();
//----------네이버--------------
//----------카카오--------------
Kakao.init('c449bf78ccf8dc336e43694099a1f4da'); //아까 카카오개발자홈페이지에서 발급받은 자바스크립트 키를 입력함
//카카오 로그인 버튼을 생성합니다.
Kakao.Auth.createLoginButton({
container: '#kakao-login-btn',
success: function(authObj) {
Kakao.API.request({
url: '/v2/user/me',
success: function(res) {
//onsole.log(res.id);//<---- 콘솔 로그에 id 정보 출력(id는 res안에 있기 때문에 res.id 로 불러온다)
//console.log(res.kakao_account.email);//<---- 콘솔 로그에 email 정보 출력 (어딨는지 알겠죠?)
//console.log(authObj.access_token);//<---- 콘솔 로그에 토큰값 출력
//로그인으로 타야함
snsLogin(res.kakao_account.email);
}
})
},
fail: function(error) {
alert(JSON.stringify(error));
}
});
//----------카카오--------------
//----------구글---------------
//처음 실행하는 함수
function init() {
gapi.load('auth2', function() {
gapi.auth2.init();
options = new gapi.auth2.SigninOptionsBuilder();
options.setPrompt('select_account');
// 추가는 Oauth 승인 권한 추가 후 띄어쓰기 기준으로 추가
options.setScope('email profile openid https://www.googleapis.com/auth/user.birthday.read');
// 인스턴스의 함수 호출 - element에 로그인 기능 추가
// GgCustomLogin은 li태그안에 있는 ID, 위에 설정한 options와 아래 성공,실패시 실행하는 함수들
gapi.auth2.getAuthInstance().attachClickHandler('GgCustomLogin', options, onSignIn, onSignInFailure);
});
}
function onSignIn(googleUser) {
var access_token = googleUser.getAuthResponse().access_token
$.ajax({
// people api를 이용하여 프로필 및 생년월일에 대한 선택동의후 가져온다.
url: 'https://people.googleapis.com/v1/people/me'
// key에 자신의 API 키를 넣습니다.
, data: {personFields:'emailAddresses', key:'AIzaSyCmVKytZ2Ea6x1Em-iXPkah29LSq6ELH1M', 'access_token': access_token}
, method:'GET'
})
.done(function(e){
//프로필을 가져온다.
//snsLogin(profile.pu);
snsLogin(e.emailAddresses[0].value);
})
.fail(function(e){
console.log(e);
})
}
function onSignInFailure(t){
console.log(t);
}
</script>
<script src="https://apis.google.com/js/platform.js?onload=init" async defer></script> <script src="https://apis.google.com/js/platform.js?onload=init" async defer></script>
</body> </body>
</html> </html>

View File

@ -56,166 +56,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
<head> <head>
<title>LoginTest</title>
<meta name ="google-signin-client_id" content="879126511006-jro7bld7b2epl3n5mkksp0p24k2inbpu.apps.googleusercontent.com">
<script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.2.js" charset="utf-8"></script> <script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.2.js" charset="utf-8"></script>
<script src = "//developers.kakao.com/sdk/js/kakao.min.js"></script> <script src = "//developers.kakao.com/sdk/js/kakao.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css">
<script src="https://apis.google.com/js/api:client.js"></script> <script src="https://apis.google.com/js/api:client.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
window.snsLogin = function(){
var f=document.loginForm;
f.action="<c:url value='/member/insertMemberInfoForm.do'/>";
f.submit();
}
</script>
<style type="text/css">
#GgCustomLogin {
display: inline-block;
background: white;
color: #444;
width: 222px;
height: 49px;
border-radius: 5px;
border: thin solid #888;
box-shadow: 1px 1px 1px grey;
white-space: nowrap;
}
#GgCustomLogin {
cursor: pointer;
}
span.label {
font-family: serif;
font-weight: normal;
}
span.icon {
background: url('/nlib/images/nlib/sign-in/g-normal.png') transparent 5px 50% no-repeat;
display: inline-block;
vertical-align: middle;
width: 42px;
height: 42px;
}
span.buttonText {
display: inline-block;
vertical-align: middle;
padding-left: 10px;
padding-right: 42px;
font-size: 14px;
width:140px;
font-weight: bold;
/* Use the Roboto font that is loaded in the <head> */
font-family: 'Roboto', sans-serif;
}
</style>
</head> </head>
<body> <body>
SNS 인증<br> SNS 인증
<form id="infoForm" name="loginForm" method="post"> <br>
<div> <input type="hidden" id="id" name="id"> <div id="naver_id_login" style="text-align:center"><a href="${naverUrl}" ><img width="223" src="${pageContext.request.contextPath}/images/nlib/sns/naver_login_btn.png"/></a></div>
<input type="hidden" id="name" name="name"> <div id="googleLogin" style="text-align:center"><a href="${googleUrl}" ><img width="223" src="${pageContext.request.contextPath}/images/nlib/sns/google_login_btn.png"/></a></div>
<input type="hidden" id="birth_yy" name="birth_yy"> <div id="kakao_id_login" style="text-align: center"> <a href="${kakaoUrl}" > <img width="223" src="${pageContext.request.contextPath}/images/nlib/sns/kakao_login_btn.png" /></a> </div>
<input type="hidden" id="birth_mm" name="birth_mm"> <br>
<input type="hidden" id="birth_dd" name="birth_dd">
<input type="hidden" id="phone" name="phone">
</div>
<div id = "naver_id_login"></div>
<a id="kakao-login-btn"></a>
<a href="http://developers.kakao.com/logout"></a>
<ul>
<div id="GgCustomLogin">
<a href="javascript:void(0)">
<span class="icon"></span>
<span class="buttonText">구글아이디로 로그인</span>
</a>
</div>
</ul>
</form>
<script type="text/javascript">
//----------네이버--------------
var naver_id_login = new naver_id_login("jefkoYhSfrQ3TtZz5mTp", "http://www.example.com/nlib/member/naverSignResultPopup.do"); // Client ID, CallBack URL 삽입
// 단 'localhost'가 포함된 CallBack URL
var state = naver_id_login.getUniqState();
naver_id_login.setButton("green", 6, 48);
naver_id_login.setDomain("http://www.example.com/nlib/member/snsCertForm.do"); // URL
naver_id_login.setState(state);
naver_id_login.setPopup();
naver_id_login.init_naver_id_login();
//----------네이버--------------
//----------카카오--------------
Kakao.init('c449bf78ccf8dc336e43694099a1f4da'); //아까 카카오개발자홈페이지에서 발급받은 자바스크립트 키를 입력함
//카카오 로그인 버튼을 생성합니다.
Kakao.Auth.createLoginButton({
container: '#kakao-login-btn',
success: function(authObj) {
Kakao.API.request({
url: '/v2/user/me',
success: function(res) {
//onsole.log(res.id);//<---- 콘솔 로그에 id 정보 출력(id는 res안에 있기 때문에 res.id 로 불러온다)
//console.log(res.kakao_account.email);//<---- 콘솔 로그에 email 정보 출력 (어딨는지 알겠죠?)
//console.log(authObj.access_token);//<---- 콘솔 로그에 토큰값 출력
//로그인으로 타야함
$("#id").val(res.kakao_account.email);
snsLogin();
}
})
},
fail: function(error) {
alert(JSON.stringify(error));
}
});
//----------카카오--------------
//----------구글---------------
//처음 실행하는 함수
function init() {
gapi.load('auth2', function() {
gapi.auth2.init();
options = new gapi.auth2.SigninOptionsBuilder();
options.setPrompt('select_account');
// 추가는 Oauth 승인 권한 추가 후 띄어쓰기 기준으로 추가
options.setScope('email profile openid https://www.googleapis.com/auth/user.birthday.read');
// 인스턴스의 함수 호출 - element에 로그인 기능 추가
// GgCustomLogin은 li태그안에 있는 ID, 위에 설정한 options와 아래 성공,실패시 실행하는 함수들
gapi.auth2.getAuthInstance().attachClickHandler('GgCustomLogin', options, onSignIn, onSignInFailure);
})
}
function onSignIn(googleUser) {
var access_token = googleUser.getAuthResponse().access_token
$.ajax({
// people api를 이용하여 프로필 및 생년월일에 대한 선택동의후 가져온다.
url: 'https://people.googleapis.com/v1/people/me'
// key에 자신의 API 키를 넣습니다.phoneNumbers birthdays names
, data: {personFields:'emailAddresses,birthdays,names,phoneNumbers', key:'AIzaSyCmVKytZ2Ea6x1Em-iXPkah29LSq6ELH1M', 'access_token': access_token}
, method:'GET'
})
.done(function(e){
//프로필을 가져온다.
$("#id").val(e.emailAddresses[0].value);
$("#name").val(e.names[0].displayName);
$("#birth_yy").val(e.birthdays[1].date.year);
$("#birth_mm").val(e.birthdays[1].date.month);
$("#birth_dd").val(e.birthdays[1].date.day);
snsLogin();
})
.fail(function(e){
console.log(e);
})
}
function onSignInFailure(t){
console.log(t);
}
</script>
<script src="https://apis.google.com/js/platform.js?onload=init" async defer></script>
</body> </body>
</html> </html>

View File

@ -1,50 +0,0 @@
<%
/**
* <pre>
* @Class Name : naverLoginResultPopup.jsp
*
* @Description : 로그인시 naver로그인 페이지
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 12. JSYOO 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP JSYOO
* @since 2021. 7. 12.
* @version 1.0
*
*/
%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!doctype html>
<html lang="ko">
<head>
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript"
src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.2.js"
charset="utf-8"></script>
</head>
<script type="text/javascript">
var naver_id_login = new naver_id_login("jefkoYhSfrQ3TtZz5mTp", "http://www.example.com/nlib/login/naverLoginResultPopup.do"); // 역시 마찬가지로 'localhost'가 포함된 CallBack URL
// 네이버 사용자 프로필 조회
naver_id_login.get_naver_userprofile("naverSignInCallback()");
// 네이버 사용자 프로필 조회 이후 프로필 정보를 처리할 callback function
function naverSignInCallback() {
opener.snsLogin(naver_id_login.getProfileData('email'));
self.close();
}
</script>
</html>

View File

@ -1,56 +0,0 @@
<%
/**
* <pre>
* @Class Name : naverSignResultPopup.jsp
*
* @Description : 회원가입시 naver로그인 페이지
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 12. JSYOO 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP JSYOO
* @since 2021. 7. 12.
* @version 1.0
*
*/
%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!doctype html>
<html lang="ko">
<head>
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript"
src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.2.js"
charset="utf-8"></script>
</head>
<script type="text/javascript">
var naver_id_login = new naver_id_login("jefkoYhSfrQ3TtZz5mTp", "http://www.example.com/login/naverSignResultPopup.do"); // 역시 마찬가지로 'localhost'가 포함된 CallBack URL
// 네이버 사용자 프로필 조회
naver_id_login.get_naver_userprofile("naverSignInCallback()");
// 네이버 사용자 프로필 조회 이후 프로필 정보를 처리할 callback function
function naverSignInCallback() {
$("#id",opener.document).val(naver_id_login.getProfileData('email'));
$("#name",opener.document).val(naver_id_login.getProfileData('name'));
$("#birth_yy",opener.document).val(naver_id_login.getProfileData('birthyear'));
$("#birth_mm",opener.document).val(naver_id_login.getProfileData('birthday').substring(0,2).replace(/(^0+)/, ""));
$("#birth_dd",opener.document).val(naver_id_login.getProfileData('birthday').substring(3,5).replace(/(^0+)/, ""));
$("#phone",opener.document).val(naver_id_login.getProfileData('mobile'));
opener.snsLogin();
self.close();
}
</script>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB