Переглянути джерело

아이디 찾기 개발 중

jsshin 5 роки тому
батько
коміт
134bbb08a3

+ 210 - 0
src/main/java/com/style24/front/biz/thirdparty/KaKaoLogin.java

@@ -0,0 +1,210 @@
+package com.style24.front.biz.thirdparty;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.style24.front.support.security.session.TsfSession;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.PostConstruct;
+import java.net.URI;
+
+
+/**
+ * 카카오 로그인
+ *
+ * @author jsshin
+ * @since 2021. 02. 05
+ */
+@Component
+@Slf4j
+public class KaKaoLogin {
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private RestTemplate restTemplate;
+
+	private String callBackUrl;
+	private String restApiKey;
+	private String profiles;
+	private String tokenUrl;
+	private String userInfoUrl;
+	private String authorizeUrl;
+	private String unlinkUrl;
+
+	@PostConstruct
+	public void init() {
+		callBackUrl = env.getProperty("kakao.login.callbackUrl");
+		restApiKey = env.getProperty("kakao.restApiKey");
+		profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		tokenUrl = env.getProperty("kakao.tokenUrl");
+		userInfoUrl = env.getProperty("kakao.userInfoUrl");
+		authorizeUrl = env.getProperty("kakao.authorizeUrl");
+		unlinkUrl = env.getProperty("kakao.unlinkUrl");
+
+		log.info("\n\n---- Kakao initialization started ----");
+		log.info("callBackUrl: [{}]", callBackUrl);
+		log.info("restApiKey: [{}]", restApiKey);
+		log.info("profiles: [{}]", profiles);
+		log.info("tokenUrl: [{}]", tokenUrl);
+		log.info("userInfoUrl: [{}]", userInfoUrl);
+		log.info("authorizeUrl: [{}]", authorizeUrl);
+		log.info("\n--- Kakao initialization completed ----\n");
+	}
+
+	public String getAuthorizeUrl(String state) {
+		String apiUrl = authorizeUrl;
+		String redirectUri = GagaFileUtil.getConcatenationPath("https://" + TsfSession.getHttpServletRequest().getServerName(), callBackUrl);
+		apiUrl += "?client_id=" + restApiKey + "&redirect_uri=" + redirectUri + "&response_type=code&state=" + state;
+		log.info("api ===> {}", apiUrl);
+		return apiUrl;
+	}
+
+	public GagaMap getAccessTocken(String code, String state) {
+		GagaMap resultMap = new GagaMap();
+		String redirectUri = GagaFileUtil.getConcatenationPath("https://" + TsfSession.getHttpServletRequest().getServerName(), callBackUrl);
+		String requestGb = "";
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+			params.add("grant_type", "authorization_code");
+			params.add("client_id", restApiKey);
+			params.add("redirect_uri", redirectUri);
+			params.add("code", code);
+			params.add("state", state);
+
+			// state 값에 리다이렉트 url 같이 넘겨줌
+			if (StringUtils.isNotBlank(state)) {
+				String[] stateArr = StringUtils.split(state, "!@!");
+				   requestGb = stateArr[1];
+			}
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
+			URI url = URI.create(tokenUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+
+			resultMap.setString("access_token", obj.get("access_token").toString());
+			resultMap.setString("refresh_token", obj.get("refresh_token").toString());
+			resultMap.setString("requestGb", requestGb);
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+	public GagaMap getKakaoUserInfo(String accessToken) {
+		GagaMap resultMap = new GagaMap();
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.set("Authorization", "Bearer " + accessToken);
+			headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(params, headers);
+			URI url = URI.create(userInfoUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+
+			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("responseEntity.getBody(): {} ", jsonResult);
+
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+			JsonObject properties = obj.get("properties").getAsJsonObject();
+
+			resultMap.setString("id", obj.get("id").toString());
+			resultMap.setString("name", properties.get("nickname").toString());
+
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+	public GagaMap getRefreshTocken(String refreshToken) {
+		GagaMap resultMap = new GagaMap();
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+			params.add("grant_type", "refresh_token");
+			params.add("client_id", restApiKey);
+			params.add("refresh_token", refreshToken);
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
+			URI url = URI.create(tokenUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+			resultMap.setString("access_token", obj.get("access_token").toString());
+
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+	public GagaMap saveUnlink(String accessToken) {
+		GagaMap resultMap = new GagaMap();
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.set("Authorization", "Bearer " + accessToken);
+			headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
+			URI url = URI.create(unlinkUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+			log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+			resultMap.setString("id", obj.get("id").toString());
+
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+}

+ 222 - 0
src/main/java/com/style24/front/biz/thirdparty/NaverLogin.java

@@ -0,0 +1,222 @@
+package com.style24.front.biz.thirdparty;
+
+import java.net.URI;
+
+import javax.annotation.PostConstruct;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.style24.front.support.security.session.TsfSession;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaFileUtil;
+
+
+/**
+ * 네이버 로그인
+ *
+ * @author jsshin
+ * @since 2021. 02. 05
+ */
+@Component
+@Slf4j
+public class NaverLogin {
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private RestTemplate restTemplate;
+
+	private String callBackUrl;
+	private String clientId;
+	private String clientSecret;
+	private String profiles;
+	private String tokenUrl;
+	private String userInfoUrl;
+	private String authorizeUrl;
+
+	@PostConstruct
+	public void init() {
+		callBackUrl = env.getProperty("naver.login.callbackUrl");
+		clientId = env.getProperty("naver.clientId");
+		clientSecret = env.getProperty("naver.clientSecret");
+		profiles = env.getProperty("spring.profiles.active").toLowerCase();
+		tokenUrl = env.getProperty("naver.tokenUrl");
+		userInfoUrl = env.getProperty("naver.userInfoUrl");
+		authorizeUrl = env.getProperty("naver.authorizeUrl");
+
+		log.debug("\n\n---- Naver initialization started ----");
+		log.debug("callBackUrl: [{}]", callBackUrl);
+		log.debug("clientId: [{}]", clientId);
+		log.debug("clientSecret: [{}]", clientSecret);
+		log.debug("profiles: [{}]", profiles);
+		log.debug("tokenUrl: [{}]", tokenUrl);
+		log.debug("userInfoUrl: [{}]", userInfoUrl);
+		log.debug("authorizeUrl: [{}]", authorizeUrl);
+		log.debug("\n--- Naver initialization completed ----\n");
+	}
+
+	public String getAuthorizeUrl(String state) {
+		String apiUrl = authorizeUrl;
+		String redirectUri = GagaFileUtil.getConcatenationPath("https://" + TsfSession.getHttpServletRequest().getServerName(), callBackUrl);
+		apiUrl += "?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&state=" + state;
+		log.info("api ===> {}", apiUrl);
+		return apiUrl;
+	}
+
+	public GagaMap getAccessTocken(String code, String state) {
+		GagaMap resultMap = new GagaMap();
+		String requestGb = "";
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+			params.add("grant_type", "authorization_code");
+			params.add("client_id", clientId);
+			params.add("client_secret", clientSecret);
+			params.add("code", code);
+			params.add("state", state);
+
+			// state 값에 리다이렉트 url 같이 넘겨줌
+			if (StringUtils.isNotBlank(state)) {
+				String[] stateArr = StringUtils.split(state, "!@!");
+				requestGb = stateArr[1];
+			}
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
+			URI url = URI.create(tokenUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+			log.info("getAccessTocken responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("getAccessTocken responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+
+			resultMap.setString("access_token", obj.get("access_token").toString());
+			resultMap.setString("refresh_token", obj.get("refresh_token").toString());
+			resultMap.setString("requestGb", requestGb);
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+	public GagaMap getNaverUserInfo(String accessToken) {
+		GagaMap resultMap = new GagaMap();
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.set("Authorization", "Bearer " + accessToken);
+			headers.add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(params, headers);
+			URI url = URI.create(userInfoUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+
+			log.info("getNaverUserInfo responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("getNaverUserInfo responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+			JsonObject response = obj.get("response").getAsJsonObject();
+
+			resultMap.setString("id", response.get("id").toString());
+			resultMap.setString("email", response.get("email").toString());
+
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+	public GagaMap getRefreshTocken(String refreshToken) {
+		GagaMap resultMap = new GagaMap();
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+			params.add("grant_type", "refresh_token");
+			params.add("client_id", clientId);
+			params.add("client_secret", clientSecret);
+			params.add("refresh_token", refreshToken);
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
+			URI url = URI.create(tokenUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+			log.info("getRefreshTocken responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("getRefreshTocken responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+			resultMap.setString("access_token", obj.get("access_token").toString());
+
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+	public GagaMap saveUnlink(String accessToken) {
+		GagaMap resultMap = new GagaMap();
+		try {
+			MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
+			params.add("grant_type", "delete");
+			params.add("client_id", clientId);
+			params.add("client_secret", clientSecret);
+			params.add("access_token", accessToken);
+			params.add("service_provider", "NAVER");
+
+			// Header
+			HttpHeaders headers = new HttpHeaders();
+			headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+
+			HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
+			URI url = URI.create(tokenUrl);
+
+			// POST방식으로 호출
+			ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
+			log.info("saveUnlink : responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
+
+			String jsonResult = responseEntity.getBody();
+			log.info("saveUnlink : responseEntity.getBody(): {} ", jsonResult);
+
+			JsonObject obj = new JsonParser().parse(jsonResult).getAsJsonObject();
+
+			resultMap.setString("access_token", obj.get("access_token").toString());
+			resultMap.setString("result", obj.get("result").toString());
+
+		} catch (Exception e) {
+			log.error(e.getMessage());
+		}
+		return resultMap;
+	}
+
+}

+ 206 - 0
src/main/java/com/style24/front/biz/thirdparty/NiceCertify.java

@@ -0,0 +1,206 @@
+package com.style24.front.biz.thirdparty;
+
+import NiceID.Check.CPClient;
+import com.gagaframework.web.parameter.GagaMap;
+import com.gagaframework.web.util.GagaDateUtil;
+import com.gagaframework.web.util.GagaFileUtil;
+import com.style24.front.support.security.session.TsfSession;
+import com.style24.persistence.domain.Customer;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * 나이스 인증
+ *
+ * @author jsshin
+ * @since 2021. 02. 05
+ */
+@Component
+@Slf4j
+public class NiceCertify {
+
+	@Autowired
+	private Environment env;
+
+	private String niceId;			// 나이스휴대폰인증ID
+	private String nicePwd;			// 나이스휴대폰인증비밀번호
+	private String niceCallback;	// 나이스휴대폰인증콜백URL
+	private String domain;
+
+	@PostConstruct
+	public void init() {
+		niceId = env.getProperty("certify.nice.id");
+		nicePwd = env.getProperty("certify.nice.pwd");
+		niceCallback = env.getProperty("certify.nice.callback");
+		domain = env.getProperty("domain.front");
+		log.info("\n\n---- NiceCertify initialization started ----");
+		log.info("나이스휴대폰인증(ID: {}, PWD: {}, callback: {})", niceId, nicePwd, domain + niceCallback);
+		log.info("\n--- NiceCertify initialization completed ----\n");
+	}
+
+	/**
+	 * 나이스 인증 처리
+	 * @return GagaMap
+	 * @author jsshin
+	 * @since 2021. 02. 05
+	 */
+	public GagaMap certify() {
+		CPClient niceCheck = new CPClient();
+
+		String sRequestNo = niceCheck.getRequestNO(niceId);
+		log.info("sRequestNo: {}", sRequestNo);
+
+		String callback = GagaFileUtil.getConcatenationPath("https://" + TsfSession.getHttpServletRequest().getServerName(), niceCallback);
+		log.info("niceCallback: {}", niceCallback);
+
+		String sAuthType = "M";	// 없으면 기본 선택화면, M: 휴대폰, C: 신용카드, X: 공인인증서
+		String sPopGubun = "N";	// Y: 취소버튼 있음, N: 취소버튼 없음
+		String sCustomize = "";	// 없으면 기본 웹페이지, Mobile: 모바일페이지
+
+		// 입력될 plain 데이타를 만든다.
+		StringBuilder sPlainData = new StringBuilder();
+		sPlainData.append("7:REQ_SEQ").append(sRequestNo.getBytes().length).append(":").append(sRequestNo);
+		sPlainData.append("8:SITECODE").append(niceId.getBytes().length).append(":").append(niceId);
+		sPlainData.append("9:AUTH_TYPE").append(sAuthType.getBytes().length).append(":").append(sAuthType);
+		sPlainData.append("7:RTN_URL").append(callback.getBytes().length).append(":").append(callback);
+		sPlainData.append("7:ERR_URL").append(callback.getBytes().length).append(":").append(callback);
+		sPlainData.append("11:POPUP_GUBUN").append(sPopGubun.getBytes().length).append(":").append(sPopGubun);
+		sPlainData.append("9:CUSTOMIZE").append(sCustomize.getBytes().length).append(":").append(sCustomize);
+		log.info("sPlainData: {}", sPlainData);
+
+		GagaMap resultMap = new GagaMap();
+
+		// 실제적인 암호화
+		int iRtn = niceCheck.fnEncode(niceId, nicePwd, sPlainData.toString());
+		resultMap.setInt("iRtn", iRtn);
+		log.info("iRtn: {}", iRtn);
+
+		if (iRtn != 0) { // 실패했으면
+			throw new IllegalStateException("안심본인인증을 사용할 수 없습니다.");
+		}
+
+		resultMap.setString("sEncData", niceCheck.getCipherData());
+
+		return resultMap;
+	}
+
+	/**
+	 * 나이스 인증 결과값
+	 * @param  customer - 인증정보
+	 * @return GagaMap
+	 * @author jsshin
+	 * @since 2021. 02. 05
+	 */
+	public GagaMap getCertifyResultInfo(Customer customer) {
+		GagaMap resultMap = new GagaMap();
+		String sEncData = customer.getEncData();
+
+		if (StringUtils.isBlank(sEncData)) {
+			throw new IllegalStateException("안심본인인증을 사용할 수 없습니다.");
+		}
+
+		CPClient niceCheck = new CPClient();
+		int iRtn = niceCheck.fnDecode(niceId, nicePwd, sEncData);
+		if (iRtn != 0) {
+			String errorMsg = "[" + iRtn + "]";
+			if (iRtn == -1) {
+				errorMsg = errorMsg + "암호화 시스템 에러";
+			} else if (iRtn == -4) {
+				errorMsg = errorMsg + "입력 데이터 오류";
+			} else if (iRtn == -5) {
+				errorMsg = errorMsg + "복호화 해쉬 오류";
+			} else if (iRtn == -6) {
+				errorMsg = errorMsg + "복호화 데이터 오류";
+			} else if (iRtn == -9) {
+				errorMsg = errorMsg + "입력 데이터 오류";
+			} else if (iRtn == -12) {
+				errorMsg = errorMsg + "사이트 비밀번호 오류";
+			} else {
+				errorMsg = errorMsg + "결과값 확인 후, NICE신용평가정보 개발 담당자에게 문의";
+			}
+			throw new IllegalStateException(errorMsg);
+		}
+		String sPlan = niceCheck.getPlainData();
+		HashMap result = niceCheck.fnParse(sPlan);
+		log.info("휴대폰 인증 결과 값 : {}", result.toString());
+
+		if (result == null && result.isEmpty()) {
+			throw new IllegalStateException("응답값 무효 본인인증을 사용할 수 없습니다.");
+		}
+
+		String sAuthType = (String)result.get("AUTH_TYPE");
+		String sName = (String)result.get("NAME");
+		String sGender = (String)result.get("GENDER");	// F:여성, M:남성
+		String sBirthDate = (String)result.get("BIRTHDATE");
+		String sNationalInfo = (String)result.get("NATIONALINFO");
+		String sDi = (String)result.get("DI");
+		String sCi = (String)result.get("CI");
+		String sMobileNo = (String)result.get("MOBILE_NO");
+		String sAdult = "";		 // 미성년 : 0, 성인 : 1
+		String foreignerYn = ""; // 외국인여부(외국인:Y)
+
+		if ("0".equals(sGender)) {
+			sGender = "F";
+		} else if ("1".equals(sGender)) {
+			sGender = "M";
+		}
+
+		if (StringUtils.isNotBlank(sBirthDate)) {
+			sAdult = this.getAdult(sBirthDate);
+		}
+
+		if ("0".equals(sNationalInfo)) {
+			foreignerYn = "N";
+		} else if ("1".equals(sNationalInfo)) {
+			foreignerYn = "Y";
+		}
+
+		resultMap.setString("authType", sAuthType);
+		resultMap.setString("custNm", sName);
+		resultMap.setString("sexGb", sGender);
+		resultMap.setString("birthYmd", sBirthDate);
+		resultMap.setString("foreignerYn", foreignerYn);
+		resultMap.setString("sDi", sDi);
+		resultMap.setString("sCi", sCi);
+		resultMap.setString("cellPhnno", sMobileNo);
+		resultMap.setString("adult", sAdult);
+
+		return resultMap;
+	}
+
+	/**
+	 * 성인여부
+	 * @param  birthDate
+	 * @return String 성인:Y , 미성년자:N
+	 * @author jsshin
+	 * @since 2021. 02. 05
+	 */
+	private String getAdult(String birthDate) {
+		Date time = new Date();
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(time);
+		cal.add(Calendar.YEAR, -13);
+
+		Date limitDate = cal.getTime();
+		Date birthDt = GagaDateUtil.getDate(birthDate, "yyyyMMdd");
+
+		int compareDt = limitDate.compareTo(birthDt);
+
+		String sAdult = "Y"; //성인
+		if (compareDt < 0) {
+			sAdult = "N"; //미성년자
+		}
+
+		return sAdult;
+	}
+
+
+}

+ 57 - 0
src/main/java/com/style24/front/biz/web/TsfCustomerController.java

@@ -1,7 +1,11 @@
 package com.style24.front.biz.web;
 
+import com.gagaframework.web.util.GagaStringUtil;
+import com.style24.front.support.security.session.TsfSession;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import com.style24.core.support.message.TscMessageByLocale;
@@ -9,6 +13,8 @@ import com.style24.front.biz.service.TsfCustomerService;
 import com.style24.front.support.controller.TsfBaseController;
 
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
 
 /**
  * 고객(회원) Controller
@@ -27,4 +33,55 @@ public class TsfCustomerController extends TsfBaseController {
 	@Autowired
 	private TsfCustomerService customerService;
 
+	/**
+	 * 아이디 & 비밀번호 찾기 화면
+	 *
+	 * @return ModelAndView
+	 * @author jsshin
+	 * @since 2021. 02. 05
+	 */
+	@RequestMapping("/id/find/form")
+	public ModelAndView idFind() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName(super.getDeviceViewName("customer/FindIdAndPwdForm"));
+
+		return mav;
+	}
+
+	/**
+	 * 아이디 찾기 결과 화면
+	 *
+	 * @param confirmYn - 인증여부
+	 * @return ModelAndView
+	 * @author jsshin
+	 * @since 2021. 02. 05
+	 */
+	@GetMapping("/id/find/result/form")
+	public ModelAndView idFindResult(@RequestParam(required = false) String confirmYn) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName(super.getDeviceViewName("customer/FindIdResultForm"));
+
+		return mav;
+	}
+
+
+	/**
+	 * 비밀번호 찾기 결과 화면
+	 *
+	 * @param confirmYn - 인증여부
+	 * @return ModelAndView
+	 * @author jsshin
+	 * @since 2020. 02. 05
+	 */
+	@GetMapping("/pwd/find/result/form")
+	public ModelAndView pwdFindResult(@RequestParam(required = false) String confirmYn) {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName(super.getDeviceViewName("customer/FindPwdResultForm"));
+		return mav;
+	}
+
+
 }

+ 69 - 0
src/main/webapp/WEB-INF/views/web/customer/DormantCertifyFormWeb.html

@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : DormantCertifyFormWeb.html
+ * @desc    : 휴면회원 본인인증 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.05   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+<div id="container" class="container mb">
+	<div class="wrap">
+		<div class="content dormant"> <!-- 페이지특정 클래스 = dormant -->
+			<div class="cont_head">
+				<h3>style24</h3>
+			</div>
+			<div class="cont_body">
+				<div class="form_wrap form_col_c">
+					<div class="form_head">
+						<h4>휴면회원 전환안내</h4>
+					</div>
+					<div class="form_info">
+						<span class="ico_content_dormant"></span>
+						<p class="c_primary">최근 1년 이상 서비스를 이용하지 않아 휴면회원으로 전환되었습니다.</p>
+						<p class="t_info mt10">휴면회원계정 복원 후 정상 서비스 이용이 가능합니다.</p>
+					</div>
+					<div class="btn_group_block">
+						<div class="ui_row">
+							<div class="ui_col_6">
+								<button class="btn btn_default btn_block"><span><i class="ico ico_phone"></i>휴대폰인증</span></button>
+							</div>
+							<div class="ui_col_6">
+								<button class="btn btn_default btn_block"><span><i class="ico ico_ipin"></i>아이핀인증</span></button>
+							</div>
+						</div>
+					</div>
+					<div class="form_summary clear">
+						<strong>관련법령</strong>
+						<p>
+							정보통신망 이용촉진 및 정보보호 등에 관한 법률 제 29조 (개인정보의 파기) 2항 및 동법 시행령 제 16조에 의거하여 최근 1년 이상 서비스 및 이용 회원의 개인정보를 별도 분리&middot;보관하고 있습니다.
+						</p>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>

+ 58 - 0
src/main/webapp/WEB-INF/views/web/customer/DormantCertifyResultFormWeb.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : DormantCertifyFormWeb.html
+ * @desc    : 휴면회원 결과 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.05   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+<div id="container" class="container mb">
+	<div class="wrap">
+		<div class="content dormant_clear"> <!-- 페이지특정 클래스 = dormant_clear -->
+			<div class="cont_head">
+				<h3>style24</h3>
+			</div>
+			<div class="cont_body">
+				<div class="form_wrap form_col_c">
+					<div class="form_head">
+						<h4>휴면회원 전환안내</h4>
+					</div>
+					<div class="form_info">
+						<span class="ico_content_dormant2"></span>
+						<p class="c_primary">휴면상태가 해제되었습니다!</p>
+						<p class="t_info mt10">지금 바로STYLE24의 모든 서비스를 이용하실 수 있습니다!</p>
+					</div>
+					<div class="btn_group_block btn_group_md ui_row">
+						<div class="ui_col_12">
+							<button class="btn btn_dark btn_block"><span>로그인</span></button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>

+ 399 - 0
src/main/webapp/WEB-INF/views/web/customer/FindIdAndPwdFormWeb.html

@@ -0,0 +1,399 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : FindIdAndPwdFormWeb.html
+ * @desc    : 아이디 비번 찾기 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.05   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+<div id="container" class="container mb">
+	<div class="wrap">
+		<div class="content find">
+			<div class="cont_head">
+				<h3>style24</h3>
+			</div>
+			<div class="cont_body">
+				<form class="form_wrap form_col_c" role="form">
+					<div class="form_head">
+						<h4>아이디&#47;비밀번호 찾기</h4>
+					</div>
+					<div class="registration_nav">
+						<ul>
+							<li class="active"><a href="javascript:void(0)">아이디 찾기</a></li>
+							<li><a href="javascript:void(0)">비밀번호 찾기</a></li>
+						</ul>
+					</div>
+					<div class="registration_tap">
+						<div class="form_group">
+							<!-- 아이디찾기일경우 -->
+							<div class="foldGroup checkcase">
+								<ul>
+									<li>
+										<form class="form_wrap" role="form">
+											<div class="fold_head">
+												<a href="javascript:void(0)">
+													<div>
+														<div class="fold_tit">
+															<span>회원정보로 찾기</span>
+														</div>
+													</div>
+												</a>
+											</div>
+											<div class="fold_cont">
+												<div class="txt mb30">
+													<p>등록된 내 회원정보로 찾을 수 있습니다.</p>
+												</div>
+												<div class="form_field">
+													<label class="input_label sr-only">이름</label>
+													<div class="ui_col_12">
+														<div class="input_wrap">
+															<input type="text" name="userName" placeholder="이름" id="txtName" class="form_control">
+														</div>
+													</div>
+												</div>
+												<div class="form_field">
+													<label class="input_label sr-only">생년월일 8자리 (예:19880912)</label>
+													<div class="ui_col_12">
+														<div class="input_wrap">
+															<input type="text" name="userBirth" placeholder="생년월일 8자리 (예:19880912)" id="txtBirth" class="form_control">
+														</div>
+													</div>
+												</div>
+												<div class="form_field">
+													<label class="input_label sr-only">이메일</label>
+													<div class="ui_col_12">
+														<div class="input_wrap">
+															<input type="text" name="userEmail" placeholder="이메일" id="txtEmail" class="form_control">
+														</div>
+													</div>
+												</div>
+												<div class="btn_group_block ui_row mt20">
+													<div class="ui_col_12">
+														<button class="btn btn_dark btn_block"><span>확인</span></button>
+													</div>
+												</div>
+											</div>
+										</form>
+									</li>
+									<li>
+										<form class="form_wrap" role="form">
+											<div class="fold_head">
+												<a href="javascript:void(0)">
+													<div>
+														<div class="fold_tit" style="width: inherit;">
+															<span style="width: inherit;">휴대폰 본인인증으로 찾기</span>
+														</div>
+													</div>
+												</a>
+											</div>
+											<div class="fold_cont">
+												<div class="txt">
+													<p>회원님의 명의로 등록된 휴대폰으로 본인확인을 진행합니다.</p>
+												</div>
+												<div class="ui_row mt20">
+													<div class="ui_col_12">
+														<button class="btn btn_dark btn_block"><span>본인명의 휴대폰으로 인증</span></button>
+													</div>
+												</div>
+											</div>
+										</form>
+									</li>
+									<li>
+										<form class="form_wrap" role="form">
+											<div class="fold_head">
+												<a href="javascript:void(0)">
+													<div>
+														<div class="fold_tit" style="width: inherit;">
+															<span style="width: inherit;">아이핀 인증으로 찾기</span>
+														</div>
+													</div>
+												</a>
+											</div>
+											<div class="fold_cont">
+												<div class="txt">
+													<p>아이핀 인증을 통해 찾을 수 있습니다.</p>
+												</div>
+												<div class="ui_row mt20">
+													<div class="ui_col_12">
+														<button class="btn btn_dark btn_block"><span>아이핀 인증</span></button>
+													</div>
+												</div>
+											</div>
+										</form>
+									</li>
+								</ul>
+							</div>
+							<!-- //아이디찾기일경우 -->
+							<!-- 아이디찾기 성공일경우 -->
+							<div class="find_result clear">
+								<div class="form_info">
+									<span class="ico_content_find"></span>
+									<p>아이디 찾기 결과 안내</p>
+								</div>
+								<div class="form_print_bar mt40">
+									<ul>
+										<li>
+											<span class="t_span">아이디</span>
+											<span class="c_primary bold" data-font="lato">I***D1</span>
+										</li>
+										<li>
+											<span class="t_span">가입일자</span>
+											<span class="bold" data-font="lato">2020.12.22</span>
+										</li>
+										<li>
+											<span class="t_span">가입경로</span>
+											<span class="bold" data-font="lato">YES24 연동</span>
+										</li>
+									</ul>
+								</div>
+								<div class="btn_group_block btn_group_md ui_row">
+									<div class="ui_col_12">
+										<button class="btn btn_dark btn_block"><span>로그인 하기</span></button>
+									</div>
+								</div>
+							</div>
+							<!-- //아이디찾기 성공일경우 -->
+							<!-- 회원정보로 아이디찾기 실패일경우 -->
+							<div class="find_result clear">
+								<div class="form_info">
+									<span class="ico_content_none"></span>
+									<p>입력한 정보와 일치하는 아이디가 존재하지 않습니다.</p>
+									<p class="t_info mt10">
+										정확한 확인을 위해 휴대폰 인증/아이핀 인증을 통한<br>아이디 찾기를 진행해 주세요.
+									</p>
+								</div>
+								<div class="btn_group_block btn_group_md ui_row">
+									<div class="ui_col_6">
+										<button class="btn btn_primary btn_block"><span>회원가입</span></button>
+									</div>
+									<div class="ui_col_6">
+										<button class="btn btn_dark btn_block"><span>다시 찾기</span></button>
+									</div>
+								</div>
+							</div>
+							<!-- //회원정보로 아이디찾기 실패일경우 -->
+							<!-- 휴대폰,아이핀 본인인증으로 아이디찾기 실패일경우 -->
+							<div class="find_result clear">
+								<div class="form_info">
+									<span class="ico_content_none"></span>
+									<p>입력한 정보와 일치하는 아이디가 존재하지 않습니다.</p>
+									<p class="t_info mt10">
+										<span class="c_primary">STYLE24의 새로운 가족이 되어 주세요!</span>
+									</p>
+								</div>
+								<div class="btn_group_block btn_group_md ui_row">
+									<div class="ui_col_12">
+										<button class="btn btn_primary btn_block"><span>회원가입</span></button>
+									</div>
+								</div>
+							</div>
+							<!-- //휴대폰,아이핀 본인인증으로 아이디찾기 실패일경우 -->
+						</div>
+						<div class="form_group" >
+							<!-- 비밀번호찾기일경우 -->
+							<div class="foldGroup checkcase">
+								<ul>
+									<li>
+										<form class="form_wrap" role="form">
+											<div class="fold_head">
+												<a href="javascript:void(0)">
+													<div>
+														<div class="fold_tit" style="width: inherit;">
+															<span style="width: inherit;">회원정보로 찾기</span>
+														</div>
+													</div>
+												</a>
+											</div>
+											<div class="fold_cont">
+												<div class="txt mb30">
+													<p>등록된 내 회원정보로 찾을 수 있습니다.</p>
+												</div>
+												<div class="form_field form_full">
+													<label class="input_label sr-only">아이디</label>
+													<div class="ui_col_12">
+														<div class="input_wrap">
+															<input type="text" name="userId" placeholder="아이디" id="txtId" class="form_control">
+															<button type="button" class="btn btn_primary"><span>확인</span></button>
+														</div>
+													</div>
+												</div>
+												<div class="form_field">
+													<label class="input_label sr-only">이름</label>
+													<div class="ui_col_12">
+														<div class="input_wrap">
+															<input type="text" name="userName" placeholder="이름" id="txtName" class="form_control">
+														</div>
+													</div>
+												</div>
+												<div class="form_field">
+													<label class="input_label sr-only">이메일</label>
+													<div class="ui_col_12">
+														<div class="input_wrap">
+															<input type="text" name="userEmail" placeholder="이메일" id="email" class="form_control">
+														</div>
+													</div>
+												</div>
+												<div class="btn_group_block ui_row mt20">
+													<div class="ui_col_12">
+														<button class="btn btn_dark btn_block"><span>확인</span></button>
+													</div>
+												</div>
+											</div>
+										</form>
+									</li>
+									<li>
+										<form action="" class="form_wrap" role="form">
+											<div class="fold_head">
+												<a href="javascript:void(0)">
+													<div>
+														<div class="fold_tit" style="width: inherit;">
+															<span style="width: inherit;">휴대폰 본인인증으로 찾기</span>
+														</div>
+													</div>
+												</a>
+											</div>
+											<div class="fold_cont">
+												<div class="txt">
+													<p>회원님의 명의로 등록된 휴대폰으로 본인확인을 진행합니다.</p>
+												</div>
+												<div class="ui_row mt20">
+													<div class="ui_col_12">
+														<button class="btn btn_dark btn_block"><span>본인명의 휴대폰으로 인증</span></button>
+													</div>
+												</div>
+											</div>
+										</form>
+									</li>
+									<li>
+										<form action="" class="form_wrap" role="form">
+											<div class="fold_head">
+												<a href="javascript:void(0)">
+													<div>
+														<div class="fold_tit" style="width: inherit;">
+															<span style="width: inherit;">아이핀 인증으로 찾기</span>
+														</div>
+													</div>
+												</a>
+											</div>
+											<div class="fold_cont">
+												<div class="txt">
+													<p>아이핀 인증을 통해 찾을 수 있습니다.</p>
+												</div>
+												<div class="ui_row mt20">
+													<div class="ui_col_12">
+														<button class="btn btn_dark btn_block"><span>아이핀 인증</span></button>
+													</div>
+												</div>
+											</div>
+										</form>
+									</li>
+								</ul>
+							</div>
+							<!-- //비밀번호찾기일경우 -->
+							<!-- 비밀번호 재설정 -->
+							<div class="find_result clear">
+								<div class="form_info">
+									<span class="ico_content_security"></span>
+									<p>안전을 위해 비밀번호를 변경하신 후 이용이 가능합니다.</p>
+								</div>
+								<div class="form_field mt40">
+									<label class="input_label sr-only">신규 비밀번호</label>
+									<div class="ui_col_12">
+										<input type="password" name="userPassword" placeholder="신규 비밀번호" id="txtPassword">
+										<!-- case (사용불가 비밀번호일경우,사용가능한 비밀번호일경우) -->
+										<div class="help_block">
+											<!-- 사용불가 비밀번호일경우 -->
+											<p class="mt10">
+												<span class="c_black2"><i class="ico ico_check black mr5"></i>영문(대/소문자), 숫자, 특수문자 중 2가지 이상 조합(8~20자)</span><br>
+												<span class="c_red2"><i class="ico ico_check red mr5"></i>4개이상 연속되거나 동일한 문자/숫자 제외</span><br>
+												<span class="c_gray"><i class="ico ico_check gray mr5"></i>아이디 제외</span>
+											</p>
+											<!-- //사용불가 비밀번호일경우 -->
+											<!-- 사용가능한 비밀번호일경우 -->
+											<p class="mt10">
+												<span class="c_black2"><i class="ico ico_check black mr5"></i>사용 가능한 비밀번호입니다</span>
+											</p>
+											<!-- //사용가능한 비밀번호일경우 -->
+										</div>
+										<!-- //case (사용불가 비밀번호일경우,사용가능한 비밀번호일경우) -->
+									</div>
+								</div>
+								<div class="form_field">
+									<label class="input_label sr-only">비밀번호 확인</label>
+									<div class="ui_col_12">
+										<input type="password" name="userConfirm" placeholder="비밀번호 확인" id="txtConfirm">
+										<!-- case (비밀번호확인 틀렸을경우,비밀번호 일치할경우) -->
+										<div class="help_block">
+											<!-- 비밀번호확인 틀렸을경우 -->
+											<p class="t_err">
+												새 비밀번호가 일치하지 않습니다.
+											</p>
+											<!-- //비밀번호확인 틀렸을경우 -->
+											<!-- 비밀번호 일치할경우 -->
+											<p class="mt10">
+                                                    <span class="c_black2">
+                                                        <i class="ico ico_check black mr5"></i>새 비밀번호가 일치합니다.
+                                                    </span>
+											</p>
+											<!-- //비밀번호 일치할경우 -->
+										</div>
+										<!-- //case (비밀번호확인 틀렸을경우,비밀번호 일치할경우) -->
+									</div>
+								</div>
+								<div class="btn_group_block btn_group_md ui_row">
+									<div class="ui_col_12">
+										<button class="btn btn_dark btn_block"><span>변경 후 다시 로그인</span></button>
+									</div>
+								</div>
+							</div>
+							<!-- //비밀번호 재설정 -->
+							<!-- 임시비밀번호 발급 -->
+							<div class="find_result clear">
+								<div class="form_info">
+									<span class="ico_content_mail"></span>
+									<p>아래의 이메일로 임시비밀번호가 발급되었습니다.</p>
+									<p class="t_info mt10">
+										로그인 시 비밀번호를 새로 설정하신 후 이용하실 수 있습니다.
+									</p>
+								</div>
+								<div class="form_print_bar mt40">
+									<p class="c_primary bold" data-font="lato">a****c@gmail.com</p>
+								</div>
+								<div class="btn_group_block btn_group_md ui_row">
+									<div class="ui_col_12">
+										<button class="btn btn_dark btn_block"><span>로그인 하기</span></button>
+									</div>
+								</div>
+							</div>
+							<!-- //임시비밀번호 발급 -->
+						</div>
+					</div>
+				</form>
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>

+ 96 - 0
src/main/webapp/WEB-INF/views/web/customer/FindIdResultFormWeb.html

@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : FindIdResultFormWeb.html
+ * @desc    : 아이디 찾기 결과 안내 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.05   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+<div id="container" class="container mb">
+	<div class="wrap">
+		<div class="content find_complete"> <!-- 페이지특정 클래스 = find_complete -->
+			<div class="cont_head">
+				<h3>style24</h3>
+			</div>
+			<div class="cont_body">
+				<div class="form_wrap form_col_c">
+					<div class="form_head">
+						<h4>아이디&#47;비밀번호 찾기</h4>
+					</div>
+					<!-- 아이디찾기 성공일경우 -->
+					<div class="find_result clear">
+						<div class="form_info">
+							<span class="ico_content_find"></span>
+							<p>아이디 찾기 결과 안내</p>
+						</div>
+						<div class="form_print_bar mt40">
+							<ul>
+								<li>
+									<span class="t_span">아이디</span>
+									<span class="c_primary bold" data-font="lato">I***D1</span>
+								</li>
+								<li>
+									<span class="t_span">가입일자</span>
+									<span class="bold" data-font="lato">2020.12.22</span>
+								</li>
+								<li>
+									<span class="t_span">가입경로</span>
+									<span class="bold" data-font="lato">YES24 연동</span>
+								</li>
+							</ul>
+						</div>
+						<div class="btn_group_block btn_group_md ui_row">
+							<div class="ui_col_12">
+								<button class="btn btn_dark btn_block"><span>로그인 하기</span></button>
+							</div>
+						</div>
+					</div>
+					<!-- //아이디찾기 성공일경우 -->
+					<!-- 회원정보로 아이디찾기 실패일경우 -->
+					<div class="find_result clear">
+						<div class="form_info">
+							<span class="ico_content_none"></span>
+							<p>입력한 정보와 일치하는 아이디가 존재하지 않습니다.</p>
+							<p class="t_info mt10">
+								정확한 확인을 위해 휴대폰 인증/아이핀 인증을 통한<br>아이디 찾기를 진행해 주세요.
+							</p>
+						</div>
+						<div class="btn_group_block btn_group_md ui_row">
+							<div class="ui_col_6">
+								<button class="btn btn_primary btn_block"><span>회원가입</span></button>
+							</div>
+							<div class="ui_col_6">
+								<button class="btn btn_dark btn_block"><span>다시 찾기</span></button>
+							</div>
+						</div>
+					</div>
+					<!-- //회원정보로 아이디찾기 실패일경우 -->
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>

+ 105 - 0
src/main/webapp/WEB-INF/views/web/customer/FindPwdResultFormWeb.html

@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : FindIdResultFormWeb.html
+ * @desc    : 비밀번호 설정 화면 안내 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.05   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+<div id="container" class="container mb">
+	<div class="wrap">
+		<div class="content security_pw"> <!-- 페이지특정 클래스 = security_pw -->
+			<div class="cont_head">
+				<h3>style24</h3>
+			</div>
+			<div class="cont_body">
+				<form class="form_wrap form_col_c form_full" role="form">
+					<div class="form_head">
+						<h4>아이디&#47;비밀번호 찾기</h4>
+					</div>
+					<!-- 비밀번호 재설정 -->
+					<div class="find_result clear">
+						<div class="form_info">
+							<span class="ico_content_security"></span>
+							<p>안전을 위해 비밀번호를 변경하신 후 이용이 가능합니다.</p>
+						</div>
+						<div class="form_field mt40">
+							<label class="input_label sr-only">신규 비밀번호</label>
+							<div class="ui_col_12">
+								<input type="password" name="userPassword" placeholder="신규 비밀번호" id="txtPassword">
+								<!-- case (사용불가 비밀번호일경우,사용가능한 비밀번호일경우) -->
+								<div class="help_block">
+									<!-- 사용불가 비밀번호일경우 -->
+									<p class="mt10">
+										<span class="c_black2"><i class="ico ico_check black mr5"></i>영문(대/소문자), 숫자, 특수문자 중 2가지 이상 조합(8~20자)</span><br>
+										<span class="c_red2"><i class="ico ico_check red mr5"></i>4개이상 연속되거나 동일한 문자/숫자 제외</span><br>
+										<span class="c_gray"><i class="ico ico_check gray mr5"></i>아이디 제외</span>
+									</p>
+									<!-- //사용불가 비밀번호일경우 -->
+									<!-- 사용가능한 비밀번호일경우 -->
+									<p class="mt10">
+										<span class="c_black2"><i class="ico ico_check black mr5"></i>사용 가능한 비밀번호입니다</span>
+									</p>
+									<!-- //사용가능한 비밀번호일경우 -->
+								</div>
+								<!-- //case (사용불가 비밀번호일경우,사용가능한 비밀번호일경우) -->
+							</div>
+						</div>
+						<div class="form_field">
+							<label class="input_label sr-only">비밀번호 확인</label>
+							<div class="ui_col_12">
+								<input type="password" name="userConfirm" placeholder="비밀번호 확인" id="txtConfirm">
+								<!-- case (비밀번호확인 틀렸을경우,비밀번호 일치할경우) -->
+								<div class="help_block">
+									<!-- 비밀번호확인 틀렸을경우 -->
+									<p class="t_err">
+										새 비밀번호가 일치하지 않습니다.
+									</p>
+									<!-- //비밀번호확인 틀렸을경우 -->
+									<!-- 비밀번호 일치할경우 -->
+									<p class="mt10">
+										<span class="c_black2">
+											<i class="ico ico_check black mr5"></i>새 비밀번호가 일치합니다.
+										</span>
+									</p>
+									<!-- //비밀번호 일치할경우 -->
+								</div>
+								<!-- //case (비밀번호확인 틀렸을경우,비밀번호 일치할경우) -->
+							</div>
+						</div>
+						<div class="btn_group_block btn_group_md ui_row">
+							<div class="ui_col_12">
+								<button class="btn btn_dark btn_block"><span>변경 후 다시 로그인</span></button>
+							</div>
+						</div>
+					</div>
+					<!-- //비밀번호 재설정 -->
+				</form>
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>

+ 168 - 0
src/main/webapp/WEB-INF/views/web/customer/JoinFormWeb.html

@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html lang="ko"
+	xmlns:th="http://www.thymeleaf.org"
+	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
+	layout:decorator="web/common/layout/DefaultLayoutWeb">
+<!--
+ *******************************************************************************
+ * @source  : JoinFormWeb.html
+ * @desc    : 회원정보 입력 Page
+ *============================================================================
+ * STYLE24
+ * Copyright(C) 2021 TSIT, All rights reserved.
+ *============================================================================
+ * VER  DATE         AUTHOR      DESCRIPTION
+ * ===  ===========  ==========  =============================================
+ * 1.0  2021.02.05   jsshin     최초 작성
+ *******************************************************************************
+ -->
+<body>
+
+<th:block layout:fragment="content">
+<div id="container" class="container mb">
+	<div class="wrap">
+		<div class="content join2"> <!-- 페이지특정 클래스 = join1 -->
+			<div class="cont_head">
+				<h3>style24</h3>
+			</div>
+			<div class="cont_body">
+				<!-- form start -->
+				<form class="form_wrap form_col_c form_full" role="form">
+					<div class="form_head">
+						<h4>회원정보 입력</h4>
+					</div>
+					<!-- 아이디 사용가능시 -->
+					<div class="form_field">
+						<label class="input_label sr-only">아이디</label>
+						<div class="input_wrap form_full">
+							<input type="text" name="userId" placeholder="아이디" value="moon123" class="form_control usable" id="txtId"><!-- class "usable" 추가 -->
+							<span class="usable" style="display:block;"></span><!-- display:block / display:none 으로 control -->
+						</div>
+					</div>
+					<!-- //아이디 사용가능시 -->
+					<!-- 아이디 사용불가시 -->
+					<div class="form_field">
+						<label class="input_label sr-only">아이디</label>
+						<div class="input_wrap form_full">
+							<input type="text" name="userId" placeholder="아이디" value="abcd1234" class="form_control err" id="txtId"><!-- 잘못기입된 경우 class "err" 추가 -->
+							<span class="usable"></span>
+						</div>
+						<div class="help_block">
+							<p class="t_err">이미 가입된 아이디입니다.다른 아이디를 입력하여 주세요.</p>
+						</div>
+					</div>
+					<!-- //아이디 사용불가시 -->
+
+					<!-- 오류시 부모 div에서 제어 -->
+					<div class="form_field">
+						<label class="input_label sr-only">비밀번호</label>
+						<div class="input_wrap form_full">
+							<input type="password" name="userPassword" placeholder="비밀번호 (8~20자 영문, 숫자, 특수문자 중 2가지 이상 조합)" class="form_control" id="txtPassword"><!-- 잘못기입된 경우 class "err" 추가 -->
+							<!-- case (사용불가 비밀번호일경우,사용가능한 비밀번호일경우) -->
+							<div class="help_block">
+								<!-- 사용불가 비밀번호일경우 -->
+								<p class="mt10">
+									<span class="c_black2"><i class="ico ico_check black mr5"></i>영문(대/소문자), 숫자, 특수문자 중 2가지 이상 조합(8~20자)</span><br>
+									<span class="c_red2"><i class="ico ico_check red mr5"></i>4개이상 연속되거나 동일한 문자/숫자 제외</span><br>
+									<span class="c_gray"><i class="ico ico_check gray mr5"></i>아이디 제외</span>
+								</p>
+								<!-- //사용불가 비밀번호일경우 -->
+								<!-- 사용가능한 비밀번호일경우 -->
+								<p class="mt10">
+									<span class="c_black2"><i class="ico ico_check black mr5"></i>사용 가능한 비밀번호입니다</span>
+								</p>
+								<!-- //사용가능한 비밀번호일경우 -->
+							</div>
+							<!-- //case (사용불가 비밀번호일경우,사용가능한 비밀번호일경우) -->
+						</div>
+					</div>
+					<!-- //오류시 부모 div에서 제어 -->
+					<div class="form_field">
+						<label class="input_label sr-only">비밀번호 확인</label>
+						<div class="input_wrap form_full">
+							<input type="password" name="userConfirm" placeholder="비밀번호 확인" class="form_control" id="txtConfirm"><!-- 잘못기입된 경우 class "err" 추가 -->
+							<!-- case (비밀번호확인 틀렸을경우,비밀번호 일치할경우) -->
+							<div class="help_block">
+								<!-- 비밀번호확인 틀렸을경우 -->
+								<p class="t_err">
+									비밀번호가 일치하지 않습니다.
+								</p>
+								<!-- //비밀번호확인 틀렸을경우 -->
+								<!-- 비밀번호 일치할경우 -->
+								<p class="mt10">
+									<span class="c_black2"><i class="ico ico_check black mr5"></i>비밀번호가 일치합니다.</span>
+								</p>
+								<!-- //비밀번호 일치할경우 -->
+							</div>
+							<!-- //case (비밀번호확인 틀렸을경우,비밀번호 일치할경우) -->
+						</div>
+					</div>
+					<div class="form_field">
+						<label class="input_label sr-only">이메일</label>
+						<div class="input_wrap form_full">
+							<input type="text" name="userEmail" placeholder="이메일" class="form_control" id="txtEmail"><!-- 잘못기입된 경우 class "err" 추가 -->
+							<!-- case (이메일 형식이 바르지않을경우,이미 가입되어있는 이메일인경우) -->
+							<div class="help_block">
+								<!-- 이메일 형식이 바르지않을경우 -->
+								<p class="t_err">
+									이메일 형식이 올바르지 않습니다.
+								</p>
+								<!-- //이메일 형식이 바르지않을경우 -->
+								<!-- 이미 가입되어있는 이메일인경우 -->
+								<p class="t_err">
+									이미 가입된 이메일 주소입니다. 다른 이메일 주소를 입력하여 주세요.
+								</p>
+								<div class="mt20">
+									<button type="button" class="btn btn_default btn_sm"><span>로그인</span></button>
+									<button type="button" class="btn btn_default btn_sm"><span>아이디 찾기</span></button>
+								</div>
+								<!-- //이미 가입되어있는 이메일인경우 -->
+							</div>
+							<!-- //case (이메일 형식이 바르지않을경우,이미 가입되어있는 이메일인경우) -->
+						</div>
+					</div>
+					<div class="form_field">
+						<label class="input_label sr-only">휴대폰번호</label>
+						<div class="input_wrap form_full">
+							<input type="text" name="userTell" placeholder="휴대폰번호" class="form_control" id="txtTell">
+							<!-- case (휴대폰번호 형식이 맞지 않을경우,이미 가입되어있는 핸드폰번호일경우) -->
+							<div class="help_block">
+								<!-- 휴대폰번호 형식이 맞지 않을경우 -->
+								<p class="t_err">휴대폰번호를 형식에 맞게 정확히 입력해주세요</p>
+								<!-- //휴대폰번호 형식이 맞지 않을경우 -->
+								<!-- 이미 가입되어있는 핸드폰번호일경우 -->
+								<p class="t_err">I***D로 가입된 핸드폰 번호 입니다.</p>
+								<div class="mt20">
+									<button type="button" class="btn btn_default btn_sm"><span>휴대폰 인증</span></button>
+								</div>
+								<!-- //이미 가입되어있는 핸드폰번호일경우 -->
+							</div>
+							<!-- //case (휴대폰번호 형식이 맞지 않을경우,이미 가입되어있는 핸드폰번호일경우) -->
+						</div>
+					</div>
+					<div class="mt40">
+						<button class="btn btn_primary btn_block"><span>동의하고 가입하기</span></button>
+					</div>
+					<div class="desc_wrap t_c mt20">
+						<p>
+							본인은&nbsp;만 14세 이상이며&nbsp;<a href="" target="_blank">STYLE24이용약관<i class="ico ico_blank ml5"></i></a>,&nbsp;<a href="" target="_blank">개인정보 수집 및 이용<i class="ico ico_blank ml5"></i></a>,<br>
+							<a href="" target="_blank">개인정보 취급 위탁<i class="ico ico_blank ml5"></i></a> 내용을 확인 하였으며,동의합니다.
+						</p>
+					</div>
+				</form>
+				<!-- form End -->
+			</div>
+		</div>
+	</div>
+</div>
+
+<script th:inline="javascript">
+/*<![CDATA[*/
+
+/*]]>*/
+</script>
+
+</th:block>
+
+</body>
+</html>