본문 바로가기
ICIA 수업일지

2021.10.18 수업일지(Spring Framework, Interceptor)

by 주성씨 2021. 10. 18.

- 금요일에 했던 프로젝트를 이어서 해보겠다.

- 인터셉터를 이용해서 연속적인 작업이 가능하도록 하겠다.

- 로그아웃 상태에서 댓글을 작성할려고 하면 로그인을 요구하는 인터셉터를 해보겠다.

/ex09/src/main/webapp/WEB-INF/views/read.jsp

...
<hr />
<h2>[댓글 목록]</h2>
<div id="insert">
	<textarea id="txtReply" cols="120" rows="5"></textarea>
	<c:if test="${uid==null}">
		<button onClick="location.href='/login'">로그인</button>
	</c:if>
	<c:if test="${uid!=null}">
		<button id="btnInsert">댓글등록</button>
	</c:if>
</div>
<hr />
...

 

- 인증 인터셉터를 하나 더 만들겠다.

/ex09/src/main/java/com/example/interceptor/AuthInterceptor.java

package com.example.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class AuthInterceptor extends HandlerInterceptorAdapter {
	// 로그인 페이지로 오기전에 실행되어야 하는 인터셉터
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (request.getSession().getAttribute("destination") == null) {
			request.getSession().setAttribute("destination", request.getHeader("Referer"));
			System.out.println("......" + request.getHeader("Referer"));
		}
		return super.preHandle(request, response, handler);
	}
}

 

/ex09/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml

...
	<!-- interceptor 등록 2-->
	<beans:bean id="AuthInterceptor" class="com.example.interceptor.AuthInterceptor"/>
	<interceptors>
		<interceptor>
			<mapping path="/insert"/>
			<beans:ref bean="AuthInterceptor"/>
		</interceptor>
		
		<interceptor>
			<mapping path="/login"/>
			<beans:ref bean="AuthInterceptor"/>
		</interceptor>
	</interceptors>
</beans:beans>

 

- 상품등록 페이지를 만들어보겠다.

/ex09/src/main/java/com/example/controller/HomeController.java

...
	
	@RequestMapping("/product/insert")
	public String insert(Model model){
		model.addAttribute("pageName","pinsert.js[");
		return "home";
	}

}

 

- 비로그인 상태에서 상품등록 버튼을 눌렀을 경우 로그인 페이지로 가게끔 한다.

/ex09/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml

...
	<!-- interceptor 등록 1-->
	<beans:bean id="LoginInterceptor" class="com.example.interceptor.LoginInterceptor"/>
	<interceptors>
		<interceptor>
			<mapping path="/insert"/>
			<mapping path="/product/insert"/>
			<beans:ref bean="LoginInterceptor"/>
		</interceptor>
	</interceptors>
...

 

확인

 

 

- 회원가입을 해보겠다.

/ex09/src/main/webapp/WEB-INF/views/login.jsp

...
<div class="loginBox">
	<form action="post" name="frm">
		<input type="text" name="uid" placeholder="ID"/>
		<input type="password" name="upass" placeholder="PW" />
		<div>
			<input type="checkbox" name="chkLogin"/> 로그인 상태 유지
			&nbsp;&nbsp;&nbsp;<a href="/user/insert">회원가입</a>
		</div>
		<input type="submit" value="LOGIN" />
	</form>
</div>
...

 

- 유저 컨트롤러에 회원가입을 위한 컨트롤러를 생성하겠다.

/ex09/src/main/java/com/example/controller/UserController.java

...
@Controller
public class UserController {
	@Autowired
	UserDAO udao;

	// user join
	@RequestMapping("/user/insert")
	public String userInsert(Model model){
		model.addAttribute("pageName","uinsert.jsp");
		return "home";
	}
...

 

/ex09/src/main/webapp/WEB-INF/views/uinsert.jsp

테이블 확인

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<h1>[회원가입]</h1>
<style>
.joinbox {
	width: 300px;
	margin: 0px auto;
	padding: 10px;
}

input[type=text], input[type=password] {
	width: 100%;
	margin-bottom: 10px;
	font-size: 15px;
}

input[type=submit], input[type=reset] {
	padding: 10px 20px 10px 20px;
	background: rgb(57, 109, 192);
	color: white;
}

input[type=checkbox] {
	margin: 10px 0px 10px 0px;
}
</style>
<div class="joinbox">
	<form action="/user/insert" name="frm" method="post">
		<input type="text" name="uid" placeholder="아이디를 입력하세요." /> <input
			type="password" name="upass" placeholder="비밀번호를 입력하세요." /> <input
			type="text" name="uname" placeholder="이름을 입력하세요." />
		<div>
			<input type="submit" value="회원등록" /> <input type="reset"
				value="등록취소" />
		</div>
	</form>
</div>
<script>
	$(frm).on("submit", function(e) {
		e.preventDefault();
		var uid = $(frm.uid).val();
		var upass = $(frm.upass).val();
		var uname = $(frm.uname).val();

		if (uid == "" || upass == "" || uname == "") {
			alert("입력란을 확인하세요.");
			return;
		}

		// 아이디 체크
		$.ajax({
			type : 'get',
			url : '/idCheck',
			data : {
				"uid" : uid
			},
			success : function(data) {
				if (data == 1) {
					alert("이미 존재하는 아이디입니다.")
				} else {
					if (!confirm("등록하시겠습니까?"))
						return;
					frm.submit();
				}
			}
		})
	})
</script>

 

- id 존재 유무 확인을 위한 컨트롤러를 만들겠다.

/ex09/src/main/java/com/example/controller/UserController.java

...
@Controller
public class UserController {
	@Autowired
	UserDAO udao;

