초급의 끄적거림

[프로젝트] 세션 (session) / web.xml / 세션변수 / application, response내부객체 / 로그인, 로그아웃 본문

카테고리 없음

[프로젝트] 세션 (session) / web.xml / 세션변수 / application, response내부객체 / 로그인, 로그아웃

codingD 2019. 9. 11. 17:54

1. 세션 (session)


  - HttpSession session

  - 요청한 사용자에게 개별적으로 접근

  - 선언된 세션 변수는 전역적 성격으로 유지 된다

  - 일정 시간동안 이벤트가 발생되지 않으면 자동 삭제 (ex. 일정 시간 후 자동 로그아웃) - 일정시간은 설정 가능

<%
    out.print("현재 세션 유지 시간 ");
    out.print(session.getMaxInactiveInterval()); //단위 : 초, get으로 값을 얻어왔고 set으로 설정 가능
    out.print("초 (30분)"); // 1800초 = 30분 (대체로 20분으로 설정)
    out.print("<hr>");
%>

세션 유지 시간 기본값

 1-1) 세션 유지 시간 변경

   - 페이지마다 다르게 줄 수 있지만 관리가 어려워서 대체로 일괄 지정

<%
	session.setMaxInactiveInterval(60*10);
   	out.print("변경된 세션 유지 시간");
    	out.print(session.getMaxInactiveInterval());
    	out.print("초 (10분)");
   	out.print("<hr>");
%>

 

 1-2) 배치관리자 web.xml 

   - 위치 : /WEB-INF/web.xml

   - 세션시간설정, 환경설정 등 지정

   - web.xml이 수정되면 반드시 서버 재시작 할 것

  (지금은 서버를 한 자리에서 스스로 관리를 하고 있어서 문제가 없지만, 다른 곳에 서버가 있을 때 임의 재시작은 위험)

   - web.xml에 그동안 보지못한 태그들 (ex. <welcome-file>) 이 있는데 필요에 의해서 만든 사용자 정의 태그

   - 사용자 정의 태그 : custom tag → 사용 방법 : 외부라이브러리가 있으면 불러서 사용

    : 손으로 직접 치지 않고 Ctrl+Space 를 사용해서 불러옴

 사용자 정의 태그

  <database>

     <url></url>

     <driver></driver>

     <username></username>

     <password></password>

  </database>

 

  - web.xml 에서 세션 시간을 설정해줌 (session-config 태그를 사용)

<!-- 세션 유지 시간 설정 60*10-->
<session-config>
	<session-timeout>600</session-timeout>
</session-config>

 

2. 세션 변수


  - myweb프로젝트의 모든 페이지에서 공유되는 전역변수

  - 별도의 자료형이 없다

 

  2-1) 세션변수 선언, 세션변수값 가져오기

     - session에서 선언했고 현재 세션은 유지시간을 10분으로 설정했기 때문에 아무 이벤트가 없다면 10분 뒤 null 값

<%
    //세션변수 선언
    session.setAttribute("s_id", "fullmoon");
    session.setAttribute("s_pw", "12341234");
    
    //세션변수값 가져오기
    Object obj=session.getAttribute("s_id"); 			//처음 가져올 때는 자료형 object
    String s_id=(String)obj;							//이후에는 필요에 맞춰 변형해서 사용
    String s_pw=(String)session.getAttribute("s_pw"); 
    
    out.print("세션변수 s_id : " + "<hr>");
    out.print("세션변수 s_pw : " + "<hr>");
%>

 

 2-2) 세션변수 강제 삭제 / 모든 값 강제 삭제

<%
    //세션변수 강제 삭제 (=로그아웃)
    session.removeAttribute("s_id");
    session.removeAttribute("s_pw");
    out.print("세션변수 삭제 후 <hr>");
    out.print("세션변수 s_id : " + session.getAttribute("s_id") + "<hr>");
    out.print("세션변수 s_pw : " + session.getAttribute("s_pw") + "<hr>");
    
    //세션영역에 있는 모든 값 전부 강제 삭제
    session.invalidate();    
%>

 

  2-3) 세션 객체에서 발급해주는 아이디 (총 32자)

  - 직접 아이디를 만들 수 있다면 문제가 없지만 아닐 경우에 사용할 수 있는 임시 아이디

  - ex) 네이버에 들어가는 불특정 다수들에게 임시 아이디를 부여하여 각자를 구분함

         로그인 없이 장바구니에 물건을 담을 수 있는 경우 (1. 쿠키를 사용하기도 하지만 2. 임시 아이디 사용)

