๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring๐Ÿ€

์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก ์‹œ: ์œ ํšจ ์‹œ๊ฐ„ ์„ค์ •(session ์‚ฌ์šฉ)

by @ENFJ 2024. 2. 25.

์ธ์ฆ ๋ฒˆํ˜ธ_์œ ํšจ ์‹œ๊ฐ„(Session ์‚ฌ์šฉ)

<aside> ๐Ÿ’ก SMTP ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์ผ ( ์ธ์ฆ ๋ฒˆํ˜ธ : ๋žœ๋ค ๋‚œ์ˆ˜ ) ์„ ์ „์†กํ•  ๋•Œ, ์œ ํšจ ์‹œ๊ฐ„ 3๋ถ„์„ session ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ ์šฉ ์‹œํ‚ค๋Š” ๊ณผ์ •์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.

</aside>


์ฝ”๋“œ

HTML

<meta name="_csrf_header" th:content="${_csrf.headerName}">
<meta name="_csrf" th:content="${_csrf.token}">

<div class="pop_wrap login user_find" data-layer-wrap="user_find" style="display: block;">
	<div class="pop_top">
	<!-- S : ์„ฑํ™˜ : ํŒ์—…์ฐฝ ๋‹ซ๊ธฐ ๋ฒ„ํŠผ-->
		<button class="pop_close hide_pop" data-layer-id="user_find" >
			<img src="/pon/common/image/chat_close.svg" alt="">
		</button>
		<!-- E : ์„ฑํ™˜ : ํŒ์—…์ฐฝ ๋‹ซ๊ธฐ ๋ฒ„ํŠผ-->
	</div>
	<div class="pop_content">
		<h2 class="pop_title">์•„์ด๋”” · ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ</h2>
		<div class="login_wrap">
			<div class="tab_menu">
				<div class="tab_menu_btn">
					<a href="javascript:void(0);" data-tab="tab1" class="active">์•„์ด๋”” ์ฐพ๊ธฐ</a>
					<a href="javascript:void(0);" data-tab="tab2">๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ</a>
				</div>

				<form th:action = "@{/findUsername}" method = "post" onsubmit="return findUsername()">
					<div class="tab_cont current" data-tab-wrap="tab1">
						<div class="input_wrap">
							<input id="username" name="username" class="name_input" type="text" placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.">

							<input id="phone" name="phone" type="number"  placeholder="ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.">
						</div>
						<!-- S : ์„ฑํ™˜: ์•„์ด๋”” ์ฐพ๊ธฐ ๋ฒ„ํŠผ-->
						<button type="button" class="btn btn_login_default login_btn" onclick="findUsername()">์•„์ด๋”” ์ฐพ๊ธฐ</button>
						<!-- E : ์„ฑํ™˜: ์•„์ด๋”” ์ฐพ๊ธฐ ๋ฒ„ํŠผ-->
						<!-- ๊ธฐ์กด์ฝ”๋“œ <button id="findId_find_btn" class="find_btn">์•„์ด๋”” ์ฐพ๊ธฐ</button>-->
					</div>
				</form>

				<div class="tab_cont" data-tab-wrap="tab2">
					<div class="input_wrap">
						<input id="findPw_name" class="name_input" type="text" placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.">

						<input id="findPw_email" class="name_input" type="text" placeholder="์ด๋ฉ”์ผ์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.">
						<div class="group">
							<input id="findPw_auth_number" class="cert_input" type="number" placeholder="์ธ์ฆ ๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.">
							<button id="findPw_send_auth_number" class="cert_btn" onclick="**findUseremail**()">์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก</button>
							<div id="timerDisplay" class="timer_display"></div>
						</div>
					</div>

					<!-- S : ์„ฑํ™˜ : ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ ๋ฒ„ํŠผ-->
					<div class="login_btn_wrap">
						<button type="button" class="btn btn_login_default login_btn" onclick="findUserpw()">๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ</button>
					</div>
					<!-- E : ์„ฑํ™˜ : ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ ๋ฒ„ํŠผ-->

					<!--๊ธฐ์กด์ฝ”๋“œ <button id="findPw_find_btn" class="find_btn">๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ</button>-->
				</div>
			</div>
		</div>
	</div>
</div>
  1. JavaScipt
