spring-boot 사용 중 DB접속 정보(계정, 비밀번호)를 application.properties에 등록 하는 경우 

해당 정보를 암호화 해야 하는 경우가 있습니다.(개인적으로 진행하는 프로젝트가 아니라면 무조건 암호화를 해줘야 합니다.)

 

jasypt를 이용해서 관련 작업을 진행 할 수 있는데 build.gradle 에 관련 의존성을 추가 해줍니다.

 

implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4'
implementation 'org.bouncycastle:bcprov-jdk15on:1.61'

암호화 관련 설정시 사용할 정보를 application.properties에 아래와 같이 추가 해주고

jasypt.encryptor.password=mypassword
jasypt.encryptor.algorithm=PBEWithMD5AndDES
jasypt.encryptor.property.prefix=ENC[
jasypt.encryptor.property.suffix=]

사용 하고자 하는 정보를 아래의 소스를 참고해 암호화 해줍니다.

StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); 
SimpleStringPBEConfig config = new SimpleStringPBEConfig(); 
config.setPassword("mypassword"); 
config.setAlgorithm("PBEWithMD5AndDES"); 
config.setKeyObtentionIterations("1000"); 
config.setPoolSize("1"); 
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); 
config.setStringOutputType("base64"); 
encryptor.setConfig(config); 

String plainText = "test"; // 암호화 할 내용
String encryptedText = encryptor.encrypt(plainText); // 암호화
String decryptedText = encryptor.decrypt(encryptedText); // 복호화
System.out.println("Enc:"+encryptedText+", Dec:"+decryptedText);

해당 결과를 database관련 설정의 value로 등록 해주고

spring.datasource.username=ENC[ZKu/LKf9DyGnJPAXqWW7uQ==]
spring.datasource.password=ENC[kXjtcrMkTLitu2n0Y+1vdA==]

위의 설정처럼 ENC[] 으로 값을 감싸 줍니다.(해당 정보를 기준으로 암호화 여부를 결정 하게 됩니다. 기본 설정은 ENC()입니다.)

서비스 시작시 해당 정보를 복호화 할 class를 아래와 같이 추가 해주면

@Configuration
@EnableEncryptableProperties
public class PropertyEncryptConfig {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	public static final String JASYPT_STRING_ENCRYPTOR = "jasyptStringEncryptor";
		
	@Value("${jasypt.encryptor.password}") 
	private String encryptKey;

	@Value("${jasypt.encryptor.algorithm}") 
	private String algorithm;
	
	@Bean(JASYPT_STRING_ENCRYPTOR) 
	public StringEncryptor stringEncryptor() { 
		logger.info("encryptKey: "+encryptKey);
		logger.info("algorithm: "+algorithm);
		
		StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); 
		SimpleStringPBEConfig config = new SimpleStringPBEConfig(); 
		config.setPassword(encryptKey); 
		config.setAlgorithm(algorithm); 
		config.setKeyObtentionIterations("1000"); 
		config.setPoolSize("1"); 
		config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); 
		config.setStringOutputType("base64"); 
		encryptor.setConfig(config); 
		
		logger.info("end");
		
		return encryptor;
	}
}

설정한 정보가 복호화 되서 접속 하게 됩니다.

아래는 작업시 참고한 블로그 입니다. 

https://derveljunit.tistory.com/339

 

[Spring & Boot][2.6.2] 스프링 프로퍼티 암복호화 Jasypt 예제

스프링부트 2.6.2 버전을 기준으로 작성되었습니다. 예제 Github 주소 https://github.com/Derveljun/derveljun-jasypt-example GitHub - Derveljun/derveljun-jasypt-example Contribute to Derveljun/derveljun-..

derveljunit.tistory.com

https://www.baeldung.com/spring-boot-jasypt

 

반응형

'spring' 카테고리의 다른 글

@RestControllerAdvice 관련 정리  (0) 2022.04.12
spring boot freemarker 적용  (0) 2022.03.28
이클립스 gradle 빌드  (0) 2022.03.15
spring-boot jdbc database 초기화 schema.sql, data.sql  (0) 2022.03.09
spring boot 실행시 DB 연결에러  (0) 2021.11.25
Posted by 질주하는구
,

MySql 서버8 이후 버전의 경우 기본 time_zone관련 설정이 되어 있지 않아 기존에 많이 사용하던 url형식으로 접속 하는 경우
time_zone 관련 에러가 발생 됩니다. 

mysql에 접속 해서 아래의 명령어를 실행 하면

SELECT @@GLOBAL.time_zone, @@SESSION.time_zone, @@system_time_zone;

와 같은 결과가 나오는걸 확인 할 수 있습니다.

global설정은 system설정을 따르게 되어 있고 session(접속시)설정도 system설정을 따르게 되어 있는데

system은 아무 설정도 되어 있지 않습니다.(���ѹα� ǥ�ؽ�) 이 경우 에러가 발생되고

jdbc url에 serverTimeZone설정을 추가 해주면 정상적으로 접속이 가능 하게 됩니다.

접속 정보에 아래와 같이 serverTimeZone을 명시 해주면 됩니다.(serverTimezone=UTC, serverTimezone=Asia/Seoul)

jdbc:mysql://localhost:3306/test_db?characterEncoding=UTF-8&serverTimezone=UTC

 

또는 mysql서버에 system 및 session접속시 사용할 time_zone정보를 my.ini파일에 아래와 같이 명시 할 수 도 있습니다.

default-time-zone='+9:00'

my.ini 설정은 mysql서버를 재기동 해야 적용이 됩니다.(+9:00 은 서울 지역의 시간대 입니다. GMT+9시간)

 

 