	// user join uid check
	@RequestMapping("/idCheck")
	@ResponseBody
	public int idCheck(String uid){
		int result = 0;
		UserVO vo = udao.login(uid);
		if(vo!=null){
			return 1;
		}
		return result;
	}
	
...

 

아이디 체크 확인

 

- user join을 위한 컨트롤러를 생성하겠다.

/ex09/src/main/java/com/example/controller/UserController.java

...
	// user join
	@RequestMapping(value="/user/insert", method=RequestMethod.POST)
	public String userPost(UserVO vo){
		System.out.println(vo.toString()); // 확인
		udao.insert(vo); // 입력
		return "redirect:/";
	}
...

 

/ex09/src/main/resources/mapper/UserMapper.xml

	<insert id="insert">
		insert into tbl_user(uid,upass,uname)
		values(#{uid},#{upass},#{uname})
	</insert>
</mapper>

 

/ex09/src/main/java/com/example/mapper/UserDAO.java

package com.example.mapper;

import com.example.domain.UserVO;

public interface UserDAO {
	public UserVO login(String uid);
	public void insert(UserVO vo);
}

 

/ex09/src/main/java/com/example/mapper/UserDAOImpl.java

	@Override
	public void insert(UserVO vo) {
		session.insert(namespace+".insert",vo);
	}

}

 

회원가입 확인

 

- 비밀번호를 암호화하여 저장하고 로그인시 입력한 비밀번호를 암호화하여 비교한다. 

- 라이브러리를 추가하겠다.

/ex09/pom.xml

	<dependencies>
		<!-- 새로운 라이브러리 추가 시작 -->
		<!-- 시큐리티 관련 라이브러리 -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>4.1.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-core</artifactId>
			<version>4.1.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>4.1.0.RELEASE</version>
		</dependency>
        ...

 

- security-context.xml 파일을 생성한다.

/ex09/src/main/webapp/WEB-INF/spring/security-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/security
 http://www.springframework.org/schema/security/spring-security.xsd">
	<beans:bean id="bcryptPasswordEncoder"
		class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
</beans:beans>

 

- web.xml 파일에 아래 내용을 추가한다. 

/ex09/src/main/webapp/WEB-INF/web.xml

...
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring/root-context.xml
			/WEB-INF/spring/security-context.xml
		</param-value>
	</context-param>
</web-app>

 

/ex09/src/main/java/com/example/controller/UserController.java

...
	@Autowired
	BCryptPasswordEncoder passEncoder;
...
	// user join
	@RequestMapping(value="/user/insert", method=RequestMethod.POST)
	public String userPost(UserVO vo){
		System.out.println(vo.toString());
		String password=passEncoder.encode(vo.getUpass());
		vo.setUpass(password);
		udao.insert(vo);
		return "redirect:/";
	}
...

 

- 암호화된 비밀번호가 자릿수가 길어서 테이블을 변경해주겠다.

- go to sql

alter table tbl_user modify upass nvarchar(200);

desc tbl_user;

확인

 

- 신규 가입하면 암호화된 비밀번호가 들어가니 다음과 같이 확인하는 작업을 하도록 하겠다.

/ex09/src/main/java/com/example/controller/UserController.java

...
	// user login check
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	public int loginPost(String uid, String upass, HttpSession session, boolean isLogin, HttpServletResponse response) throws Exception {
		int result = 0;
		UserVO vo = udao.login(uid);
		if (vo != null) {
			if (passEncoder.matches(upass, vo.getUpass())) { <<<<<-------
				session.setAttribute("uid", uid);
				if(isLogin){
					Cookie cookie = new Cookie("uid", uid);
					cookie.setPath("/");
					cookie.setMaxAge(60 * 60 * 24 * 7);
					response.addCookie(cookie);					
				}
				result = 1;
			} else {
				result = 2;
			}
		}
		return result;
	}
...

 

암호화된 아이디로 로그인 확인

 

 

- 아이디를 클릭하면 사용자 정보가 나오도록 하겠다.

/ex09/src/main/webapp/WEB-INF/views/home.jsp