<%
    out.print("세션 임시 아이디 : ");
    out.print(session.getId());
    out.print("<hr>");
%>

 

 

3. application 내부객체


(참고 : https://ninearies.tistory.com/54)

  - ServletContext application

  - 서버에 대한 정보를 관리하는 객체

  - 사용자 모두가 공유하는 전역적 성격의 객체

 

 3-1) bbs 폴더의 실제 경로

   - 물리적인 경로 (.metadata는 이클립스에서 시작했기 때문에 생긴 경로)   D:\java0514\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\myweb\bbs 

   - 실제경로 → D:\java0514\workspace\myweb\WebContent\bbs

   - 웹경로  → http://172.16.83.13:8090/myweb/bbs

out.print(application.getRealPath("/bbs"));		//추천방법
out.print("<br>");
	
out.print(request.getRealPath("/bbs"));
out.print("<br>");	

 

 3-2) application 내장 변수

application.setAttribute("uname", "장만월");
out.print(application.getAttribute("uname"));

 

4. response 내부 객체


  - 요청한 사용자에게 응답할 때

//페이지 이동
response.sendRedirect("파일명");

//요청한 사용자에게 응답 메세지 전송
PrintWriter write=response.getWriter();

 

5. 회원테이블 - 로그인/로그아웃


 5-1) sql 폴더에 'member.sql' 만들고 member 테이블 만들기 & 테스트용 행추가 

  ★ 행 추가 후 commit; 잊지 말기

  회원테이블

  CREATE TABLE member (
      id        VARCHAR(10)  NOT NULL,  -- 아이디, 중복 안됨, 레코드를 구분하는 컬럼 
      passwd    VARCHAR(10)  NOT NULL,   -- 패스워드
      mname    VARCHAR(20)  NOT NULL,   -- 성명
      tel        VARCHAR(14)  NULL,       -- 전화번호
      email      VARCHAR(50)  NOT NULL  UNIQUE,  -- 전자우편 주소, 중복 안됨 

      (pk : 절대 null값 허용 X, unique : pk와 같은 성격이지만 null값 한 번 허용)
      zipcode   VARCHAR(7)    NULL,       -- 우편번호, 101-101
      address1  VARCHAR(255) NULL,       -- 주소 1
      address2  VARCHAR(255) NULL,       -- 주소 2(나머지주소)
      job         VARCHAR(20)  NOT NULL,   -- 직업
      mlevel     CHAR(2)         NOT NULL,   -- 회원 등급, A1, B1, C1, D1, E1, F1 (명령 정책일 뿐 필수 아님), 기본 등급 : D1
      mdate     DATE             NOT NULL,   -- 가입일    
      PRIMARY KEY (id)      -- id에 pk 

     (pk 여러 개 지정가능 : 다른 칼럼에 pk를 넣으려면 primary key(id, mdate) 등과 같이 , 로 넣을 수 있음 

      but 칼럼명에 붙여서 바로 primary key 제한 조건으로 넣으면 에러남)
  );

  테스트용 행추가 (3개)

  INSERT INTO member (id, passwd, mname, tel, email, zipcode, address1, address2, job, mlevel, mdate)
  VALUES ('fullmoon', '123123', '장만월', '1300-1300', 'fulmoon@email.com', '04536', 

  '서울특별시 중구 명동', '80', 'A01', 'A1', '2019-09-11');

  INSERT INTO member (id, passwd, mname, tel, email, zipcode, address1, address2, job, mlevel, mdate)
  VALUES ('okgoo', '123123', '구찬성', '4040-1234', 'okgoo@email.com', '12345', 

  '서울특별시 종로구 관철동', '코아빌딩5층', 'A02', 'D1', '2019-09-11');

  INSERT INTO member (id, passwd, mname, tel, email, zipcode, address1, address2, job, mlevel, mdate)
  VALUES ('magod', '123123', '마고신', '1234-1234', 'magod@email.com', '77777',

  '서울특별시 중구 명동', '1', 'A03', 'D1', '2019-09-11');

3개 행이 추가 된 모습

  5-2) 회원 로그인

   - net.member 패키지를 만들고 MemberDAO.java 와 MemberDTO.java 만들기

   MemberDTO.java

package net.member;

public class MemberDTO {
	
