저희는 사용자가 회원가입을 진행할 때 DB에는 암호화되지 않은 비밀번호가 저장이 되어있습니다.

이럴경우 개인정보의 피해를 받을 수 있는데 사용자의 개인정보를 암호화하여 이러한 피해를 방지할 수 있습니다.

 

1. pom.xml에 spring-security dependency 추가

 

<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>5.0.8.RELEASE</version>
</dependency>

		
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.0.8.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.0.8.RELEASE</version>
</dependency>

 

 

2. spring-security.xml 작성

 

src -> main -> webapp -> WEB-INF -> spring 경로에 

spring-security.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>

 

 

3. web.xml 작성

 

<servlet>
	<servlet-name>appServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring/appServlet/servlet-context.xml
			/WEB-INF/spring/spring-security.xml
		</param-value>
	</init-param>
		<load-on-startup>1</load-on-startup>
</servlet>

 

위와 같이 <param-value> 태그안에 spring-secyrity.xml의 위치를 작성하여 

DispatcherServlet이 읽을 수 있도록 합니다.

 

4. UserController 추가

 

<!-- BCryptPasswordEncoder 추가 -->

@Inject
private BCryptPasswordEncoder pwdEncoder;

 

다음과 같이 암호화 기능을 사용할 수 있도록 BCryptPasswordEncoder를 추가합니다.

 

먼저 회원가입을 위한 코드에 암호화 기능을 적용합니다.

 

1. 회원가입

 

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerPOST(UserVO vo, RedirectAttributes ra) throws Exception {
	logger.info("registerPOST");
		
	int result = service.idOverlap(vo);
		
	System.out.println("중복은 1 아니면 0 = " + result );
	if(result == 1) {
		ra.addFlashAttribute("result", "registerFalse");
		return "/user/register";
	} else if(result == 0) {
		String PlaintextPassword = vo.getPassword();
		String encryptionPassword = pwdEncoder.encode(PlaintextPassword);
		vo.setPassword(encryptionPassword);
		service.register(vo);
		ra.addFlashAttribute("result", "registerOK");
	}
		
	return "redirect:/";
}

 

해당코드는 일단  대략적으로

register.jsp의 script단에서 아이디 중복체크로 result의 값을 넣어주는데요.

보시다시피 중복이면 리다이렉트로 register.jsp로 보내주고,

중복이 아니라면 암호화를 적용하여 회원 가입을 실행합니다.

 

result 값이 0일때 설명을 하자면

사용자가 회원가입을 할 때 해당 정보들을 입력하고 가입 버튼을 누르면

vo의 setPassword로 해당 값들이 들어가는데

String 변수를 하나 만들어 vo의 있는 getPassword를 가져와 PlaintextPassword에 저장

이제 PlaintextPassword에 저장한 값을 

BCryptPasswordEncoder의 encode속성을 사용하여 PlaintextPassword을 암호화 시키고,

암호화 시킨 비밀번호를 vo로 다시 보내주어

마지막으로 service의 register에 vo값을 넣어 실행하면 암호화된 비밀번호가 DB에 저장

 

 

2. 로그인

 

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String loginPOST(UserVO vo, HttpServletRequest req, RedirectAttributes ra) throws Exception {
	logger.info("post login");
		
	// HttpServletRequest를 사용하면 값을 받아 올수 있다.
	HttpSession session = req.getSession();
	UserVO login = service.login(vo);
		
	// 이렇게 안하면 db에 없는 아이디를 입력하고 로그인하면 에러코드 발생
	if(login == null ) { 
		ra.addFlashAttribute("result", "loginFalse");
		return "redirect:/";
	}
		
	logger.info("원래 비밀번호 : " + login.getPassword());
	logger.info("로그인할때 입력한 비밀번호 : " + vo.getPassword());
		
		
	boolean passwordMatch = pwdEncoder.matches(vo.getPassword(), login.getPassword());
	logger.info("원래 비밀번호와 로그인할 때 입력한 비밀번호가 같으면 트루 : " + passwordMatch);
	if(login != null && passwordMatch == true) {
		session.setAttribute("user", login);
		ra.addFlashAttribute("result", "loginOK");
	} else {
		session.setAttribute("user", null);
		ra.addFlashAttribute("result", "loginFalse");
	}
	return "redirect:/";
}

 

