WEB8 - 세션

Leafy·2024년 1월 15일
0

중앙_자바

목록 보기
30/76

로그인 세션 만들기

가끔 뻑날 때는 / 때문일 때가 있다.


이거 빼고 새로 해보면 좋다.

footer.jsp

footer도 jsp 파일을 뺀다.

회사 정보 / 정보보안 책임자 / 연락처(사업장 소재지) / 주소

세션 만들기

Login.java 파일
이 부분을 외워야.

//세션만들기 -> 겁나 어려울 것. (너무 중요해서 외우자.)
HttpSession session = request.getSession(); //세션만들기의 시작
session.setAttribute("mname", dto.getMname()); //mname이라는 이름으로 세션 만듦
session.setAttribute("mid", dto.getMid()); //mid라는 이름으로 세션 만듦

board.jsp 파일

${sessionScope.mname }님 반갑습니다. <!-- mname이라고 한다 -->

sessionScope.뭐뭐 <- 이거를 외우라고 하심.

menu.jsp 파일
얘도 외운다. 로그인한 사람에게는 로그아웃이라고 보이게 하기.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<nav>
	<ul>
		<li onclick="url('./')"></li>
		<li onclick="url('./board')">게시판</li>
		<li onclick="url('./qna')">문의게시판</li>
		<li onclick="url('./notice')">공지사항</li>
		<li onclick="url('./login')">로그인</li>
		<li onclick="url('./logout')">로그아웃</li>
		<li onclick="url('./info')">info</li>
	</ul>
</nav>

로그아웃은 서블릿만 있으면 되고 jsp는 필요 없다.
로직을 거기다 써주기만 하면 됨.
write, update, login도 POST

로그아웃은 GET
누르면 /logout 이렇게 바로 가니까.

POST 처리 안해준 건 다 GET임.
Logout.java 서블릿

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//response.getWriter().append("Served at: ").append(request.getContextPath());
		System.out.println("get으로 들어왔어요");
		//세션 종료, 세션 삭제
		/*
		 * 세션 쿠키 (서로 반대됨)
		 * 세션 : 서버(우리는 톰캣)에 저장됨. 필요할 때마다 서버에서 불러다 써서 보안에 강력
		 * - 로그인 정보
		 * - 자바
		 * - 은닉형태. 서버가 느려질 순 있음.
		 * 
		 * 쿠키 : 클라이언트(브라우저)에 저장됨. 쿠키를 조작하면 조작된 쿠키가 서버에 올라감. 보안에 취약. 수억~군데에서 관리
		 * - 쇼핑정보, 장바구니, 방문내역, 로그인 정보 같은 것도 있다.
		 * - 스크립트(계열들이 만들어서 저장. JS같은..)
		 * - 오픈형태. 브라우저 방문하면 해당? 쿠키 볼 수 있음.
		 * 
		 * 요즘은 JWT(javascript web token) 토큰이라는 것도 쓴다.
		 */
		HttpSession session = request.getSession(); //세션이라는 객체 만들고 if문으로 불러올 것.
		if(session.getAttribute("mname") != null) { //세션이 있으면 -> 종료
			System.out.println("세션 유효시간 : " + session.getMaxInactiveInterval()); //세션이 만든지 얼마나 됐는지, 남은 시간은? 기본적으로 30분(1800). web xml에서 조정가능.
			System.out.println("mname : " + session.getAttribute("mname"));// 만들어 둔 이름을 알아야 뽑아볼 수 있다.
		}
		if(session.getAttribute("mid") != null) { //세션이 2개. 근데 어차피 종료하러 들어왔으니 if로 물을 것도 없이 로그아웃
			System.out.println("mid : " + session.getAttribute("mid"));
			
		}
		//login 페이지로 보내기
		response.sendRedirect("./login");
	}

get으로 들어왔어요
세션 유효시간 : 1800


쿠키와 세션

https://interconnection.tistory.com/74

세션 완전히 삭제

https://wickedmagic.tistory.com/132

프레임워크와 라이브러리 React, Vue, Angular

https://velog.io/@haizel/20240111-TIL-FE-%EC%8A%A4%ED%84%B0%EB%94%94-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%99%80-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-React-vs-Vue-vs-Angular


menu.jsp

<% if(session.getAttribute("mname") == null) { %>
					<li onclick="url('./login')">로그인</li>
					<% } else { %>
					<li onclick="url('./logout')">로그아웃</li>
					<% } %>

일단 이렇게 테스트.

컴파일 시기?가 다른 두 가지(jstl)

<c:import>까지 사실 세 가지
https://m.blog.naver.com/halowd/221686425368

<%@ include file="menu.jsp" %>

일단 파일에 붙여넣고, 자바를 실행시킨다.
board.jsp에서는 jstl로 써둔 menu.jsp가 잘 나옴.
(menu.jsp에서 jstl 상단에 taglib 줄을 없애서 와서 실행??)

<jsp:include page="menu.jsp"></jsp:include>

최종 결과를 파일에 붙여넣는다.

다시 전자로 바꾼다.

이렇게 차이가 난 이유는.. menu.jsp에서 taglib을 빼서임. (어차피 갖다쓰면 중복되니까..)
-> 근데 / url에서 해결이 안 돼서(/index랑 같은 거라 index.jsp 손봤는데도 ㅠ)
menu.jsp에 taglib 다시 씀.

taglib prefix부분을 뒤로 보내면 된다고 한다.
=> https://blog.naver.com/aladdin76/221033241746

Login.java