		    private String id;
		    private String passwd;
		    private String mname;
		    private String tel;
		    private String email;
		    private String zipcode;
		    private String address1;
		    private String address2;
		    private String job;
		    private String mlevel;
		    private String mdate;
		    
		    //default constructor (기본 생성자)
		    public MemberDTO(){}

		    
		    //setter, getter
			public String getId() {
				return id;
			}

			public void setId(String id) {
				this.id = id;
			}

			public String getPasswd() {
				return passwd;
			}

			public void setPasswd(String passwd) {
				this.passwd = passwd;
			}

			public String getMname() {
				return mname;
			}

			public void setMname(String mname) {
				this.mname = mname;
			}

			public String getTel() {
				return tel;
			}

			public void setTel(String tel) {
				this.tel = tel;
			}

			public String getEmail() {
				return email;
			}

			public void setEmail(String email) {
				this.email = email;
			}

			public String getZipcode() {
				return zipcode;
			}

			public void setZipcode(String zipcode) {
				this.zipcode = zipcode;
			}

			public String getAddress1() {
				return address1;
			}

			public void setAddress1(String address1) {
				this.address1 = address1;
			}

			public String getAddress2() {
				return address2;
			}

			public void setAddress2(String address2) {
				this.address2 = address2;
			}

			public String getJob() {
				return job;
			}

			public void setJob(String job) {
				this.job = job;
			}

			public String getMlevel() {
				return mlevel;
			}

			public void setMlevel(String mlevel) {
				this.mlevel = mlevel;
			}

			public String getMdate() {
				return mdate;
			}

			public void setMdate(String mdate) {
				this.mdate = mdate;
			}


			//에러를 잡기 위해서 toString까지
			@Override
			public String toString() {
				return "MemberDTO [id=" + id + ", passwd=" + passwd
						+ ", mname=" + mname + ", tel=" + tel + ", email="
						+ email + ", zipcode=" + zipcode + ", address1="
						+ address1 + ", address2=" + address2 + ", job=" + job
						+ ", mlevel=" + mlevel + ", mdate=" + mdate + "]";
			};
		    
}//class end

 

  MemberDAO.java

package net.member;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import DBPKG.DBOpen;

public class MemberDAO {
	String mlevel=null;
    try{
    	Connection con=DBOpen.getConnection();
        StringBuidler sql=new StringBuilder();
        
        //회원 로그인 (성공하면 회원 등급 가져오기)
        //단, 비회원, 탈퇴회원은 제외
        sql.append(" SELECT mlevel ");
        sql.append(" FROM member ");
        sql.append(" WHERE id=? AND passwd=? ");
        sql.append(" AND mlevel IN ("'A1', 'B1', 'C1', 'D1') );
        
        PreparedStatement pstmt=con.prepareStatement(sql.toString());
		  pstmt.setString(1, dto.getId());
		  pstmt.setString(2, dto.getPasswd());
		  
		  ResultSet rs=pstmt.executeQuery();
		  if(rs.next()){
		  	mlevel=rs.getString("mlevel");
		  }else{
		  	mlevel=null;
		  }//if end
    }catch(Exception e){
      System.out.println("로그인 실패 : "+e);
    }//try end
}//class end
	

 

  5-3) member 폴더와 ssi.jsp 만들기 

    - 회원가입과 관련된 것들을 넣기 위한 폴더

    - 자주 써야하는 것들을 ssi.jsp에 넣기

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

<%@page import="java.io.*"%>
<%@page import="java.util.*"%>
<%@page import="java.sql.*"%>

<%@page import="net.utility.*"%>
<%@page import="net.member.*"%>

<jsp:useBean id="dao" class="net.member.MemberDAO"></jsp:useBean>
<jsp:useBean id="dto" class="net.member.MemberDTO"></jsp:useBean>

<% request.setCharacterEncoding("UTF-8");%>

 

  5-4) loginForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="auth.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문시작 loginForm.jsp-->
	<h3>* 로 그 인 *</h3>
	<div class=login>
