[TIL] Day33 - 로그인 / 템플릿

JIONY·2022년 9월 21일
0
post-thumbnail

지금 블로그 일주일 밀려서 매일 킹받고 있는 사람 됨ㅋㅋㅋㅋ 이제 수업 진행 속도가 왕 빨라지고 코드 복습하거나 과제 하다보면 그것만으로도 하루가 부족해서 일주일 내내 3,4시에 잤음. 약간 각성상태처럼 깨어 있는 건지 아닌 건지 모르게 눈 뜨고 걷고 먹고 기절하고 했는데 그래도 별 다른 문제가 없다는 게 신기했닼ㅋㅋㅋ 게시판이 점점 완성되어가고 있어서 재밌는데 수업 노트에 있는 걸 그대로 옮겨서 블로그에 구구절절 새로 작성하려니 시간이 배로 들어서 이제 포인트 위주로 정리 하려고 함. 밀린 거 이번 주 내로 만회한다..^^..


로그인

  • 등록된 회원인지를 판단하기 위해 회원 목록을 조회 하는 건데 조회 조건을 설정하기 위해 입력이 필요함
  1. 입력: GET (id, pw)
  2. 처리: 로그인 판정 POST
  3. 결과
    a. 성공: 홈(or 이전 페이지)로 이동
    b. 실패: redirect to 로그인 정보 입력 페이지

문제점1

  • 로그인 정보 입력 페이지일 때, 정상적으로 로그인 메뉴를 진입한 건지, 로그인 실패로 다시 되돌아온 건지 구분이 불가능함

해결책

  • 로그인 실패로 redirect될 때, url에 파라미터를 추가
    • error에 value를 붙여 에러 원인을 구분할 수 있음
      ex. login?error=1

### Controller - error가 null이면 정상 접근, null이 아니면 로그인 실패로 인한 접근 - jsp에서 ${param.error}가 null이 아닐 때 로그인 입력 화면에 보여 줄 메시지를 추가할 수 있음
@PostMapping("/login")
public String login(@ModelAttribute MemberDto inputDto) {
	MemberDto findDto = memberDao.selectOne(inputDto.getMemberId());
	if(findDto == null) {
		return "redirect:login?error";
	}
	boolean passwordMatch = findDto.getMemberPw().equals(inputDto.getMemberPw());
	if(passwordMatch) {
		return "redirect:/";
	}else {
		return "redirect:login?error";
	}
}

문제점2

  • 로그인 여부를 확인할 수 없음
    • 로그인 버튼이 계속 노출되고, 접근 권한이 다른 메뉴가 구분되는 등의 차이점이 없음

해결책

  • 로그인 상태를 유지해야 함
    • 어딘가에 로그인 아이디를 저장, 필요할 때 그 기록을 확인

HttpSession

  • 로그인 상태를 유지하려면
  • 로그인 성공 시, HttpSession에 로그인 아이디를 저장, 필요할 때 세션을 검사해 로그인 기록을 확인
    • HttpSession 도구 사용
    • .setAttribute("key", value): 저장 값 설정
    • .getAttribute("key"): 저장된 값 불러오기
    • .removeAttribute("key"): 저장된 값 삭제(로그아웃 시 활용 가능)

* session: 유저는 볼 수 없고, 보안 수준이 굉장히 높음. 저장된 정보가 많으면 조회에 시간이 많이 걸리므로 중요한 정보만을 최소한으로 저장해야 함

Controller

@PostMapping("/login")
Public String login(@ModelAttribute MemberDto inputDto,
    			HttpSession session) {
 
  MemberDto findDto = memberDao.selectOne(inputDto.getMemberId());
  if(findDto == null) {
  	return "redirect:login?error"; //redirect는 항상 GET
  }
  boolean passwordMatch = inputDto.getMemberPw().equals(findDto.getMemberPw());
  if(passwordMatch) {
  	session.setAttribute("loginId", inputDto.getMemberId());//findDto에서 꺼내도 무관
    return "redirect:/";
  }else {
    return "redirect:login?error";
 }
    		
}