로그인 부분은 헷갈릴 수 있기 때문에 암호화한 부분과 같이 설명하겠습니다.

 

1. 로그인을 할 때는 2가지 비밀번호가 필요하다.

  - 회원가입을 할 때 입력한 비밀번호
  - 로그인 입력폼에 입력한 비밀번호
  

2. 사용자가 로그인 페이지에서 아이디와 비밀번호를 입력한다.(중요)

  1번에서 회원가입 할 때 입력한 비밀번호를 구해야 하는데
  
  방법은 identification(아이디)를 이용한다.
  
  userMapper의 로그인을 담당하는 mapper에서 where 조건을 id로 주었는데,
  
  이는 로그인 할 때를 위해 설정해주었다.
  
  왜? 라고 생각할 수 있겠지만 이해가 가도록 설명하자면
  
  쿼리에서 where절을 identification을 주었고  검색결과는 identification, name, password인데
  
  그 값을 resultType으로 인해 다시 UserVO로 주었기 때문에
  
  로그인 폼에 존재하는 아이디를 입력하면 해당 쿼리로 인해 vo에는 아이디, 이름, 비밀번호가 들어가게 되는 것이다.
  
  
  
3. 이제 본격적으로 회원가입을 할 때 입력한 비밀번호를 login메서드에서 구현한다.
 
  UserVO login = service.login(vo);
  
  데이터타입이 UserVO login을 생성하고
  
  이 login에다가 login쿼리를 조회하여 값을 넣어준다.
  
  그러면 login에 사용자의 아이디, 이름, 비밀번호가 들어가게 되는것이다.
  
  

 

중간점검을 하자면 login.getPassword()에는 회원가입할 때 입력한 암호화된 비밀번호가 들어가겠고,

vo.getPassword()에는 로그인폼에 입력한 암호화 되지 않은 비밀번호가 들어갑니다.

 

이제 평문인 비밀번호와 암호화된 비밀번호를 비교하여 같으면 로그인처리

다르면 비로그인 처리를해야하는데요.

 

두 비밀번호가 동일한지 비교하기 위해 BCryptPasswordEncoder의 matches 속성을 이용할것입니다!!

boolean passwordMatch = pwdEncoder.matches(vo.getPassword(), login.getPassword());

 

데이터 타입은 boolean값을 주었고 matches 을 이용하여 원래비밀번호와 로그인폼에 입력한 비밀번호를 비교하여

같으면 true, 다르면 false를 출력하도록 합니다.

 

여기서 주의할 점은 matches를 사용할 때

첫 번째 인자에는 평문화된 비밀번호를 입력하고, 두 번째 인자에는 암호회된 비밀번호를 입력해야합니다.

 

이렇게 matches를 이용하여 두 비밀번호가 일치하면 

if(login != null && passwordMatch == true) {
		session.setAttribute("user", login);
		ra.addFlashAttribute("result", "loginOK");
	} else {
		session.setAttribute("user", null);
		ra.addFlashAttribute("result", "loginFalse");
	}

 

다음과 같은 코드 처럼 login에 null이 아니면서 passwordMatch가 true이면 로그인이 되도록 처리합니다.

 

 

3. 회원 수정

 

@RequestMapping(value ="/modify", method = RequestMethod.POST)
public String modifyPOST(HttpSession session, UserVO vo, RedirectAttributes ra) throws Exception {
	logger.info("modifyPOST");		
		
	String PlaintextPassword = vo.getPassword();
	String encryptionPassword = pwdEncoder.encode(PlaintextPassword);
	vo.setPassword(encryptionPassword);
	service.modify(vo);
	session.invalidate();
	ra.addFlashAttribute("result", "updateOK");
	return "redirect:/";
}

 

