커뮤니티 - 로그아웃, 아이디 저장 기능 구현 (23.07.06)

·2023년 7월 6일
0

Server

목록 보기
8/35
post-thumbnail

📝 로그아웃, 아이디 저장 기능 구현


💡Eclipse

🔎 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>KH 커뮤니티</title>

    <link rel="stylesheet" href="resources/css/main-style.css">

    <script src="https://kit.fontawesome.com/4dca1921b4.js" crossorigin="anonymous"></script>
</head>
<body>

    <main>
        <header>
            
            <!-- 클릭 시 메인페이지로 이동하는 로고 -->
            <section>
                <a href="#">
                    <img src="resources/images/logo.jpg" id="home-logo">
                </a>
            </section>

            <!-- header의 두번째 자식 div -->
            <section>
                <article class="search-area">

                    <!-- form 내부 input 태그 값을 서버 또는 페이지로 전달 -->
                    <form action="#" name="search form">

                        <!-- fieldset : form 내부에서 input을 종류별로 묶는 용도로 많이 사용 -->
                        <fieldset>

                            <input type="search" id="query" name="query" 
                                placeholder="검색어를 입력해주세요" autocomplete="off">

                            <!-- 검색 버튼 -->
                            <button type="submit" id="search-btn" class="fa-solid fa-magnifying-glass"></button>
                            
                        </fieldset>

                    </form>
                </article>
            </section>
            <section></section>
        </header>

        <nav>

            <ul>
                <li><a href=#>공지사항</a></li>
                <li><a href=#>자유 게시판</a></li>
                <li><a href=#>질문 게시판</a></li>
                <li><a href=#>FAQ</a></li>
                <li><a href=#>1:1문의</a></li>
            </ul>
        </nav>

        <section class="content">
            <section class="content-1">
            	loginMember : ${sessionScope.loginMember}
            	
            	<hr>
            	
            	message : ${sessionScope.message}
            </section>
            <section class="content-2">
            
            	<!-- if - else -->
            	<c:choose>

					<%-- choose 내부에는 jsp 주석만 사용 --%>
            		<c:when test="${ empty sessionScope.loginMember }">
            		
            			<!-- 절대경로 : /community/member/login -->
		            	<!-- 상대경로 (index.jsp) 기준 -->
		                <form action="member/login" method="post" name="login-form">
		        
		                    <!-- 아이디(이메일)/비밀번호/로그인 버튼 영역 -->
		                    <fieldset id="id-pw-area">
		                        <section>
		                            <input type="text" name="inputEmail" placeholder="아이디(이메일)" value="${cookie.saveId.value}">
		                            															<%-- 현재 페이지 쿠키 중 "saveId"의 내용을 출력 --%>
		                            <input type="password" name="inputPw" placeholder="비밀번호">
		                        </section>
		                        <section>
		                            <button>로그인</button>
		                        </section>
		                    </fieldset>
		        
		                    <!-- 회원가입, ID/PW 찾기 영역 -->
		                    <article id="signup-find-area">
		                        <a href="#">회원가입</a>
		                        <span>|</span>
		                        <a href="#">ID/PW 찾기</a>
		                    </article>
		
                            <%-- 쿠키에 saveId가 있는 경우 --%>
                            <c:if test="${!empty cookie.saveId.value}">

                                <%-- chk 변수 생성(page scope) --%>
                                <c:set var="chk" value="checked"></c:set>

                            </c:if>

		                    <label>
		                        <input type="checkbox" name="saveId" ${chk}>아이디 저장
		                    </label>
		                    
		                </form>
		                
            		</c:when>
            		
            		<%-- 로그인이 되어 있는 경우 --%>
            		<c:otherwise>
            			<article class='login-area'>
            			
            				<!-- 회원 프로필 이미지 -->
            				<a href="#">
            					<img src="/community/resources/images/user.png" id="member-profile">
            				</a>

							<!-- 회원 정보 + 로그아웃 버튼 -->
							<div class="my-info">
								<div>
									<a href="#" id="nickname">${sessionScope.loginMember.memberNickname}</a>

									<a href="/community/member/logout" id="logout-btn">로그아웃</a>
								</div>
								
								<p>
									${sessionScope.loginMember.memberEmail}
								</p>
							</div>
							
            			</article>
            		</c:otherwise>

            	</c:choose>
            
            </section>
        </section>
    </main>
    <footer>
        <p>Copyright &copy; KH Information Educational Institute M-Class</p>

        <article>
            <a href="#">프로젝트 소개</a>
            <span>|</span>
            <a href="#">이용약관</a>
            <span>|</span>
            <a href="#">개인정보처리방침</a>
            <span>|</span>
            <a href="#">고객센터</a>
        </article>
    </footer>