<% if(s_id.equals("guest") || s_passwd.equals("guest") || s_mlevel.equals("guest")){ %> <!-- 세 개 중 아무거나 guest인 경우 로그인하지 않았다는 것을 알리기 위함 -->	
	<form name="loginfrm" method="post" action="loginProc.jsp" onsubmit="return loginCheck(this)"> <!-- get 방식으로 하면 보안이 안됨 -->
	<table  class="table">
	<tr>
	  <td>
	 	<input type="text" name="id" placeholder="아이디" required>
	  </td>
	  <td rowspan="2">
		<input type="image" src="../images/bt_login.gif" style="cursor: pointer"> <!-- 로그인과 관련된 이미지  -->
		<!-- s
			 cursor:pointer 커서손모양
			 <input type=images>기본속성이 submit	
		-->
	  </td>
	</tr>
	<tr>
	  <td>
		<input type="password" name="passwd" placeholder="비밀번호" required>
	  </td>
	</tr>
	<tr>
	  <td colspan="2">
		아이디 저장 
		&nbsp; &nbsp; 
		|  회원가입 
		&nbsp; &nbsp; 
		| 아이디/비번찾기
	  </td>
	</tr>
	</table>
	</form>
<%
	}else{ //로그인에 성공했을 경우, 로그아웃이 떠야함
		out.println("<strong>" + s_id  + "</strong>");
		out.println("<a href='logout.jsp'>[로그아웃]</a>");
		out.println("<br><br>");
		out.println("[회원정보수정]");
		out.println("[회원탈퇴]");
	}//if end

%>
</div>
<!-- 본문끝 -->
<%@ include file="../footer.jsp"%>

 

  5-5) myscript.js 에 'loginCheck()'이라는 함수로 아이디와 비번의 유효성검사

  function loginCheck(f){
    	  //로그인 유효성 검사
    	  //1) 아이디 5~10글자 이내
    	  var id=f.id.value;
    	  id=id.trim();
    	  if(id.length<5 || id.length>10){
    		  alert("아이디가 5~10자 이내인지 확인해주세요");
    		  return false;
    	  }//if end
    	  
    	  //2) 비밀번호 5~10글자 이내
    	  var passwd=f.passwd.value;
    	  passwd=passwd.trim();	//공백 없애주기
    	  if(passwd.length<5 || passwd.length>10){
    		  alert("비밀번호를 5~10자 이내인지 확인해주세요");
    		  f.passwd.focus(); //커서 가져다 두기
    		  return false;  
    	  } 
    	  return true;
      }//loginCheck() end

유효성 검사가 제대로 수행이 될 경우

 

 

  5-6) loginProc.jsp 

  5-7) session 만들기

      - 다른 페이지에서도 사용할 수 있도록 session을 만들어 줌

      - 로그인을 하게 되면 로그인이 있던 자리에 로그아웃에 대한 버튼이 생겨야 함 

      - 일정시간이 지나면 자동으로 로그아웃이 될 수 있게 session을 사용하여 가져옴

      - loginProc.jsp 의 내용 수정

 

- 로그인을 하지 않은 상태에서는 session에 guest를 올려 줄 것

- member 폴더에 auth.jsp를 만들어서 계속 써야할 session을 넣어줄 것. 필요할 때마다 auth.jsp에서 가져다 쓰기 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp" %>
<%@ include file="../header.jsp"%>
<!-- 본문시작 loginProc.jsp-->
	<h3>*로그인 결과*</h3>
<%
	String id =request.getParameter("id").trim();
	String passwd =request.getParameter("passwd").trim();
	
	dto.setId(id);
	dto.setPasswd(passwd);
	String mlevel=dao.loginProc(dto);
	if(mlevel==null){
		out.print("<p>아이디와 비밀번호를 확인해주세요.</p>");
		out.print("<p><a href='javascript:history.back()'>[다시시도]</a></p>");
	}else{
		//out.print("<p>로그인 완료</p>");
		//out.print(mlevel);
		//session으로 만들어줌 
		session.setAttribute("s_id", id);
		session.setAttribute("s_passwd", passwd);
		session.setAttribute("s_mlevel", mlevel);
		
		//첫 페이지로 이동
		String root=Utility.getRoot();
		response.sendRedirect(root+"/index.jsp");
	}//if end

%>	
	
<!-- 본문끝 -->
<%@ include file="../footer.jsp"%>

  

로그인이 완료 되면 fullmoon의 mlevel이었던 A1이 뜸
잘 못 입력한 경우

 

 

 

5-8) loginForm.jsp에 session 적용

 - include를 이용해 auth.jsp 파일을 연결해줌

 - <%%> 안에 세 개 중 하나라도 guest가 나오면 로그인을 하지 않았음을 나타냄

 - else 문에 guest가 아니면 로그인 되었다는 것을 알림

 

  - 위의 과정들이 올바르게 수행 된 경우, login 페이지를 눌렀을 때 로그인 정보가 뜨게 됨

 

Comments