로그인 상태 확인(jsp)

  • home.jsp에서 로그인 상태를 확인

    • ${sessionScope.loginId}
    • 축약해서 ${loginId}
  • 로그인을 성공했을 때에만 session 데이터가 생김

    • ${loginId}이 null이 아니면 로그인 상태인 것을 활용해 회원/비회원 메뉴 구분 가능

세션 정보 불러오기(Controller)

  • 세션에서 로그인 정보를 가져와야 할 때가 있음
    • ex. 마이페이지에 로그인한 회원의 정보를 출력할 때

세션에 들어있는 아이디(String)를 꺼냄

  • 파라미터로 아이디 정보를 넘기지 않음
  • 세션 데이터는 Object 형태로 저장되므로 꺼내려면 다운캐스팅 필요
  • 로그인 아이디를 저장한 이름인 loginId로 불러옴
String memberId = (String)session.getAttribute("loginId");

기타 문제점

  • 로그인을 홈에서만 검사하고 다른 페이지에서는 로그인 상태 확인이 안됨
    • 해결책: 템플릿 페이지 include
  • 모든 페이지에 주소를 직접 입력해서 접근할 수 있음
    • 해결책: Interceptor 구현

* Day33(현재 글) ~ Day34에서 다룸


로그아웃

  • 로그아웃 시, 기록한 session 값을 삭제 후 홈으로 돌아가기
    • .removeAttribute(”key”, value)

Controller

@GetMapping("/logout")
public String logout(HttpSession session) {
	session.removeAttribute("loginId");
    return "redirect:/";
}


템플릿 페이지

필요한 이유

  • 어느 페이지에나 노출되는 정보/메뉴 존재하므로 공통으로 사용할 틀을 생성해 쉽게 불러오고 일관성을 유지
    • header.jsp, footer.jsp를 생성해 템플릿 페이지로 사용
  • 로그인을 홈에서만 검사하고 다른 페이지에서는 로그인 상태 확인이 안되는 문제가 있음
    • 다른 페이지에서 검사하고 그 결과를 불러올 수 있도록 설정
    • header.jsp에서 로그인을 검사, 다른 페이지에는 header.jsp를 include해서 언제든 session 데이터를 불러올 수 있도록 설정

템플릿 페이지 구현

  • 두 파일이 합쳐져야 하나의 페이지가 되도록 html 태그를 열고 닫기
  • header에 메뉴 링크 설정 시, 절대경로 사용
    • 상대경로 사용 시 주소가 "/"인 home에서는 정상작동하나, 나머지 페이지에서는 모두 에러 발생

Page Include

  • 절대경로 사용

정적 Include

jsp가 컴파일되기 전에 include한 파일(header.jsp)이 부모 페이지에 삽입되어 컴파일됨

  • 장점 : include 페이지에서 선언한 변수를 부모 페이지에서 별도의 변수 선언 없이 사용 가능
  • 단점 : 부모 페이지에 include한 파일이 많을 경우 inlucde 페이지에서 선언된 변수를 추적해야 함. 유지보수 어려움 (강결합)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/template/header.jsp" %>
	<div align="center">
		<h1>안녕하세요</h1>
	</div>
<%@ include file="/WEB-INF/views/template/footer.jsp" %>

동적 include

사용자가 부모 페이지 호출 시 실행되는 시점에 include한 파일이 삽입됨

  • 장점
    • 동적 include한 페이지에 변수를 생성해도 에러 안남 → 결합도가 낮아짐
    • 파라미터 전달 가능
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:include page="/WEB-INF/views/template/header.jsp">
	<jsp:param value="메인" name="title"/>
</jsp:include>
	<h1>안녕하세요</h1>
<jsp:include page="/WEB-INF/views/template/footer.jsp"></jsp:include>

정적 vs. 동적 include

  • 정적: 딸기, 바나나, 키위를 한번에 갈아서(렌더링) 주스 만들기
    • 각 과일 특징이 사라짐 → 데이터가 다 사라지고 완전한 화면이 나온다음에 렌더링
  • 동적: 딸기/바나나/키위 따로 갈아서 합치기
    • 변수가 따로 관리됨(공유되지 않음) 렌더링하고 화면을 만들기

정적/동적 include

0개의 댓글