반응형

'DB > MY-SQL' 카테고리의 다른 글

MYSQL 프로시저 오류 실행 오류  (0) 2022.02.28
mysql datetime 0000-00-00 00:00:00  (0) 2022.02.22
Error Code: 2006 - MySQL server has gone away  (0) 2017.01.18
jdbc연결시 한글 인코딩 문제  (0) 2017.01.18
mysql recource설정시 옵션  (0) 2016.12.20
Posted by 질주하는구
,

bootstrap디자인에 맞춰서 폴더 및 파일을 아래와 같이 나누어서 작업 할 예정 입니다.

/inc/...

/layout/...

2개의 폴더에 각각의 폴더를 생성 합니다. 폴더 및 파일은 자신이 생각하는 이름으로 작업 해주시면 됩니다.

(패키지 및 파일명, 변수명 생각하는데 정말 많은 시간을 사용하는데 많은 페이지가 아니고 작업 해보는것에 의미가 있어 막지었습니다.)

기존에 작업한 내용을 각 파일에 맞게 잘라서 붙여 주시면 됩니다.

다른 분들 글에는 class형으로 사용하는 경우가 있는데 저는 함수형 그중에서 익명함수형으로 소스 작업을 진행 했습니다.

Top.js

const Top =()=>{
    return(
        <div className="row mt-2">
            <div className="card w-100">
                <div className="card-header bg-primary text-white">DATA SEARCH</div>
                <div className="card-body">
                    <div className="row">
                        <div className="col-md-11">
                            <form className="form-inline">
                                <div className="form-group mb-2 mr-1">
                                    <label htmlFor="searchYear">년도</label>
                                    <select className="form-control" name="searchYear" id="searchYear"> 
                                        <option value="">선택</option>                               
                                        <option value="1">1</option>
										<option value="2">2</option>
										<option value="3">3</option>
										<option value="4">4</option>
                                    </select>
                                </div>
                                <div className="form-group mb-2 mr-1">
                                    <label htmlFor="searchSiDo">시군</label>
                                    <select className="form-control" name="searchSiDo" id="searchSiDo">
                                        <option value="">선택</option>                               
                                        <option value="1">1</option>
										<option value="2">2</option>
										<option value="3">3</option>
										<option value="4">4</option>                           
                                    </select>
                                </div>
                                <div className="form-group mb-2 mr-1">
                                    <label htmlFor="searchGuGun">구군</label>                           
                                    <select className="form-control" name="searchGuGun" id="searchGuGun">
                                        <option value="">선택</option>
                                        <option value="1">1</option>
										<option value="2">2</option>
										<option value="3">3</option>
										<option value="4">4</option>
                                    </select>
                                </div>
                                <ReactBootstrap.Button type="button" className="btn btn-primary mb-2">search</ReactBootstrap.Button>
                            </form>
                        </div>
                    </div>                                      						
                </div>
            </div>
        </div>
    )
}
    
export default Top;

tab.js

const Tab =()=>{
    return(
        <div className="row mt-2">
            <ul className="nav nav-tabs w-100">
                <li className={"nav-item nav-link"}>
                목록
                </li>
                <li className={"nav-item nav-link"}>
                지도
                </li>
            </ul>
        </div>
    )
}
    
export default Tab;

main.js

const Main =()=>{  
    return(
		<div className={"row mt-1">
			<div className="card w-100">
				<div className="card-body">NO DATA.</div>
			</div>				
		</div>       
	);
}
    
export default Main;

bottom.js

const Bottom =(props)=>{
    return(
        <footer className="container mt-2">
			<div className="row"><div className="col-12 text-center">©2022 Copyright: {props.tempVal}</div></div>
		</footer>
    )
}
    
export default Bottom;

App.js

import Top from './layout/top'
import Tab from './inc/tab'
import Main from './layout/main'
import Map from './layout/map'
import Bottom from './layout/bottom'

return (
	<div className="container">
	  <Top/>
	  <Tab/>
	  <Main/>
	  <Map/>
	  <Bottom tempVal="KOOREMO"/>
	</div>
);

App.js 는 상단 import 부분과 return 영역의 내용만 작성 했습니다.

최초 생성시 index.html 내용에 보면 <body> 태그 하위에 <div id="root"></div> 영역이 있는데 이 부분을

<body id="root">
    
</body>

body 기준으로 변경 해줍니다. <div> 하나를 허용하는 경우 출력되는 화면이 의도와 다르게 출력 될 수 있어 삭제 

처리 해줬습니다.

(class container 아래에 구성요소를 위치 하는게 화면 구성을 잡기 좋아서 그렇게 했는데 필요 없는경우 그냥 기본 index.html로 작업 진행 하셔도 됩니다.)

 

위의 내용 들중 설명이 필요한 부분은 class->className으로 처리 해야 하는 부분과, Bottom을 호출할때 tempVal이라는 key에 KOOREMO라는 값을 담아 보내 줬고 해당 값을 bottom.js에서 props로 전달 받아 사용 했다는 겁니다.

 

react는 부모가 자식 구성요소에 데이터 및 함수를 전달 할 수 있는데 이 때 props를 사용 하게 됩니다.

또한 데이터는 state에 담아 변경 사항을 관리 합니다. state부분은 다음 데이터를 불러오는 부분에서 설명 하겠습니다.

 

위의 내용까지 작업 하고 나면 확인이 가능 합니다. 해당 프로젝트로 이동 후

yarn start

명령어를 실행 하면 작업한 디자인을 확인 할 수 있습니다.

 

반응형
Posted by 질주하는구
,