/* S: ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ - ์ด๋ฉ”์ผ ์ฐพ๊ธฐ(์ด๋ฉ”์ผ ๋ฐœ์†ก, ํƒ€์ด๋จธ) */
function **findUseremail**(){
    //์‚ฌ์šฉ์ž ์ž…๋ ฅ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ
    var findpwname = $("#findPw_name").val();
    var findpwemail = $("#findPw_email").val();

    // ์„œ๋ฒ„๋กœ ์ „์†กํ•  ๋ฐ์ดํ„ฐ ๊ตฌ์„ฑ

    data = new FormData();
    data.append( "userNm", findpwname );
    data.append( "userId", findpwemail );

    var header = $("meta[name='_csrf_header']").attr('content');
    var token = $("meta[name='_csrf']").attr('content');

    // Ajax ๋ฅผ ์‚ฌ์šฉํ•œ ์„œ๋ฒ„๋กœ์˜ ์š”์ฒญ
    $.ajax({
        url: "/findUseremail",
        type: "POST",
        data: data,
        cache: false,
        contentType: false,
        processData: false,
        // contentType: "application/json; charset=utf-8",
        beforeSend: function(xhr){
            xhr.setRequestHeader(header, token);
        },
        success: function (result) {

            // ํ†ต์‹  ์ดํ›„ ๋กœ์ง
            **if ( result.flag == "E" ) {**
                **alert( result.msg );**

            **} else if ( result.flag == "S" ) {**
                // ์กด์žฌํ•˜๋Š” ๊ณ„์ •์ •๋ณด์ผ ๊ฒฝ์šฐ ์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก๋˜์—ˆ๋‹ค๊ณ  ์•Œ๋ฆผ
                **alert(result.msg);**

                // TODO : 3๋ถ„ ํƒ€์ด๋จธ ํ•ด์•ผํ•จ
                **startTimer**(**180**);
            }
        },
        error: function (){
            alert("code:"+request.status+"\\n"+"message:"+request.responseText+"\\n"+"error:"+error)
        }
    })
}

// ํƒ€์ด๋จธ(3๋ถ„)
function **startTimer**(**duration**) {
    var timer = duration, minutes, seconds;
    var intervalId = setInterval(function () {
        minutes = parseInt(timer / 60, 10);
        seconds = parseInt(timer % 60, 10);

        minutes = minutes < 10 ? "0" + minutes : minutes;
        seconds = seconds < 10 ? "0" + seconds : seconds;

        // 'timerDisplay'๋ผ๋Š” ID๋ฅผ ๊ฐ€์ง„ HTML ์š”์†Œ์— ํƒ€์ด๋จธ ํ‘œ์‹œ
        $("#timerDisplay").text("์žฌ๋ฐœ์†ก (" + minutes + ":" + seconds + ")");

        if (--timer < 0) {
            clearInterval(intervalId);
            // ํƒ€์ด๋จธ๊ฐ€ 0์— ๋„๋‹ฌํ•˜๋ฉด ๋ฒ„ํŠผ ํ…์ŠคํŠธ๋ฅผ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ
            $("#findPw_send_auth_number").text("์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก");
            // ์„ ํƒ์ ์œผ๋กœ ํƒ€์ด๋จธ๊ฐ€ 0์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์ถ”๊ฐ€ ์ž‘์—… ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ
        }
    }, 1000);
}

