Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
5a7fd69462
24
pom.xml
24
pom.xml
@ -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>
|
||||||
|
|||||||
90
src/main/java/nlib/cmm/snslogin/GoogleOAuthRequest.java
Normal file
90
src/main/java/nlib/cmm/snslogin/GoogleOAuthRequest.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
49
src/main/java/nlib/cmm/snslogin/GoogleOAuthResponse.java
Normal file
49
src/main/java/nlib/cmm/snslogin/GoogleOAuthResponse.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
81
src/main/java/nlib/cmm/snslogin/KakaoController.java
Normal file
81
src/main/java/nlib/cmm/snslogin/KakaoController.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/main/java/nlib/cmm/snslogin/NaverLoginApi.java
Normal file
29
src/main/java/nlib/cmm/snslogin/NaverLoginApi.java
Normal 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
102
src/main/java/nlib/cmm/snslogin/NaverLoginBO.java
Normal file
102
src/main/java/nlib/cmm/snslogin/NaverLoginBO.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
* @Class Name : LoginController.java
|
||||||
*
|
*
|
||||||
* @Description : 스프링 시큐리티를 이용한 로그인 처리 컨트롤러
|
* @Description : 스프링 시큐리티를 이용한 로그인 처리 컨트롤러
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
|
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (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
|
|
||||||
, @RequestParam(required=false) String logout
|
|
||||||
, ModelMap model) {
|
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
model.addAttribute("error", String.format("ID와 비밀번호를 확인하여 주시기 바랍니다. %s", error));
|
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,12 +239,9 @@ 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);
|
||||||
|
|
||||||
@ -101,8 +249,10 @@ public class LoginController
|
|||||||
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";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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()
|
||||||
}
|
}
|
||||||
@ -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 -->
|
||||||
|
|||||||
@ -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>
|
|
||||||
<div id="GgCustomLogin">
|
|
||||||
<a href="javascript:void(0)">
|
|
||||||
<span class="icon"></span>
|
|
||||||
<span class="buttonText">구글아이디로 로그인</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</ul>
|
|
||||||
<input type="button" onclick="signUp();" value="회원가입">
|
<input type="button" onclick="signUp();" value="회원가입">
|
||||||
<input type="button" onclick="findInfo();" value="ID|비밀번호찾기">
|
<input type="button" onclick="findInfo();" value="ID|비밀번호찾기">
|
||||||
<input type="hidden" name="authKey" id="authKey" value="yjhOJW0gKZ13f0/mofcEeA==" /> <br />
|
</div>
|
||||||
<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>
|
||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
|
||||||
@ -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 |
BIN
src/main/webapp/images/nlib/sns/google_login_btn.png
Normal file
BIN
src/main/webapp/images/nlib/sns/google_login_btn.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
BIN
src/main/webapp/images/nlib/sns/kakao_login_btn.png
Normal file
BIN
src/main/webapp/images/nlib/sns/kakao_login_btn.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
BIN
src/main/webapp/images/nlib/sns/naver_login_btn.png
Normal file
BIN
src/main/webapp/images/nlib/sns/naver_login_btn.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Loading…
Reference in New Issue
Block a user