				<c:if test="${uid!=null}">
					<a href="/logout" title="로그아웃" style="float: right">로그아웃</a>
					<span style="float:left">
						<a href="/user/read?uid=${uid}">${uid}님</a>
					</span>				
				</c:if>

 

/ex09/src/main/java/com/example/controller/UserController.java

...
	// user info read
	@RequestMapping("/user/read")
	public String read(String uid, Model model){
		model.addAttribute("pageName","uread.jsp");
		model.addAttribute("vo",udao.login(uid));
		return "home";
	}
...

 

- 기존 uservo에 address, tel을 추가하겠다.

/ex09/src/main/java/com/example/domain/UserVO.java

package com.example.domain;

public class UserVO {
	private String uid;
	private String upass;
	private String uname;
	private String address;
	private String tel;
    ... getter, setter, tostring

 

/ex09/src/main/webapp/WEB-INF/views/uread.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<h1>[회원정보]</h1>
<style>
.joinbox {
	width: 300px;
	margin: 0px auto;
	padding: 10px;
}

input[type=text], input[type=password] {
	width: 100%;
	margin-bottom: 10px;
	font-size: 15px;
}

input[type=submit], input[type=reset] {
	padding: 10px 20px 10px 20px;
	background: rgb(57, 109, 192);
	color: white;
}

input[type=checkbox] {
	margin: 10px 0px 10px 0px;
}
</style>
<div class="joinbox">
	<h1>회원정보</h1>
	<form action="/user/update" name="frm" method="post">
		<input type="text" name="uid" value="${vo.uid}" readonly/> 
		<input type="password" name="upass" /> 
		<input type="text" name="uname" value="${vo.uname}" />
		<input type="text" name="address" value="${vo.address}" />
		<input type="text" name="tel" value="${vo.tel}" />
		<div>
			<input type="submit" value="정보수정" /> 
			<input type="reset" value="수정취소" />
		</div>
	</form>
</div>

 

- 회원정보를 수정하는 xml을 만들겠다.

/ex09/src/main/resources/mapper/UserMapper.xml

...
	<update id="update">
		update tbl_user set uname=#{uname},address=#{address},tel=#{tel}, upass=#{upass}
		where uid=#{uid}
	</update>
</mapper>

 

/ex09/src/main/java/com/example/mapper/UserDAO.java

...
	public void update(UserVO vo);
}

 

/ex09/src/main/java/com/example/mapper/UserDAOImpl.java

...
	@Override
	public void update(UserVO vo) {
		session.update(namespace+".update",vo);
	}

}

 

/ex09/src/main/java/com/example/controller/UserController.java

...
	// user info update
	@RequestMapping(value="/user/update", method=RequestMethod.POST)
	public String updatePost(UserVO vo, String oldPass){
		System.out.println(vo.toString());
		if(vo.getUpass().equals("") || vo.getUpass()==null){
			vo.setUpass(oldPass);
		}else{
				vo.setUpass(passEncoder.encode(vo.getUpass()));
		}
		udao.update(vo);
		return "redirect:/";
	}
...

 

- 이전 비밀번호를 히든으로 넣어놓겠다.

/ex09/src/main/webapp/WEB-INF/views/uread.jsp

...
<div class="joinbox">
	<h1>회원정보</h1>
	<form action="/user/update" name="frm" method="post">
		<input type="hidden" name="oldPass" value="${vo.upass}"/>
		<input type="text" name="uid" value="${vo.uid}" readonly/> 
		<input type="password" name="upass" /> 
		<input type="text" name="uname" value="${vo.uname}" />
		<input type="text" name="address" value="${vo.address}" />
		<input type="text" name="tel" value="${vo.tel}" />
		<div>
			<input type="submit" value="정보수정" /> 
			<input type="reset" value="수정취소" />
		</div>
	</form>
</div>
...
<script>
	$(frm).on("submit", function(e) {
		e.preventDefault();
		var uid = $(frm.uid).val();
		var uname = $(frm.uname).val();

		if (uname == "") {
			alert("입력란을 확인하세요.");
			return;
		}
		if(!confirm("수정하시겠습니까?")) return;
		frm.submit();
	})
</script>

 

확인

 

확인