study/spring | java

[Spring Web Project] Security [1] - 회원가입 시 비밀번호 암호화 작업

_드레 2021. 2. 27. 19:47

[개인 기록용]

※ 개인 공부기록입니다. 성공한 작업이 아닙니다. ㅠㅠ

참고할만한 글을 찾으신다면 뒤로가기를 눌러주세요..!

 

팀 프로젝트에서 시큐리티/관리자 페이지 부분을 진행중인데

어느정도 완성된 프로젝트 구조에 맞추려고 해서 그런건지,, 내가 쪼렙이라 그런건지 몰라도

계속 오류나서 같은작업을 또 하고 또 하는 중,,, ㅜ . ㅜ (3일째 매달리는중...)

 

한 네다섯번의 반복작업 중 막히는 부분

- web.xml에 filter-mapping (springSecurityFilterChain)을 삽입하면, 회원가입 부분에서 중복확인을 담당하는 ajax가 동작하지 않는다. 

- 아이디/닉네임 중복확인 구현한 부분에서 막히니 비밀번호 암호화가 되었는지도 확인이 안 되고 가입도 안 됨 ㅠㅠ

 

기록하면서 해보면 또다시(?) 할때 편할 것 같아서 차근차근 작성해 보려고 함. . . 

 

 

1. 가장먼저 폼 파일에 아래 내용을 추가한다. 

 

pom.xml

      <!-- Security -->
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-core</artifactId>
          <version>5.0.8.RELEASE</version>
      </dependency>
      
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-web</artifactId>
          <version>5.0.8.RELEASE</version>
      </dependency>
      
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-config</artifactId>
          <version>5.0.8.RELEASE</version>
      </dependency>
   
      
      <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-taglibs -->
      <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-taglibs</artifactId>
          <version>5.0.7.RELEASE</version>
      </dependency>    
      <!-- Security end-->

 

src>main>webapp>WEB-INF

 

 

 

2.

src>main>webapp>WEB-INF 에

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

 

 

security-context.xml (ver.1)

<?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>

security-context.xml (ver.2)

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

<bean id="bcryptPasswordEncoder" 
	class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />	

</beans>

ver.1은 비밀번호 암호화를 검색했을때 나온 게시글 두 개에서 따온 파일인데 내용이 같았다.

ver.2은 수업교재에서 참고한 파일인데 마찬가지로 <beans:beans 이렇게 이중으로 쓴걸 제외하면 나머진 다 같다. 

결론 : security-context.xml은 대부분 이렇게 생긴 걸로... 

 

3. web.xml 파일에 security-context의 경로를 잡아준다.

저 폼 파일에 아래 내용을 추가한다. 1. 가장먼저 폼 파일에 아래 내용을 추가한다. 

web.xml 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<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.xml을 보면 아래에 <servlet-name>appServlet</servlet-name> 내에도 xml파일 경로가 잡혀있는데,

거기에는 security 경로를 잡지 말란 게시글을 봐서 일단 ConfigLocation 내에만 넣어줬다. 

 

- 일단 여기까지 적용했을 때 서버가 잘 돌아가고 회원가입 기능도 정상적으로 작동한다.

(아이디/닉네임 중복확인 기능도 마찬가지로 잘 작동함.)

 

 

일단 회원가입정보를 받아오는 컨트롤러 Member.controller.java에 아래처럼 추가해서 BCryptPasswordEncoder를 사용할 수 있게 하고, 

 

Member.controller.java

@Inject
BCryptPasswordEncoder pwdEncoder;