서블릿에서
로그인이 됐을 때 이미 로그인했다~ 하고 알려줄 것.

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		response.getWriter().append("Served at: ").append(request.getContextPath());
		HttpSession session = request.getSession();
		RequestDispatcher rd = null;
		if (session.getAttribute("mname") != null) {
			rd = request.getRequestDispatcher("already.jsp");
		} else {
			rd = request.getRequestDispatcher("login.jsp");
		}
		rd.forward(request, response);
	}

board.jsp

로그인한 사람한테만 글쓰기 버튼 보여주기 (jstl)

<c:if test="${sessionScope.mname ne null }">
  <button onclick="url('./write')">글쓰기</button>
</c:if>
  • (/write)url로 들어오는 것도 막자. Write.java 서블릿
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		response.getWriter().append("Served at: ").append(request.getContextPath());
		HttpSession session = request.getSession();
		if(session.getAttribute("mname") == null) {
			response.sendRedirect("./login");
		} else {
			RequestDispatcher rd = request.getRequestDispatcher("write.jsp");
			rd.forward(request, response);
		}
	}

관리자 사이트는 따로 파기도 한다.

글 작성자 외래키!

이제는 자기 글에만 수정, 삭제 보이도록 할 것.


원래 이렇게 있던 것을
board_writer 열을 삭제하고
mno 열을 새로 추가함. (null 허용 X)

여기까지 하고 저장 먼저 한다.

HeidiSQL에서 외래키 설정

sql문

ALTER 코드 (기존 데이터가 있어서 이렇게...)

ALTER TABLE `board`
   ADD CONSTRAINT `FK_board_member` FOREIGN KEY (`mno`) REFERENCES `member` (`mno`) ON UPDATE NO ACTION ON DELETE NO ACTION;
ALTER TABLE `board`
   ADD COLUMN `mno` INT NOT NULL AFTER `board_content`,
   DROP COLUMN `board_write`;

join

SELECT b.board_no, b.board_title, 
		m.mname,
		b.board_date, b.board_count
FROM board b JOIN member m
ON (b.mno=m.mno)
ORDER BY b.board_no DESC
LIMIT 0, 10

join한 view

select `b`.`board_no` AS `board_no`,
`b`.`board_title` AS `board_title`,
`m`.`mname` AS `mname`,
if(date_format(current_timestamp(),'%Y-%m-%d') = 
date_format(`b`.`board_date`,'%Y-%m-%d'),
date_format(`b`.`board_date`,'%h:%i'),
date_format(`b`.`board_date`,'%m-%d')) AS `board_date`,
`b`.`board_count` AS `board_count` 
from (`board` `b` join `member` `m` on(`b`.`mno` = `m`.`mno`)) 
order by `b`.`board_no` desc limit 0,10

실습땜에 이렇게 됐지만 처음부터 join 염두에 두고 뷰를 짜는 게 좋다.


글쓴 사람

BoardDTO에 mid도 만든다.
session에 mname과 함께 mid를 올려둔 이유가 이거 하려고.

DAO에서는 이렇게 바뀜.

public BoardDTO detail(int no) {
		BoardDTO dto = new BoardDTO();
		Connection con = DBConnection.getInstance().getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql = "SELECT b.board_no, b.board_title, b.board_content, m.mname AS board_write, m.mid, "
				+ "b.board_date, b.board_count "
				+ "FROM board b JOIN member m ON b.mno=m.mno "
				+ "WHERE b.board_no=?";
		
		try {
			pstmt = con.prepareStatement(sql);
			pstmt.setInt(1, no);
			rs = pstmt.executeQuery();
			
			// 글 하나니까 while아니고 if
			if(rs.next()) {
				dto.setNo(rs.getInt("board_no"));
				dto.setTitle(rs.getString("board_title"));
				dto.setContent(rs.getString("board_content"));
				dto.setWrite(rs.getString("board_write"));
				dto.setDate(rs.getString("board_date"));
				dto.setCount(rs.getInt("board_count"));
				dto.setMid(rs.getString("mid"));
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		
		
		return dto;
	}

detail.jsp에서
${detail.write } / ${detail.mid } / ${sessionScope.mid }
를 하면 순서대로 글쓴사람, 글쓴사람id, 로그인한사람id가 보인다.

글쓰기

public int write(BoardDTO dto) {
		int result = 0;
		
		Connection con = DBConnection.getInstance().getConnection();
		PreparedStatement pstmt = null;
		String sql = "INSERT INTO board (board_title, board_content, mno) " //외래키 mno 넣고, 서브쿼리 날릴 것.
				+ "VALUES (?, ?, (SELECT mno FROM member WHERE mid=?))"; //mid 갖다가 mno로 insert
		
		try {
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, dto.getTitle());
			pstmt.setString(2, dto.getContent());
			pstmt.setString(3, dto.getMid());//수정완
			result = pstmt.executeUpdate();//영향받은 행을 result에 저장한다.
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(null, pstmt, con);
		}
		
		
		return result;
	}

detail.jsp에서 로그인 세션의 mid와 글쓴 mid가 일치하는 사람한테만 글삭제, 글수정 띄우기

<c:if test="${detail.mid eq sessionScope.mid }">
							<img alt="delete" src="./img/delete.png" onclick="del()">
							<img alt="edit" src="./img/write_pencil.png" onclick="update()">
							
							</c:if>

Write.java 서블릿에서
한 번 더 거른다.

https://www.postman.com/
같은 곳은...

0개의 댓글