회원수정하는 로직은 로그인에 비하면 매우 간단합니다!

 

1. 사용자가 입력한 비밀번호를 가져와 PlaintextPassword에 저장한다.

2. 가져온 PlaintextPassword을 encode로 암호화시켜 encryptionPassword에 저장한다.

3. 이 암호화된 비밀번호를 setter를 이용하여 다시 vo에 보낸다.

4. 그러면 vo에 있는 password에는 암호화된 비밀번호가 들어있게 된다.

5. 이제 회원수정하는 쿼리에 vo값을 실어 쿼리를 실행하면 정상적으로 회원 수정이 된다.

 

 

4. 회원탈퇴

 

@RequestMapping(value="/remove", method = RequestMethod.POST)
public String removePOST(UserVO vo, HttpSession session, RedirectAttributes ra) throws Exception {
	logger.info("removePOST");
		
	UserVO user = (UserVO)session.getAttribute("user");
		
	String oldPass = user.getPassword();
	logger.info("로그인할 때 입력한 비밀번호  = " + oldPass);
	String newPass = vo.getPassword();
	logger.info("회원탈퇴할 때 입력한 비밀번호 = " + newPass);
		
	boolean passwordMatch = pwdEncoder.matches(newPass, oldPass);  // 첫번째 인자는 평문, 두번 째 인자는 암호화로 설정해야 오류가 안난다.
	System.out.println("비밀번호 비교 : " + passwordMatch);
		
	if(passwordMatch == true) {
		service.remove(user);
		ra.addFlashAttribute("result", "removeOK");
		session.invalidate();
		return "redirect:/";
	} else {
		ra.addFlashAttribute("result", "removeFalse");
		return "redirect:/user/remove";
	}
}

 

회원탈퇴는 로그인처리하는 메서드와 비슷합니다.

 

1. session에 담겨있는 "user"를 getAttribute로 가져와 UserVO로 형변환 시켜 데이터 타입이 UserVO인 user에 저장한다.

2. 그러면 user 인스턴스에는 로그인할 때 입력한 비밀번호가 들어가고

3. 회원탈퇴 폼에 입력한 비밀번호는 vo에 들어가게 된다.

4. 로그인과 마찬가지로 matches 속성을 이용하여 값을 비교한다.

5. 참이 나오면 원래 비밀번호가 담겨있는 user를 회원탈퇴 쿼리에 넣어 정상적으로 회원탈퇴가 진행된다.

6. 만약 passwordMatch 값이 false이면 다시 /user/remove페이지로 리다이렉트 처리한다.

'JAVA > blog' 카테고리의 다른 글

게시판 리스트 제목에 댓글 수 표시  (1) 2020.08.05
조회수 증가  (0) 2020.08.05
아이디 중복검사 기능  (0) 2020.08.04
회원(4) - 회원탈퇴  (0) 2020.07.31
회원(3) - 비밀번호 변경  (0) 2020.07.31

이번장에서는 회원가입을 할때 아이디 중복 체크하는 기능을 만들어보겠습니다.

 

 

1. userMapper.xml 

 

<select id="idOverlap" resultType="int">
   	select count(identification)
   	from user
   	where identification = #{identification}
</select>

 

해당 쿼리는 아이디를 조건으로 user 테이블에서 카운트를하는데 보시다시피 조회결과 타입을

resultType="int"으로 설정해주어 Dao, Service, Controller에서 쓰일 예정입니다.

 

2. UserDAO 작성

 

package kr.co.web.persistence;

import kr.co.web.domain.UserVO;

public interface UserDAO {

	public void register(UserVO vo) throws Exception;
	public UserVO login(UserVO vo) throws Exception;
	public void modify(UserVO vo) throws Exception;
	public void remove(UserVO vo) throws Exception;
    
   	// 아이디 중복체크
	public int idOverlap(UserVO vo) throws Exception;
} 

 

package kr.co.web.persistence;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import kr.co.web.domain.UserVO;