/* E: ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ - ์ด๋ฉ”์ผ ์ฐพ๊ธฐ(์ด๋ฉ”์ผ ๋ฐœ์†ก, ํƒ€์ด๋จธ) */
  1. Controller (1. ์ด๋ฉ”์ผ ์ „์†ก ์‹œ(์ธ์ฆ ๋ฒˆํ˜ธ) , 2. ์ธ์ฆ ๋ฒˆํ˜ธ ๊ฒ€์ฆ)
	/* S : ์ด๋ฉ”์ผ ํ™•์ธ ๋ฐ ์ธ์ฆ๋ฒˆํ˜ธ ์ „์†ก */
	@ResponseBody
	**@PostMapping("/findUseremail")**
	public Map<String, Object> findUseremail( @ModelAttribute LoginDto loginDto) {

		//๋ฉ”์†Œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ๋‚˜์„œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ˜ํ™˜๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๊ธฐ ์œ„ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„
		Map<String, Object> result = new HashMap<String, Object>();

		// ์—ฌ๊ธฐ์—์„œ ์‹ค์ œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

		// 1. ์ด๋ฆ„/ ์ด๋ฉ”์ผ / (๊ด€๋ฆฌ์ž์—ฌ๋ถ€) ๋กœ ๊ณ„์ •์„ ์ฐพ์Œ
		// ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ ๊ธฐ๋Šฅ์—์„œ ์‹ค์ œ๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์กฐํšŒํ•˜๋Š” ๋ถ€๋ถ„
		LoginDto targetDto = loginService.findByUserNmAndUserIdAndMngrYn(loginDto);

		if ( targetDto != null ) {
			// 1-1. ํ•ด๋‹น ์ž…๋ ฅ๊ฐ’์œผ๋กœ ์ฐพ์€ ๊ณ„์ •์ด ์žˆ์„ ๋–„
			result.put("flag", "S");
			result.put("msg", "์ธ์ฆ๋ฒˆํ˜ธ๊ฐ€ ๋ฐœ์†ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ");

			//์ด๋ฉ”์ผ ์ „์†ก
			// sendEmail(targetDto.getUserId(),generateRandomAuthNumber());
			try{
				sendEmail(targetDto.getUserId(),generateRandomAuthNumber(), session);
			}catch(MessagingException e){
				e.printStackTrace();
				result.put("flag", "E");
				result.put("msg","์ด๋ฉ”์ผ ์ „์†ก ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.");
				return result;
			}

		} else if ( targetDto == null ) {
			// 1-2. ํ•ด๋‹น ์ž…๋ ฅ๊ฐ’์œผ๋กœ ์ฐพ์€ ๊ณ„์ •์ด ์—†์„ ๋•Œ
			result.put("flag", "E");
			result.put("msg", "์ž…๋ ฅํ•˜์‹  ์ •๋ณด์™€ ์ผ์น˜ํ•˜๋Š” ๊ณ„์ •์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”. ");
		}

		return result;
	}

	**// ์ด๋ฉ”์ผ ์ „์†ก ๋ฉ”์„œ๋“œ**
	private void **sendEmail**(String to, String authNumber , **HttpSession session**)throws MessagingException{
		MimeMessage mimeMessage = javaMailSender.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, false, "UTF-8");

		helper.setTo(to);
		helper.setSubject("์ด๋ฉ”์ผ ์ธ์ฆ๋ฒˆํ˜ธ");
		helper.setText("์ธ์ฆ๋ฒˆํ˜ธ: " + authNumber, true);

		javaMailSender.send(mimeMessage);

		// ์„ธ์…˜์— ์ธ์ฆ๋ฒˆํ˜ธ ์ €์žฅ
		session.setAttribute("authCode", authNumber);
		// TODO : ์‹œ์ž‘ ์‹œ๊ฐ„ ์ฒดํฌ
		// ์„ธ์…˜์— ์‹œ์ž‘์‹œ๊ฐ„ ์ €์žฅ
		**session**.**setAttribute**("authStartTime", System.currentTimeMillis());
	}

	// ๋žœ๋คํ•œ ์ธ์ฆ๋ฒˆํ˜ธ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ
	private String generateRandomAuthNumber(){
		// TODO ์—ฌ๊ธฐ์— ๋žœ๋ค ์ธ์ฆ๋ฒˆํ˜ธ ์ƒ์„ฑ ๋กœ์ง ์ถ”๊ฐ€ (์กฐ๊ฑด : ๋žœ๋คํ•œ 6์ž๋ฆฌ ์ˆซ์ž)
		// return "123456";
		// ๋žœ๋ค ์ธ์ฆ๋ฒˆํ˜ธ ์ƒ์„ฑ (6์ž๋ฆฌ ์ˆซ์ž)
		Random random = new Random();
		int min = 100000;
		int max = 999999;
		int randomAuthNumber = random.nextInt((max - min) + 1) + min;

		return String.valueOf(randomAuthNumber);
	}
	/* E : ์ด๋ฉ”์ผ ํ™•์ธ ๋ฐ ์ธ์ฆ๋ฒˆํ˜ธ ์ „์†ก */
  • ์ด๋ฉ”์ผ (์ธ์ฆ๋ฒˆํ˜ธ) ๋ฐœ์†ก ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์‹œ๊ฐ„์„ ์„ธ์…˜(Session) ์— ์ €์žฅํ•œ๋‹ค.