</body>
</html>

🔎 LoginServlet.java

package edu.kh.community.member.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import edu.kh.community.member.model.service.MemberService;
import edu.kh.community.member.model.vo.Member;

@WebServlet("/member/login")
public class LoginServlet extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
//		Post 방식 요청 시 문자 인코딩이 서버 기본값으로 지정
//		-> 한글 깨짐 -> 문자 인코딩 변경 필요
//		req.setCharacterEncoding("UTF-8");
		
//		* 모든 doPost() 메소드에 인코딩 변경 코드를 작성해야 함.. (귀찮다)
//		-> 모든 요청(전달 방식 가리지 않음) 시 req, resp에 문자 인코딩을 UTF-8로 변경
//		-> 필터(Filter)
		
//		전달된 파라미터 변수에 저장
		String inputEmail = req.getParameter("inputEmail");
		String inputPw = req.getParameter("inputPw");
		
		System.out.println(inputEmail);
		System.out.println(inputPw);
		
		// 파라미터를 VO에 세팅(롬복 확인)
		Member mem = new Member();
		mem.setMemberEmail(inputEmail);
		mem.setMemberPw(inputPw);
		
		try {
			// 서비스 객체 생성
			MemberService service = new MemberService();
			
			// 이메일, 비밀번호가 일치하는 회원을 조회하는 서비스 호출 후 결과 반환
			Member loginMember = service.login(mem);
			
			// 로그인 성공/실패에 따른 처리 코드
			
			// *** 로그인 ***
			// ID/PW가 일치하는 회원 정보를 Session Scope에 세팅하는 것
			
			// Session 객체 얻어오기
			HttpSession session = req.getSession();
			
			if(loginMember != null) { // 성공
				
				// 회원 정보를 Session에 세팅
				session.setAttribute("loginMember", loginMember);
				
				// 특정 시간 동안 요청이 없으면 세션 만료
				session.setMaxInactiveInterval(3600); // 3600초 == 1시간
				// -> 초 단위로 작성
				
				//===========================================================================
				
				// 아이디 저장(Cookie)
				
				/* Cookie : 클라이언트(브라우저)에서 관리하는 파일
				 * 
				 * - 특정 주소 요청 시마다
				 * 	 해당 주소와 연관된 쿠키 파일을 브라우저가 알아서 읽어옴
				 * 	 -> 읽어온 쿠키 파일 내용을 서버에 같이 전달함
				 * 
				 * 	 생성 및 사용 방법
				 * 
				 *   1) 서버가 요청에 대한 응답을 할 때
				 *   	쿠키를 생성한 후 응답에 쿠키를 담아서 클라이언트에게 전달
				 *   
				 *   2) 응답에 담긴 쿠키가 클라이언트에 파일 형태로 저장
				 *   
				 *   3) 이후 특정 주소 요청 시
				 *   	쿠키 파일을 브라우저가 찾아서 자동으로 요청에 실어서 보냄
				 *   
				 *   4) 서버는 요청에 실려온 쿠키 파일을 사용함
				 * 
				 * */

				// 쿠키 객체 생성
//				Cookie c = new Cookie("클라이언트쪽에 저장될 쿠키 이름", "쿠키 내용");
				Cookie c = new Cookie("saveId", inputEmail);
				
				// 아이디 저장이 체크된 경우
				if(req.getParameter("saveId") != null) {
					// 쿠키 파일을 30일 동안 유지
					c.setMaxAge(60 * 60 * 24 * 30); // 30일(1초 단위)
					
				} else {
					// 쿠키 파일을 0초 동안 유지
					// -> 기존에 존재하던 쿠키 파일에 유지 시간을 0초로 덮어씌움
					//	  == 삭제하겠다는 소리
					c.setMaxAge(0);
				}
				
				// 해당 쿠키 파일이 적용될 주소를 지정
				c.setPath( req.getContextPath() );
				// req.getContextPath() : 최상위 주소(/community)
				// -> /community로 시작하는 주소에서만 쿠키 적용
				
				// 응답 객체를 이용해서 클라이언트로 전달
				resp.addCookie(c); // 코드가 해석되는 순간 바로 전달
				
				//===========================================================================
				
			} else { // 실패
				
				session.setAttribute("message", "아이디 또는 비밀번호가 일치하지 않습니다.");
				
			}
			
			// 클라이언트 요청 -> 서버 요청 처리(Servlet) -> 응답 화면 만들어 줘(JSP 위임)
			
			// 1. forward(요청 위임)
			// - Servlet으로 응답 화면 만들기가 불편하기 때문에
			//   JSP로 req, resp 객체를 위임하여
			//	 요청에 대한 응답 화면을 대신 만듦
			
			// *** 화면이 변경되어도 요청 주소가 유지된다 ***
			
			// ex) 아이스 아메리카노 주세요 -> 	주문 받음		-> 바리스타가 만든 커피
			//		   클라이언트           캐셔(Servlet)		응답 결과(JSP)
			
			
			// 2. Redirect(재요청)
			// - 현재 Servlet에서 응답 페이지를 만들지 않고
			//	 응답 페이지를 만들 수 있는
			//	 다른 요청의 주소로 클라이언트를 이동시킴(재요청)
			
			// 클라이언트 재요청
			// -> 기존 HttpServletRequest/Response 제거
			// -> 새로운 HttpServletRequest/Response 생성
			
			// ---> 리다이렉트 시 request 객체가 유지되지 않기 때문에
			//		특정 데이터를 전달하거나 유지하고 싶으면
			//	    Session 또는 application 범위에 세팅해야 한다!
			
			// CGV 카페
			// ex) 팝콘 주세요		->	팝콘 파는 위치 알려 줌	-> (클) 팝콘 파는 곳으로 이동
			//     클라이언트			  캐셔(Servlet)		  클라이언트의 다른 주소 재요청
			
			resp.sendRedirect( req.getContextPath() );
			// req.getContextPath() : 최상위 주소 (/community)
			
			// forward
			// req.getRequestDispatcher("../index.jsp").forward(req, resp);
			
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

🔎 LogoutServlet.java

package edu.kh.community.member.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/member/logout")
public class LogoutServlet extends HttpServlet{

	// a 태그를 이용한 요청은 무조건 GET 방식
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		// *** 로그아웃 ***
		// Session Scope에 세팅된 회원 정보를 없앰
		
		// Session 얻어오기
		HttpSession session = req.getSession();
		
		// 1) Session에서 회원 정보만 없앰
//		session.removeAttribute("loginMember");
		
		
		// 2) Session 전체를 없애도 새로운 Session 만들기 (더 많이 사용되는 방법)
		session.invalidate(); // 세션 무효화
							  // 현재 세션을 없앰 -> 자동으로 새로운 세션이 생성됨
		
		// 메인 페이지로 돌아가기
		// 1) forward : 로그아웃 응답 화면을 만든다. (부적절)
		// 2) redirect : 메인 페이지 재요청 (이거!)
		//				 메인 페이지 == 최상위 주소(/community)로 요청했을 때 화면
		resp.sendRedirect( req.getContextPath() );
		
		
	}
	
}

profile
풀스택 개발자 기록집 📁

0개의 댓글