기본 콘텐츠로 건너뛰기

4월, 2021의 게시물 표시

불변 객체를 만들자!

 1. Object.preventExtensions Object의 확장을 막는다. const arr = [ 1 , 2 , 3 ] Object . preventExtensions ( arr ) arr [ 0 ] = 5 arr . pop () try { arr . push ( 3 ) } catch (err){ console . error (err) } console . log ( arr ) 실행결과를 보자 pop은 정상적으로 작동하나, push에 대해서만 안되는 것을 볼 수 있다. 2. Object.seal Object의 확장, 축소를 막는다. const arr = [ 1 , 2 , 3 ] Object . seal ( arr ) arr [ 0 ] = 5 try { arr . pop () } catch (err) { console . error (err) } try { arr . push ( 4 ) } catch (err){ console . error (err) } console . log ( arr ) 실행결과를 보자 pop과 push 둘다 안되는 것을 볼 수 있다. 3. Object.freeze Object의 확장, 축소, 변경을 막는다. const arr = [ 1 , 2 , 3 ] Object . freeze ( arr ) arr [ 0 ] = 5 try { arr . pop () } catch (err) { console . error (err) } try { arr . push ( 4 ) } catch (err){ console . error (err) } console . log ( arr ) 실행결과를 보자. push, pop도 막혔으며, 속성의 변경까지 안되었음을 확인 할 수 있다.

css var()

css에서 변수를 이용 하고 싶었던 때가 있었을 것이다. 위의 코드는 css에서 변수를 정의하고, 해당 변수를 사용 해보는 간단한 예제이다. 간단하게 내용을 뜯어보면 :root { --text-color: red; } // --text-color 변수에 red라는 값을 할당. .title { --text-color: green; } // 클래스가 title인 경우 --text-color 변수에 green라는 값을 할당. * { color: var(--text-color); } // 모든 태크에서 색상을 변수에서 색상을 가져오게 변경. Title 안녕하세요  그리하여 위처럼 title클래스를 가지고 있는 녀석은 녹색으로 일반 태그는 빨간색으로 보이게 된다. 조금더 꼬아보자. 위처럼 transform 처럼 여러속성을 정의할 수 있는 css속성에서는 변수 사용에 있어서 더더욱 절실하게 된다. css를 뜯어보자. .btn { transform: scale(var(--big, 1)) skew(var(--skew, 0deg)) } // scale을 --big변수를 참조하되, 정의 되어있지 않으면 1을 이용하게하고, skew를 --skew 변수를 참조 하되, 정의 되있지 않아면 0deg를 쓰게 하였다. .big { --big: 1.5; } // --big 변수에 1.5라는 값을 할당. .skew { --skew: 30deg; } // --skew 변수에 30deg라는 값을 할당. 위와 같이 정의 하여 4가지 경우를 각각 원하는 방식으로 정의를 할 수 있었는데, 만약에 변수를 사용 하지 않았다면,  .big { transform: scale(1.5) } .skew { transform: skew(30deg) } .big.skew { transform: scale(1.5) skew(30deg) } 위와 같이 조합 되는 css가지수에 따라 전부 정의해야 할 수도 있다. 종류가 많아지면 많아질수록 지옥이 될지도...

자바스크립트 이모저모

 1. Javascript Prototype 자 아래의 코드를 보고 이상한 점을 찾아보자. function Human ( name ) { this . name = name this . sayHello = function () { console . log ( ` 안녕하세요 . ${ this . name } 입니다 .` ) } } const sejiwork = new Human ( 'sejiwork' ) const sejinjja = new Human ( 'sejinjja' ) sejiwork . sayHello () //output: 안녕하세요 . sejiwork 입니다 . sejinjja . sayHello () //output: 안녕하세요 . sejinjja 입니다 . console . log ( sejiwork . sayHello === sejinjja . sayHello ) // output: false Human으로 만들어지 sejiwork, sejinjja객체에는 같은 동작을 하는 sayHello 함수가 각각 자신의 객체에서 정의가 되었다. 결과적으로 똑같은 일을 하는 함수임에도 불구하고, 불필요한 일을 하게 된 것이다. 위의 코드를 prototype을 이용하여 수정해보자. function Human ( name ) { this . name = name } Human . prototype . sayHello = function () { console . log ( ` 안녕하세요 . ${ this . name } 입니다 .` ) } const sejiwork = new Human ( 'sejiwork' ) const sejinjja = new Human ( 'sejinjja' ) sejiwork . sayHello () //output: 안녕하세요 . sejiwork 입니다 . sejinjja . sayHello () //output: 안녕하세요 . sejinjja 입니다

Sql Injection을 막아보자! (Statement vs PreparedStatement)

 머나 먼 옛날, 군대를 다니던 시절 소프트웨어 유지보수를 하고있었던 시절이였다.  평화롭던 나날들을 보내고있었는데, 출근을 하였더니, 모든 계정에 대해서 블락이 되었던 때가 있었다. 뭘까? 뭐길래 전 유저들의 로그인 5회 실패시에 뜨는 계정블록이 되었을까?  일단 바로 수습에 들어갔다. 운영 데이터에서 로그인 실패수를 초기화 해주는 쿼리를 돌렸다. 이제 수습은 끝났고, 이제 원인을 찾아서 해당 문제를 해결해야 한다. 로그인 실패 카운트가 올라간 시간을 찾아보니, 같은 시간이였고, 문제가 컸음을 느꼇다. 한번의 시도로 전 유저들의 실패를 올릴수 있는 방법, 실패한 유저의 아이디 부분을 무시하고, 실패 카운트를 올리면 된다.  로그인 쿼리와 실패시 실패 카운트를 올리는 쿼리를 확인해보았다.  아뿔싸 로그인 쿼리는  PreparedStatement인데 반해, 실패 카운트는 Statement이였다. 전임자가 싸둔똥을 찾은 느낌은 매우 더러웠다. 시나리오는 이러했다. 누군가가 공격을 했고, 유저 아이디로 ' or 1=1 # 를 이용하여 로그인 시도를 한 것이다.  다른 분들은 위와 같은 문제를 후임자에게 겪게 하지 않았으면 하고자, 이 포스트를 적는다. 이번 포스트는 실험이 위주이므로 적당히 훑어 보시면 된다.  아래의 코드를 준비하자. package kr . co . sejiwork ; import java.sql.* ; public class Main { public static void main ( String [] args ) throws Exception { String url = "jdbc:mysql://localhost/test-user?serverTimezone=UTC" ; String id = "tester" ; String pw = "0000" ; Connection conn = DriverManager . getConnectio