/* S: ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ - ์ธ์ฆ๋ฒˆํ˜ธ ๊ฒ€์ฆ */
	@ResponseBody
	**@PostMapping("/findUserpw")**
	public Map<String,Object> findUserpw(@RequestParam String authNumber, **HttpSession session**){
		Map<String, Object> result = new HashMap<>();

		// ์„ธ์…˜์—์„œ ์ €์žฅ๋œ [์ธ์ฆ๋ฒˆํ˜ธ] ์™€  [์‹œ์ž‘ ์‹œ๊ฐ„]  ๊ฐ€์ ธ์˜ค๊ธฐ
		String storedAuthCode = (String) session.getAttribute("authCode");
		**Long startTime = (Long) session.getAttribute("authStartTime");**

		if (storedAuthCode != null && storedAuthCode.equals(authNumber) && **startTime != null**) {
			// ์ธ์ฆ๋ฒˆํ˜ธ ์ผ์น˜
			result.put("flag", "S");
			result.put("msg", "์ธ์ฆ์— ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.");
			**// ๊ฒ€์ฆ ์‹œ๊ฐ„ ์ฒดํฌ**
			// TODO : ์‹œ์ž‘ ์‹œ๊ฐ„ , ๊ฒ€์ฆ์‹œ๊ฐ„ ๋น„๊ตํ•˜์—ฌ 3๋ถ„ ์ด๋‚ด์ธ์ง€ ํ™•์ธ
			**long currentTime = System.currentTimeMillis();
			long timeDifference = currentTime - startTime;
			if (timeDifference <= 3 * 60 * 1000) {** // 3๋ถ„ (3 * 60 * 1000 ๋ฐ€๋ฆฌ์ดˆ)
				// 3๋ถ„ ์ด๋‚ด
				**result.put("flag", "S");
				result.put("msg", "์ธ์ฆ์— ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.");**
			// ์ธ์ฆ ์„ฑ๊ณต ํ›„ ํ•„์š”ํ•œ ์ž‘์—… ์ˆ˜ํ–‰
			**} else {**
				// 3๋ถ„ ๋„˜์–ด๊ฐ€๋ฉด..
				// ์‹œ๊ฐ„์ดˆ๊ณผ ๋ฉ”์‹œ์ง€..
			**result.put("flag", "E");
			result.put("msg", "์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");**
			**}**

		} else {
			// ์ธ์ฆ๋ฒˆํ˜ธ ๋ถˆ์ผ์น˜
			result.put("flag", "E");
			result.put("msg", "์ธ์ฆ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ์‹œ๋„ํ•ด์ฃผ์„ธ์š”.");
		}

		return result;
	}
	/* E: ๋น„๋ฐ€๋ฒˆํ˜ธ ์ฐพ๊ธฐ - ์ธ์ฆ๋ฒˆํ˜ธ ๊ฒ€์ฆ */

๊ฐ Level ์—ญํ• 

[์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก] ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ

  1. html ์—ญํ•  : 03:00 (3๋ถ„) ์ด ํ๋ฅด๊ณ  ์žˆ์Œ์„ ํ‘œ์ถœํ•ด์•ผ ํ•œ๋‹ค.
  2. JavaScript ์—ญํ• : html ์— ์‹ค์‹œ๊ฐ„์œผ๋กœ ์‹œ๊ฐ„์ด ํ๋ฅด๊ฒŒ ๋™์ž‘ ๊ตฌํ˜„


  1. Controller ์—ญํ• :
  • 1-1: [์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก] ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ → ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ์— ์‹œ์ž‘ ์‹œ๊ฐ„์„ ์„ธ์…˜์— ์ €์žฅ ,
  • 1-2: ์ธ์ฆ๋ฒˆํ˜ธ ์ž…๋ ฅ ํ›„ [ํ™•์ธ] ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ → ํ•ด๋‹น ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ํ•˜์—ฌ ์ธ์ฆ๋ฒˆํ˜ธ ๋ฐœ์†ก ํ•  ๋•Œ ์„ธ์…˜์— ์ €์žฅํ•ด๋‘” ์‹œ๊ฐ„๊ณผ ํ˜„์žฌ ์‹œ๊ฐ„์„ ๋น„๊ตํ•˜์—ฌ 3๋ถ„ ์ด๋‚ด์ธ์ง€(ํ˜„์žฌ ์‹œ๊ฐ„ -๋ฐœ์†ก ์‹œ๊ฐ„) ํ™•์ธ
  • 1-3: ํ•ด๋‹น ๊ฒฐ๊ณผ result ์— put ํ•˜์—ฌ ๊ฒฐ๊ณผ_return ์‹œํ‚ด.

'Spring๐Ÿ€' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Spring Bean ์ •๋ฆฌ  (1) 2022.10.23
JDBC,SQLMAPPER ์ •๋ฆฌ  (0) 2022.10.22
spring MVC(๋ชจ๋ธ2, DispatcherServlet) ์ •๋ฆฌ  (3) 2022.10.20
Spring(์Šคํ”„๋ง) : API  (2) 2022.09.24
Spring ์„ค์น˜  (1) 2022.04.01