코코딩딩

[스프링 / spring] 비밀번호 처리하기 (비밀번호 확인,변경) 본문

일단기록/매일기록

[스프링 / spring] 비밀번호 처리하기 (비밀번호 확인,변경)

겟츄 2022. 5. 4. 18:49

api 통신을 이용해 비밀번호 변경 처리하는 작업을 진행하였다.

 

예를들어 "user"라는 id와 "qwer1234!" 라는 비밀번호가 있다고 가정해보자 이러한 값이 db에 그냥 저장 된다면 관리자가 db를 확인할 경우 유저의 비밀번호를 눈으로 확인할 수 있을 것이다. 이러한 상황을 방지하기 위해 유저가 입력한 비밀번호를 spring-security의 PasswordEncoder를 이용해 암호화를 진행한 후 db에 저장할 것이다.

 

 


 

SecurityConfig

 

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	@Bean
	public PasswordEncoder getPasswordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.cors().disable()
			.csrf().disable()
			.formLogin().disable()
			.headers().frameOptions().disable();
	}

}

 

 

spring-security의존성 주입을 해준 다음 위와 같이 PasswordEncoder bean을 추가해준다. 이후 @Autowired
어노테이션을 이용해 사용할 수 있다.

 

 

비밀번호를 암호화해 update하는 api

 

 

비밀번호를 변경하기 위한 프로세스는 다음과 같다. 참고로 아래 코드에 나오는 CommonMap은 custom한 map이다.

 

1. 요청으로 들어온 json이 들어있는 params에서 id값을 가져와 db조회할 때 넣어줄 new_user_info에 넣어준다.

 

2. 요청으로 들어온 json이 들어있는 params에서 pw값(암호화되지 않은 그냥string)을 가져와 passwordEncoder.encode()를 이용해 암호화 한 값을 new_user_info에 넣어준다.

 

3. password값을 update 해주는 service인 update_user_pw()에 new_user_info 를 넣어서 sql문을 실행시켜준다.

 

이러한 방식으로 db에 비밀번호를 insert/update 하면 "qwer1234!" 가 아닌

$2a$10$3qm7EDmJ2FZjO3KN.NlvzuYv/8wkQxm과 같은 암호화 된 값으로 저장이된다.

 

 

	// 계정정보 - 비밀번호 update
	@ApiOperation(value="비밀번호 변경", notes="비밀번호 변경")
	@PostMapping(value="/user/pwupdate")
	@Transactional
	@ApiIgnore
	public ResponseEntity<?> USER_PW_UPDATE(@ApiParam(value = "INFO") @RequestBody CommonMap params, HttpServletRequest req){
		
		CommonMap result = new CommonMap();
		CommonMap new_user_info = new CommonMap();
        
		if(((String)params.get("id")).equals("") || !params.containsKey("id")) {
			result.put("result", "F");
			return ResponseEntity.ok(result);
		}
		
		if(((String)params.get("pw")).equals("") || !params.containsKey("pw")) {
			result.put("result", "F");
			return ResponseEntity.ok(result);
		}        
        
		new_user_info.put("id", params.get("id"));
		new_user_info.put("pw", passwordEncoder.encode(params.getString("pw")));
		
		
	    try {
	    	// 비밀번호 변경 로직
	    	userService.update_user_pw(new_user_info);
	    	result.put("result", "S");
			
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "F");
		} 
	    
		return ResponseEntity.ok(result);
	}

 

 

기존 비밀번호와 같은지 확인하는 api

 

 

비밀번호 확인을 하는 프로세스는 다음과 같다.

 

1. 유저 pw를 select하는 service인 chek_user_pw에 유저의 id가 담긴 json이 있는 params를 넣어 실행해 암호화된 pw 값을 받아온다.

 

2. passwordEncoder.matches()에 확인하고자 하는 비밀번호인 일반스트링 (ex : "qwer1234!")과 암호화된 값을 넣어준다.

 

3. 2번 과정에서 일치할 경우 true 아닐경우 false가 반환되며 이 값을 가지고if문으로 처리해준다.

 

	// 계정정보 - 비밀번호 check
	@ApiOperation(value="비밀번호 맞는지 확인", notes="비밀번호 맞는지 확인")
	@PostMapping(value="/user/pwcheck")
	@Transactional
	@ApiIgnore
	public ResponseEntity<?> USER_PW_CHECK(@ApiParam(value = "INFO") @RequestBody CommonMap params, HttpServletRequest req){
		
		CommonMap result = new CommonMap();
		CommonMap check = new CommonMap();
		
		if(((String)params.get("id")).equals("") || !params.containsKey("id")) {
			result.put("result", "F");
			return ResponseEntity.ok(result);
		}
		if(((String)params.get("pw")).equals("") || !params.containsKey("pw")) {
			result.put("result", "F");
			return ResponseEntity.ok(result);
		}
		
		String ori_pw = userService.check_user_pw(params);
		String pw = params.getString("pw");
		boolean ispw = passwordEncoder.matches(pw, ori_pw);
		

		
	    try {
			if(ispw) {
				// 입력한 비밀번호와 실제 비밀번호가 같은경우
				result.put("result", "S");
			}else {
				// 다른경우
				result.put("result", "F");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "F");
		} 
		return ResponseEntity.ok(result);
	}