Member.controller.java (참고용1)

	@Override
	public void regist(MemberVO vo) throws Exception {
        
		System.out.println("서비스레지스");

		String encPassword = passwordEncoder.encode(vo.getMemberPassword());
		vo.setMemberPassword(encPassword);
		//System.out.println("암호화된 비밀번호 : "+user.getUserPassword());

		dao.insertUser(vo);
		System.out.println(vo);
		System.out.println("///////////////////////");  회원가입 

Member.controller.java (참고용2)

// 회원가입 post
	@RequestMapping(value = "/user/register", method = RequestMethod.POST)
	public String postRegister(MemberVO vo) throws Exception {
		logger.info("post register");
		int result = service.idChk(vo);
		int result2 = service.nameChk(vo);
			try {
				if(result == 1 || result2 == 1) {
				return "/user/register";
			} else if(result == 0 || result2 == 0) {
				String inputPass = vo.getUserPassword();
				String pwd = pwdEncoder.encode(inputPass);
				vo.setUserPassword(pwd);
                
				service.register(vo);
			}

	// 요기에서~ 입력된 아이디가 존재한다면 -> 다시 회원가입 페이지로 돌아가기 
	// 존재하지 않는다면 -> register
	} catch (Exception e) {
		throw new RuntimeException();
	}
		return "redirect:/user/register_success";
}

참고용 2에서는 아래 내용이 추가되어, pwdEncoder로 인코딩한 password를 input받아서 vo객체로 넣어주고

service를 동작시키는 것 같다. 

    	  String inputPass = vo.getUserPassword();
    	  String pwd = pwdEncoder.encode(inputPass);
          vo.setUserPassword(pwd);
          service.register(vo);

 

참고용 1과 비교해보면 마찬가지로 String타입의 encoding된 password를 받고 vo객체로 넣어주는것 같다.

(아직 코딩을 배운지 얼마 안 돼서 표현을 어케 해야할지 ㅠ 잘 모름...) 

	String encPassword = passwordEncoder.encode(vo.getMemberPassword());
	vo.setMemberPassword(encPassword);
	dao.insertUser(vo);
//로그인
    @Override
    public MemberVO login(LoginDTO dto) throws Exception {
        System.out.println("service dto: "+dto);
        System.out.println("멤버서비스 dto");
        try {
            String pw = dao.getUserPw(dto.getMemberEmail()).getMemberPassword();
            String rawPw = dto.getMemberPassword();
            //System.out.println("db pW  : "+pw);
            //System.out.println("입력Pw:"+rawPw);
            //System.out.println(passwordEncoder.matches(rawPw, pw));
            
            if(passwordEncoder.matches(rawPw, pw)) {
                System.out.println("비밀번호 일치");
                dto.setMemberPassword(pw);
            }else {
                dto.setMemberPassword(pw);
            }
        }catch(NullPointerException npe){
            MemberVO vo=new MemberVO();
            vo=null;
            System.out.println(vo);
            return vo;
        }catch (Exception e){
            MemberVO vo=new MemberVO();
            vo=null;
            return vo;
        }
        return dao.login(dto);
    }

일단 참고용 2 가 우리 프로젝트랑 구조가 비슷해서 참고용 2 대로 입력해보았다. 

 

//로그인 POST
@RequestMapping(value = "/user/login", method = RequestMethod.POST)
public String login(MemberVO vo, HttpServletRequest req, HttpSession session, RedirectAttributes rttr) throws Exception{
   logger.info("post login");
   
//   session = req.getSession();
   session.getAttribute("member");
   MemberVO login = service.login(vo);
   boolean pwdMatch = pwdEncoder.matches(vo.getUserPassword(), login.getUserPassword());
   
   if(login != null && pwdMatch == true) {
	   session.setAttribute("member", login);
   } else {
	   session.setAttribute("member", null);
	   rttr.addFlashAttribute("msg", false);
   }
   
   return "redirect:/";
}

session = req.getSession();
session.getAttribute("member");

이 둘의 차이를 모르겠다.... 일단 겹치는 것 같으니 참고한 글과 다른 부분은 주석처리 ㅠ 

 

여기까지 입력했을 때  

다행히 이전에 막히던 중복확인 부분은 이루어지는데, 폼 기입 후에 '회원가입'버튼을 누르면 아래 500 오류가 난다. 

 

 

 

 

 

 

 

 

 

 

ㅠㅠ database를 확인해봐도 회원 테이블에 등록이 되지 않았다. 

 

 

 

 

 

 

 

 

 

뿌애애애앵 ------- ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

오류를 찾ㅇ ㅏ .... 떠나야지.... ㅎ ㅏ 주말까지 다 할수있나...? 

 

 

* 참고한 블로그 (감사합니다)

melonpeach.tistory.com/

MelonPeach

웹개발과 맛있는음식, 게임을 좋아하는 개발자입니다.!

melonpeach.tistory.com

songc92.tistory.com/

프로그래머하려고

SONGC 기술블로그

songc92.tistory.com