@Repository
public class UserDAOImpl implements UserDAO{
	
	@Inject
	private SqlSession session;
	
	private static final String NS = "userMapper";
	private static final String REGISTER = NS + ".register";
	private static final String LOGIN = NS + ".login";
	private static final String LOGINBCRYPT = NS + ".loginBcrypt";
	private static final String MODIFY = NS + ".modify";
	private static final String REMOVE = NS + ".remove";
    
     	 //아이디 중복체크
	private static final String IDOVERLAP = NS + ".idOverlap";
	
	@Override
	public void register(UserVO vo) throws Exception {
		session.insert(REGISTER, vo);
	}
	
	@Override
	public UserVO login(UserVO vo) throws Exception {
		return session.selectOne(LOGINBCRYPT, vo);
	}
	
	@Override
	public void modify(UserVO vo) throws Exception {
		session.update(MODIFY, vo);
	}
	
	@Override
	public void remove(UserVO vo) throws Exception {
		session.delete(REMOVE, vo);
	}
	
    
     	 //아이디 중복체크
	@Override
	public int idOverlap(UserVO vo) throws Exception {
		int result = session.selectOne(IDOVERLAP, vo);
		return result;
	}
	
}

 

Service에서 보내주는 파라미터들을 DAO에서 받아주고

받은 파라미터는 userMapper.xml에 id가 idOverlap인 곳으로 보내준 후 

쿼리를 조회한 결과는 result로 return합니다.

 

3. UserService 작성

 

package kr.co.web.service;

import kr.co.web.domain.UserVO;

public interface UserService {

	public void register(UserVO vo) throws Exception;
	public UserVO login(UserVO vo) throws Exception;
	public void modify(UserVO vo) throws Exception;
	public void remove(UserVO vo) throws Exception;
    
    	// 아이디 중복체크
	public int idOverlap(UserVO vo) throws Exception;
}

 

package kr.co.web.service;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import kr.co.web.domain.UserVO;
import kr.co.web.persistence.UserDAO;

@Service
public class UserServiceImpl implements UserService {
	
	@Inject
	private UserDAO user;
	
	@Override
	public void register(UserVO vo) throws Exception {
		user.register(vo);
	}
	
	@Override
	public UserVO login(UserVO vo) throws Exception {
		return user.login(vo);
	}
	
	@Override
	public void modify(UserVO vo) throws Exception {
		user.modify(vo);
	}
	
	@Override
	public void remove(UserVO vo) throws Exception {
		user.remove(vo);
	}
	
    
   	 // 아이디 중복체크
	@Override
	public int idOverlap(UserVO vo) throws Exception {
		int result = user.idOverlap(vo);
		return result;
	}
}

 

4. UserController 작성

 

@ResponseBody
@RequestMapping(value="/idOverlap", method = RequestMethod.POST)
public int idOverlap(UserVO vo) throws Exception {
	int result = service.idOverlap(vo);
	return result;
}

 

UserController에 idOverlap요청이 들어오면 파라미터를 UserService로 보내주고 조회한 결과를 

result로 넣어 반환해줍니다.

이렇게 하게되면 결과가 있는 경우에는 1이 들어가고 없으면 0이 들어가게 됩니다.

 

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerPOST(UserVO vo, RedirectAttributes ra) throws Exception {
	logger.info("registerPOST");
		
	int result = service.idOverlap(vo);
		
	System.out.println("중복은 1 아니면 0 = " + result );
	if(result == 1) {
		ra.addFlashAttribute("result", "registerFalse");
		return "/user/register";
	} else if(result == 0) {
		service.register(vo);
		ra.addFlashAttribute("result", "registerOK");
	}
		
	return "redirect:/";
}

 

아이디 중복체크를 마친 후 회원가입 요청이 들어오면 결과가 1이면 아이디가 중복이기 때문에

다시 register.jsp로 보내고,

결과가 0이면 중복된 아이디가 없는것이기 때문에 service.register(vo)를 실행시키고

