JSP

JSP 웹 프로그래밍 - 웹 쇼핑몰 만들기 04 (상품 등록 페이지의 보안 처리, 예외 처리 페이지, 로그 기록하기)

로기221 2023. 3. 6. 12:23
728x90
반응형

 


웹 쇼핑몰 만들기 01 >>>  https://rogi221.tistory.com/93

웹 쇼핑몰 만들기 02 >>>  https://rogi221.tistory.com/101

웹 쇼핑몰 만들기 03 >>>  https://rogi221.tistory.com/105

 

 

 


 

10. 상품 등록 페이지의 보안 처리하기

 

 

 

[웹 쇼핑몰] 상품 등록 페이지의 보안 처리하기

 

 

 

로그인 인증을 통해 상품 등록 페이지에 접근하기

 

  • 웹 서버에 사용자와 역할 설정하기
// tomcat-users.xml


  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="admin"/>		<< 추가
  <user username="tomcat" password="tomcat1234" roles="tomcat"/>
  <user username="both" password="both1234" roles="tomcat,role1"/>
  <user username="role1" password="role1234" roles="role1"/>
  <user username="admin" password="admin1234" roles="admin"/>	<< 추가

 

 

  • 웹 애플리케이션 배포 설명자 web.xml 만들기
// WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
	<security-role>
		<description></description>
		<role-name>admin</role-name>
	</security-role>
	<security-constraint>
		<display-name>WebMarket Security</display-name>
		<web-resource-collection>
			<web-resource-name>WebMarket</web-resource-name>
			<discription></discription>
			<url-pattern>/appProduct.jsp</url-pattern>
		</web-resource-collection>
		<auth-constraint>
			<description>권한 관리자명</description>
			<role-name>admin</role-name>
		</auth-constraint>
	</security-constraint>
	<login-config>
		<auth-method>FORM</auth-method>
		<form-login-config>
			<form-login-page>/login.jsp</form-login-page>
			<form-error-page>/login_failed.jsp</form-error-page>
		</form-login-config>
	</login-config>
</web-app>

 

 

  • 로그인 페이지 만들기
// login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css"/>
<title>Login</title>
</head>
<body>
	<jsp:include page="menu.jsp"/>
	<div class="jumbotron">
		<div class="container">
			<h1 class="display-3">로그인</h1>
		</div>				
	</div>
	<div class="container" align="center">
		<h3 class="form-signin-heading">Please sign in</h3>
		<%
			String error = request.getParameter("error");
			if(error != null) {
				out.println("<div class='alert alert-danger'>");
				out.println("아이디와 비밀번호를 확인해주세요");
				out.println("</div");
			}
		%>
		<form class="form-signin" action="j_security_check" method="post">
			<div class="form-group">
				<label for="inputUserName" class="sr-only">User Name</label>
				<input type="text" class="form-control" placeholder="ID" name='j_username' required autofocus>
			</div>
			<div class="form-group">
				<label for="inputPassword" class="sr-only">Password</label>
				<input type="password" class="form-control" placeholder="Password" name='j_password' required>
			</div>
			<button class="btn btn btn-lg btn-success btn-block" type="submit">로그인</button>
		</form>
	</div>
</body>
</html>

 

  • 로그인 인증 실패 페이지 만들기
// login_failed.jsp

	<%
		response.sendRedirect("login.jsp?error=1");
	%>

 

 

 

로그아웃 작성하기

 

  • 로그아웃 페이지 만들기
// logout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%
	session.invalidate();
	response.sendRedirect("addProduct.jsp");
%>

 

 

  • 상품 등록 페이지 수정하기