해당 코드가 실행되면 redirect:/ 처리로 인해 로그인 페이지로 보내줍니다.

 

5. register.jsp 버튼 속성, script 추가

 

<form method="post" autocomplete="off">
 	
 	<div>
 		<label for="identification">아이디</label>
 		<input type="text" id="identification" name="identification" />
 		<button type="button" id="idOverlap" onclick="fn_idOverlap();">중복확인</button>
 	</div>
 	
 	<div>
 		<label for="password">비밀번호</label>
 		<input type="password" id="password" name="password" />
 	</div>
 	
 	<div>
 		<label for="name">이름</label>
 		<input type="text" id="name" name="name" />
 	</div>
 	
 	<div>
 		<button type="submit" id="submit" disabled="disabled">가입</button>  // disabled 추가
 	</div>
 	
</form>

 

button 태그에 disable이라는 속성을 추가해주는데요.

이는 default 값으로  비활성화를 시켜줍니다.

즉, 기본값이 disabled(비활성화)이기 때문에 회원가입 버튼이 눌러지지 않고,

아이디 중복체크를 통해 중복된 아이디가 없으면 disabled이라는 속성을 제거해 다시 활성화 시켜줍니다.

 

 <script type="text/javascript">
	
	function fn_idOverlap() {
		$.ajax({
			url : "/user/idOverlap",
			type : "post",
			dataType : "json",
			data : { "identification" : $("#identification").val()},
			success : function(data) {
				if(data == 1) {
					alert("중복된 아이디 입니다.");
					$("#submit").attr("disabled", "disabled");
				} else if(data == 0) {
					alert("사용가능한 아이디 입니다.");
					$("#submit").removeAttr("disabled");
				}
			}
		})
	}

 </script>

 

아이디의 중복처리를 하는 과정을 ajax로 작성했습니다.

 

url : 요청하는 url 설정

data : identification 이름으로 id가 identification인 값을 가져와 데이터를 url로 넘김

success : 성공하면 Controller에서 요청받은 /user/idOverlap의 반환값을 fuction(data)의 data에 값을 넣어줌

 

data가 1이면 중복되었다는 의미이기 때문에 alert을 이용해 '중복된 아이디' 라고 경고창을 띄워주고,

마찬가지로 data가 0이면 중복되지 않았기 때문에 '사용가능한 아이디' 라고 경고창을 띄워줍니다.

 

그리고 아까 버튼을 추가했죠?

 

ajax로 아이디가 중복되면 

$("#submit").attr("disabled", "disabled");

다음과 같이 비활성화 시켜주고

 

아이디가 중복되지 않았으면

$("#submit").removeAttr("disabled");

removeAttr속성을 이용하여 disabled을 삭제하여 다시 활성화 시키는 의미입니다.

 

이제 확인 해보도록 하겠습니다.

 

 

아까 버튼의 기본값을 disabled로 주었기 때문에 비활성화가 된 상태입니다.

 

중복된 아이디를 입력하면 

 

 

마찬가지로 중복되었기 때문에 버튼이 비활성화 되었죠?

 

이제 중복되지 않은 아이디를 입력하겠습니다.

 

 

ajax에서 중복된 아이디가 없을 때 disabled을 삭제하여 가입버튼이 활성화 되었습니다!

 

 

저는 이렇게 버튼을 비활성화 시켰는데요

이렇게 한 이유는 컨트롤러에서 중복되면 model값으로 실패했다는 메세지를 주고싶었는데

이상하게 메세지가 뜨지 않아서 이렇게 구현하게 되었습니다.

'JAVA > blog' 카테고리의 다른 글

조회수 증가  (0) 2020.08.05
비밀번호 암호화 기능  (0) 2020.08.05
회원(4) - 회원탈퇴  (0) 2020.07.31
회원(3) - 비밀번호 변경  (0) 2020.07.31
회원 (2) - 로그인, 로그아웃 기능  (0) 2020.07.31

이제 회원기능에서 마지막 기능인 회원 탈퇴입니다.

 

먼저 정상적으로 삭제가 되는지 DB에서 

임시데이터를 생성하고 삭제해보겠습니다.

 

 

 

정상적으로 삭제 되었습니다.

잘 삭제가 되는것을 확인했으니 mapper를 작성하도록 하겠습니다.

 

1. userMapper.xml 작성

 

<?xml version="1.0" encoding="UTF-8"?>

<!-- DTD 선언 -->
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="userMapper">
	
   <insert id="register">
   		insert into user(identification, password, name)
   		values( #{identification}, #{password}, #{name})
   </insert>
   
   <select id="login" resultType="UserVO">
   		select identification, name, password
   		from user
   		where identification = #{identification} and password = #{password}
   </select>
   
   <update id="modify">
   		update user
   		set password = #{password}
   		where identification = #{identification}
   </update>
   
   <delete id="remove">
   		delete 
   		from user
   		where identification = #{identification} and password = #{password}
   </delete>
    	
</mapper>

 

회원탈퇴시에 비밀번호를 입력하여 사용자를 인증하게 됩니다.

그때 기존 비밀번호가 필요하기에 로그인 쿼리에 password를 추가해주었습니다.

 

2. DAO 작성

 

package kr.co.web.persistence;

import kr.co.web.domain.UserVO;

public interface UserDAO {

	public void register(UserVO vo) throws Exception;
	public UserVO login(UserVO vo) throws Exception;
	public void modify(UserVO vo) throws Exception;
	public void remove(UserVO vo) throws Exception;
}

 

package kr.co.web.persistence;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import kr.co.web.domain.UserVO;

@Repository
public class UserDAOImpl implements UserDAO{
	
	@Inject
	private SqlSession session;
	
	private static final String NS = "userMapper";
	private static final String REGISTER = NS + ".register";
	private static final String LOGIN = NS + ".login";
	private static final String MODIFY = NS + ".modify";
	private static final String REMOVE = NS + ".remove";
	
	@Override
	public void register(UserVO vo) throws Exception {
		session.insert(REGISTER, vo);
	}
	
	@Override
	public UserVO login(UserVO vo) throws Exception {
		return session.selectOne(LOGIN, vo);
	}
	
	@Override
	public void modify(UserVO vo) throws Exception {
		session.update(MODIFY, vo);
	}
	
	@Override
	public void remove(UserVO vo) throws Exception {
		session.delete(REMOVE, vo);
	}
}

 

 

3. SERVICE 작성

 

package kr.co.web.service;

import kr.co.web.domain.UserVO;

public interface UserService {

	public void register(UserVO vo) throws Exception;
	public UserVO login(UserVO vo) throws Exception;
	public void modify(UserVO vo) throws Exception;
	public void remove(UserVO vo) throws Exception;
}

 

package kr.co.web.service;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import kr.co.web.domain.UserVO;
import kr.co.web.persistence.UserDAO;

@Service
public class UserServiceImpl implements UserService {
	
	@Inject
	private UserDAO user;
	
	@Override
	public void register(UserVO vo) throws Exception {
		user.register(vo);
	}
	
	@Override
	public UserVO login(UserVO vo) throws Exception {
		return user.login(vo);
	}
	
	@Override
	public void modify(UserVO vo) throws Exception {
		user.modify(vo);
	}
	
	@Override
	public void remove(UserVO vo) throws Exception {
		user.remove(vo);
	}
}

 

4. remove.jsp 작성

 

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
 <title>게시판</title> 
 
 <script>
 	var result = '${result}';
 	
 	if(result === "removeFalse") {
 		alert("비밀번호를 다시 입력해주세요.");
 	}
 </script>
</head>
<body>

<form method="post" autocomplete="off">
 	
 	<div>
 		<label for="identification">아이디</label>
 		<input type="text" id="identification" name="identification" value="${user.identification}" readonly/>
 	</div>
 	
 	<div>
 		<label for="password">비밀번호</label>
 		<input type="password" id="password" name="password" />
 	</div>
 	
 	<div>
 		<button type="submit">회원탈퇴</button>
 	</div>
 	
</form>

	<div>
		<button onclick ="location.href='/'">처음</button>
	</div>
</body>
</html>

 

설명드리지 않아도 되겠죠??

 

5. Controller 작성

 

이제 회원탈퇴를 위한 메서드를 작성하겠습니다.

 

<!-- UserController -->

	@RequestMapping(value="/remove", method = RequestMethod.GET)
	public void removeGET() throws Exception {
		logger.info("removeGET");
	}
	
	@RequestMapping(value="/remove", method = RequestMethod.POST)
	public String removePOST(UserVO vo, HttpSession session, RedirectAttributes ra) throws Exception {
		logger.info("removePOST");
		
		UserVO user = (UserVO)session.getAttribute("user");
		
		String oldPass = user.getPassword();
		String newPass = vo.getPassword();
		
		if(oldPass.equals(newPass)) {
			service.remove(vo);
			ra.addFlashAttribute("result", "removeOK");
			session.invalidate();
			return "redirect:/";
		} else {
			ra.addFlashAttribute("result", "removeFalse");
			return "redirect:/user/remove";
		}
	}

 

removePOST를 보겠습니다.

 

session.getAttribute("user");

 

 를 이용하여 로그인할 때 생성되는세션에서 user값을 받아옵니다.

기본적으로 받아오는 데이터 타입은 오브젝트(Object) 타입이므로, 오브젝트 변수를 생성하여

받거나 형변환(캐스팅)을 해주어야 하는데요.

 

session.getAttribute("user");

 

가 UserVO의 형태라는 것을 알고있기에

(UserVO)session.getAttribute("user");

형태로 형변환 할 수 있으며, UserVO형의 변수 user에 값을 넣을 수 있습니다.

 

이렇게 받아온 user는 UserVO에서 만들어 두었던 getter를 이용하여 내부에 접근할 수 있으며,

문자열 변수 oldPass에 user에 있는 비밀번호를 넣어줍니다.

다른 문자열 변수 newPass에는 회원탈퇴 페이지에 입력했던 비밀번호를 넣어줍니다.

 

회원가입할 때 만들었던 비밀번호인 oldPass와 newPass를 비교해야하는데

문자열 변수를 비교할 때 ==를 사용하여 비교하면 다른 결과가 나오는데

이는 oldPass와 newPass에 들어있는 비밀번호를 비교하는것이 아니라

주소를 비교하는것이기 때문에 다른 결과가 나오는 것입니다.

 

oldPass와 newPass에 들어있는 실제 값을 비교하고 싶으면

.equals()을 사용해야합니다.

이는 실제 변수가 가진 값을 비교하는 것입니다.

 

조건문쪽을 보시면

 

만약에 oldPass와 newPass가 같다면

삭제를 진행하고

redirectAttributes 값으로 정상적으로 삭제되었다는 모델값을 보낸 후

회원탈퇴가 되었으니 invalidate()로 세션을 무효화 시키고

return 값을 home.jsp로 설정하여 로그인페이지로 다시 가도록 설정했습니다.

 

하지만 oldPass와 newPass가 다르다면

redirectAttributes 값으로 삭제에 실패했다는 모델값을 보내고

return 값은 다시 회원삭제 페이지로 설정했습니다.

 

확인해볼까요?

 

 

회원탈퇴 버튼을 클릭하면

 

 

비밀번호를 입력하고 회원탈퇴를 클릭하면 removePOST 메서드가 실행되어

test2 사용자를 삭제합니다.

 

 

'JAVA > blog' 카테고리의 다른 글

비밀번호 암호화 기능  (0) 2020.08.05
아이디 중복검사 기능  (0) 2020.08.04
회원(3) - 비밀번호 변경  (0) 2020.07.31
회원 (2) - 로그인, 로그아웃 기능  (0) 2020.07.31
회원 (1) - 가입 기능  (0) 2020.07.31

+ Recent posts