// addProduct.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
    ... (생략) ...
    
   <jsp:include page="menu.jsp"/>
      <div class="jumbotron">
         <div class="container">
            <h1 class="display-3"><fmt:message key="title"/></h1>
         </div>
      </div>
      <div class="container">
         <div class="text-right">
            <a href="?language=ko">Korean</a> | <a href="?language=en">English</a>
            <a href="logout.jsp" class="btn btn-sm btn-success pull-right">logout</a>	<< 추가
         </div>
         <form name="newProduct" action="./processAddProduct.jsp" class="form-horizontal" method="post" enctype="multipart/form-data">
            <div class="form-group row">
            
            ... (생략) ...

 

 

 

 

 

 

 

11. 예외 처리 페이지 만들기

 

[웹 쇼핑몰] 예외 처리 페이지 만들기

 

 

 

 

page 디렉티브 태그에 errorPage 속성을 이용하여 오류 페이지 호출하기

  • 오류 페이지 작성하기
// exceptionNoProductId.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css"/>
<title>상품 아이디 오류</title>
</head>
<body>
	<jsp:include page="menu.jsp"/>
	<div class="jumbotron">
		<div class="container">
			<h2 class="alert alert-danger">해당 상품이 존재하지 않습니다.</h2>
		</div>
	</div>
	<div class="container">
		<p><%=request.getRequestURL() %>?<%=request.getQueryString() %>
		<p> <a href="products.jsp" class="btn btn-secondary">상품 목록&raquo;</a>
</body>
</html>

 

  • 상품 상세 보기 페이지 수정하기
// product.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="dto.Product" %>
<%@ page import="dao.ProductRepository" %>
<%@ page errorPage="exceptionNoProductId.jsp" %> 	<<< 추가
<jsp:useBean id="productDAO" class="dao.ProductRepository" scope="session"/>
 
 ... (생략) ...

 

 

 

 

web.xml 파일에 오류 코드로 오류 페이지 호출하기

  • web.xml 파일에 추가 작성하기
// web.xml

<web-app>
	... (생략) ...
    <error-page>
		<error-code>404</error-code>
		<location>/exceptionNoPage.jsp</location>
	</error-page>
</web-app>

 

 

  • 오류 페이지 작성하기
// exceptionNoPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css"/>
<title>페이지 오류</title>
</head>
<body>
	<jsp:include page="menu.jsp"/>
	<div class="jumbotron">
		<div class="container">
			<h2 class="alert alert-danger">요청하신 페ㅣ지를 찾을 수 없습니다.</h2>
		</div>
	</div>
	<div class="container">
		<p><%=request.getRequestURL()%></p>
		<p> <a href="products.jsp" class="btn btn-secondary">상품 목록&raquo;</a>
	</div>
</body>
</html>

 

 

 

 

 

 

 

12. [웹 쇼핑몰] 로그 기록하기

 

[웹 쇼핑몰] 로그 기록하기

 

 

 

 

 

필터 처리로 로그 기록하기

// LogFilter.java

package filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class LogFilter implements Filter {

	public void init(FilterConfig config) throws ServletException {
		System.out.println("WebMarket 초기화...");
	}
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
		System.out.println("접속한 클라이언트 IP : " + request.getRemoteAddr());
		long start = System.currentTimeMillis();
		System.out.println(" 접근한 URL 경로 : " + getURLPath(request));
		System.out.println(" 요청 처리 시작 시각 : " + getCurrentTime());
		chain.doFilter(request,  response);
		
		long end = System.currentTimeMillis();
		System.out.println("요청 처리 종료 시각 : " + getCurrentTime());
		System.out.println("요청 처리 소요 시간 : " + (end-start)+ "ms ");
		System.out.println("============================================================================");
	}
	
	public void destroy() {
		
	}
	
	private String getURLPath(ServletRequest request) {
		HttpServletRequest req;
		String currentPath="";
		String queryString="";
		if(request instanceof HttpServletRequest) {
			req = (HttpServletRequest)request;
			currentPath = req.getRequestURI();
			queryString = req.getQueryString();
			queryString = queryString == null ? "" : "?" + queryString;
		}
		return currentPath+queryString;
	}
	
	private String getCurrentTime() {
		DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		return formatter.format(calendar.getTime());
	}
}
// web.xml

<web-app>
	<filter>
		<filter-name>LogFilter</filter-name>
		<filter-class>filter.LogFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>LogFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

 

 

 

필터 처리로 로그 기록 파일 만들기

  • 로그 기록 파일의 저장 폴더 만들기: C 드라이브에 log 폴더를 생성
  • Filter 인터페이스의 구현 클래스 작성하기
// LogFilter.java

package filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;

public class LogFilter implements Filter {

   PrintWriter writer;
   
   @Override
   public void init(FilterConfig config) throws ServletException {
      String filename = config.getInitParameter("filename");
      
      if(filename == null)
         throw new ServletException("로그 파일의 이름을 찾을 수 없습니다.");
      
      try {
         writer = new PrintWriter(new FileWriter(filename, true), true);
      }
      catch(IOException e) {
         throw new ServletException("로그 파일을 열 수 없습니다.");
      }
      
      System.out.println("WebMarket 초기화...");
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      
      writer.println(" 접속한 클라이언트 IP : " + request.getRemoteAddr());
      long start = System.currentTimeMillis();
      writer.println(" 접근한 URL 경로 : " + getURLPath(request));
      writer.println(" 요청 처리 시작 시간 : " + getCurrentTime());
      chain.doFilter(request, response);
      
      long end = System.currentTimeMillis();
      writer.println(" 요청 치리 종료 시간 : " + getCurrentTime());
      writer.println(" 요청 처리 소요 시간 : " + (end - start) + "ms");
      writer.println("======================================================================");
   }

   @Override
   public void destroy() {
   }
   
   private String getURLPath(ServletRequest request) {
      HttpServletRequest req;
      String currentPath = "";
      String queryString = "";
      if(request instanceof HttpServletRequest) {
         req = (HttpServletRequest) request;
         currentPath = req.getRequestURI();
         queryString = req.getQueryString();
         queryString = queryString == null ? "" : "?" + queryString;
      }
      return currentPath + queryString;
   }
   
   private String getCurrentTime() {
      DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
      Calendar calendar = Calendar.getInstance();
      calendar.setTimeInMillis(System.currentTimeMillis());
      return formatter.format(calendar.getTime());
   }
}
// web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
   <filter>				<< 추가
      <filter-name>LogFilter</filter-name>
      <filter-class>filter.LogFilter</filter-class>
      <init-param>
         <param-name>filename</param-name>
         <param-value>c:\\logs\\webmarket.log</param-value>
      </init-param>
   </filter>
   <filter-mapping>		<< 추가
      <filter-name>LogFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
   <security-role>
      <description></description>
      <role-name>admin</role-name>
   </security-role>
   <security-constraint>
      <display-name>WebMarket Security</display-name>
      <web-resource-collection>
         <web-resource-name>WebMarket</web-resource-name>
         <description></description>
         <url-pattern>/addProduct.jsp</url-pattern>
      </web-resource-collection>
      <auth-constraint>
         <description>권한 관리자명</description>
         <role-name>admin</role-name>
      </auth-constraint>
   </security-constraint>
   <login-config>
      <auth-method>FORM</auth-method>
      <form-login-config>
         <form-login-page>/login.jsp</form-login-page>
         <form-error-page>/login_failed.jsp</form-error-page>
      </form-login-config>
   </login-config>
   <error-page>
      <error-code>404</error-code>
      <location>/exceptionNoPage.jsp</location>
   </error-page>
</web-app>

 

 


웹 쇼핑몰 만들기 01 >>>  https://rogi221.tistory.com/93

웹 쇼핑몰 만들기 02 >>>  https://rogi221.tistory.com/101

웹 쇼핑몰 만들기 03 >>>  https://rogi221.tistory.com/105

 

 

 

웹 쇼핑몰 만들기 05 >>>  https://rogi221.tistory.com/114

728x90
반응형