프로그래밍/전자정부프레임워크(eGov)

스프링 쿠키의 활용법

Jay Tech 2017. 3. 13. 21:11
반응형

로그인 인증에서 쿠키를 쓰면 안된다는 말을 많이 들었을 것이다. 쿠키 대신 세션을 활용하라는 것도 말이다. 그러면 쿠키는 쓰레기인가?


답을 말하면 그렇지 않다. 당연히 로그인에선 쓰지 않는다. 그러면 어디서 쓸까?


결론부터 이야기하자면 웹사이트를 운영하면서 보안에 전혀 상관없고 서버요청(데이터베이스 접근)하기에는 무리가 있을 때 쿠키를 활용한다. 무리가 있다는 뜻은 굳이 데이터 베이스 접근을 할 필요가 있느냐 이다. 예를들어 나의 탐색목록 또는 임시 체크 목록 이라는 카테고리를 만들고 싶다. 이 기능을 위해 과연 테이블들을 새로 생성해야 할까?

답은 없다. 생성해도 된다. 하지만 굳이 그럴필요까지는 없다는 것이다. 왜냐하면 수많은 사용자들이 쓴다면 데이터베이스만 커질 뿐만 아니라 임시저장소라면 더욱이 낭비일 것이다. 그러면 각 사용자 브라우저내에서 임시데이터베이스같은 기능을 쓰면 참 좋겠다. 지금 말한 이 기능을 할 수 있는 것이 바로 쿠키이다. 쿠키는 보안에 취약하다. 하지만 누가 자기가 임시로 체크해둔것이나 열어본 목록 확인을 털거나 조작하겠는가. 절대적으로 보안과 상관없는 데이터이다. 그리고 데이터베이스에 저장될 필요가 없이 브라우저내에서 동작하므로 서버자원을 아낄 수 있다. 즉, 다른 사람과 공유할 필요도 없고 자기만 보면된다.


이제 이러한 쿠키의 활용법에 대해서 보겠다. 


표에서 체크 된 내용을 확인하는 예이다. 내가 어떤 라인을 체크했는지 쿠키에 저장 후 새로고침을 해도 계속 체크된 목록이 남아 있는 것이다. expire 즉, 파기는 사용자가 원하는 사용시간을 등록하면 된다.


먼저 부트스트랩 표를 사용하겠다. 표 구현에 대한 자세한 내용은 밑의 글을 참고하기 바란다.

http://pjh3749.tistory.com/140





자 이렇게 표를 만들자. 예시는 표이지만 실제로는 체크박스 레프트,라이트 메뉴, 사이드바 어디에서든 응용가능하다.


쿠키적용은 상단의 editText에 이름을 입력하고 버튼을 누르게 되면 해당 라인에 border가 생기면 된다. 다른 페이지를 왔다갔다 해도 계속 이 라인이 유지가 된다. 그리고 다시 같은 값을 입력했을 때 border가 지워지고 쿠키에서도 삭제된다.


실행화면을 먼저 보자.



희동이와 진구를 입력해서 저렇게 border가 생겼다. 이 상황에서 f5를 누르던 다른 사이트를 갔다 오던 저대로 계속 나오게 된다. 즉 브라우저에 값이 저장되는 것이다.



다시 희동이를 입력하면 border가 사라지고 쿠키도 없어지게 된다.


하나씩 시작해보자.


먼저 해당 버튼을 타겟팅 하자. 당연히 jQuery를 이용한다. 실무에서 자주 쓰이는 jQuery의 타겟팅에 대한 자세한 내용은 아래 게시글을 참고하기 바란다.

http://pjh3749.tistory.com/142


1
2
3
4
5
6
<div class="col-md-2">
    <div class="form-group">
        <input type="button" class="btn btn-info btn-fill pull-right" value="쿠키쿠킼">
    </div>
</div>
cs


해당 버튼의 코드이다. type을 버튼으로 해놓았으므로 스크립트내 타겟팅 $("[type=button]"); 으로 잡는다. 이게 잘 이해 안된다면 위의 링크에 설명되어 있다.


이것이 특정 버튼 타게팅이고 이제 스크립트를 만들어야 한다. 해당 jsp페이지내에 스크립트 부분을 작성해보자.

$(document).ready부분에는 만들게 될 함수들을 사용할 것이고 이 바깥쪽에 프로퍼티를 가지는 자바스크립트 객체를 만들어보자.


두 가지 종류의 객체가 필요하다. 선택된(클릭된) 라인을 구하는 객체, 쿠키설정을 위한 객체 이렇게 2개가 필요하다.


첫 번째, 라인을 구하는 객체를 보자.


lineCheck이라는 객체를 만들 건데 이 안에 필드는 아까 타게팅한 버튼, 쿠키 배열 이렇게 2개이고 프로퍼티는 4개가 들어가는데 하나 씩 살펴보자.


1
2
3
4
var lineCheck = {
    btnsTarget : null,
    cookieArray : null,
 

cs

(밑으로 이어지는 코드임)


아까도 말했듯이 첫 번째 필드는 버튼 타겟이다. 두 번째는 쿠키 배열이다. 


첫 번째 프로퍼티 initCookieArray는 단순히 배열을 하나 선언하는 것이다. 여기에 쿠키목록을 넣을 것이다. 


1
2
3
4
initCookieArray : function() {
        this.cookieArray = new Array();
    },
cs



두 번째 프로퍼티 init은 버튼 타겟팅이다. 


1
2
3
    init : function() {            
        this.btnsTarget = $("[type=button]");
    },
cs





세 번째 프로퍼티 initFn은 좀 복잡하다. var that에 this를 박았다. 여기서 this는 lineCheck객체를 의미한다. 이것을 that에 넣었다. 왜 그런지는 바로 밑의 코드를 보면 알 수 있다. this(이객체의필드를 사용할건데).btnsTarget(필드명은 버튼타켓이야).click(클릭리스너를 달거야).function(익명함수를정의한다면) 딱 여기까지하고 중괄호가 오픈된다. 그리고 이 중괄호 안에서의 코드는 아까 입력박스(처음 사진에 표위에 있는것)에서 입력된 값을 체크하는 것이다. 길이가 0이면 아무것도 입력되지 않은 것이다. 그렇지 않다면 그 값을 어디에 저장한다. 어디에?? 자 클릭리스너 중괄호가 열렸다. 열리는 순간 this가 해당 리스너의 주체로 바뀐다. 즉, 중괄호 안에서의 this는 버튼이 된다. 그러면 나는 lineCheck라는 객체를 이용하고 싶은데 (좀 전까지 this로 썼었던) 어떻게 하지? 라고 생각하는 순간 아까의 that을 떠올리자. 중괄호 열리기 직전에 that에 lineCheck객체를 박았다. 이제 이해되는가? 중괄호 안에서 that을 쓴다면 lineCheck를 이용하는 것과 같다. 즉 else문안의 that.lineFn은 lineCheck안에 lineFn을 쓴다는 의미가 된다. lineFn에 입력된 값을 던졌다. lineFn을 정의해 보자.


1
2
3
4
5
6
7
8
9
10
11
initFn : function() {            
        var that = this;
        
        this.btnsTarget.click(function() {
            if($("#textVal").val().length == 0) {
                alert("텍스트를 입력하세요");
                } else {
                    that.lineFn($("#textVal").val());
                }
        });
    },
cs


네 번째 프로퍼티인 lineFn이다. 얘는 아까 던진 텍스트박스의 값을 받는다. 그리고 쿠키 배열을 가져온다. 


$("tbody tr")에서 each를 돌렸다. 즉 표가 이렇게 생겼는데


<tbody>

<c:forEach items="${welcomeWebList}" var="welcomeWebList"

varStatus="status">

<tr>

<td><c:out value="${welcomeWebList.id}" /></td>

  <td><c:out value="${welcomeWebList.userName}" /></td>

<td><c:out value="${welcomeWebList.age}" /></td>

<td><c:out value="${welcomeWebList.country}" /></td>

<td><c:out value="${welcomeWebList.etc}" /></td>

</tr>

</c:forEach>

</tbody>



tr까지 잡아서 each를 돌리면 안의 td가 하나씩 튀어나올것이다. var $this = $(this)라고 했다. 이것 또한 tr타겟팅한것을 변수에 넣는 것이다 .변수 앞에 $는 허용이 되는데 이렇게 하는 이유는 jQuery 타게팅한 변수는 암묵적으로 $를 붙여주는 것이 관례기 때문이다. 당연히 가독성을 위해서 이다. 아까 textVal을 체크한다. 즉, 표의 이름에 해당하는 칸 $this.find("td:eq(1)") 이렇게 한다면 tbody의 tr의 td에서 1번째 요소 (0부터 시작하니 실질적위치는 2번째)인 이름에 해당하는 .text() 값을 가져온다. 비교해서 같다면 if문안을 타게된다. 타서 trLine즉 빨간줄을 의미하는 클래스가 없다면 적용해주고 있다면 지워주고 이런식이다. 다음 if문은 쿠키배열 셋팅인데 each문을 돌면서 trLine이 있는 인덱스(!!)를 배열에 push한다. 그리고 myCookie.setCookieArray(array)는 만든 배열을 넘기는 것이다. myCookie도 정의할 것이다. 물론 setCookieArray도 정의한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
lineFn : function(textVal) {            
        var array = this.cookieArray;
        $("tbody tr").each(function(index) {
            var $this = $(this);
            if(textVal == $this.find("td:eq(1)").text()) {
                if(!$this.hasClass("trLine")) {
                    $this.addClass("trLine");
                } else {
                    $this.removeClass("trLine");
                }
            }
            
            if($this.hasClass("trLine")) {
                array.push($this.index());
                alert("array에 넣는 인덱스 : "+$this.index());
            }
        });
        
        alert("cookie set!");
        myCookie.setCookieArray(array);
        
        if($('.trLine').length == $("tbody tr").length) {
            alert("꽉 참!");
        } else if($(".trLine").length == 0) {
            alert("다 지워짐");
        }
    }    
cs


cf) <style>

.trLine {

border : 4px solid #f00

}

</style>



두 번째 객체인 myCookie를 만들어보자. 프로퍼티는 4개이다. 쿠키 배열 설정, 쿠키 설정, 쿠키 배열가져오기, 쿠키가져오기. getter setter와 같은 형식이다.


첫 번째 프로퍼티인 setCookie이다. 받은 값으로 쿠키를 설정하는 것이다. 설정할때 만기날짜 (expire date)을 설정해준다. 즉, 1시간을 설정하면 1시간 후에 쿠키가 날아가는 것이다. 날짜 객체를 만든다. 그리고 setTime으로 시간을 설정하는데 현재 시간에서 1*24*60*60*1000 을 했는데 이것은 하루를 의미한다. 사용자 임의대로 시간을 설정하자. expire객체는 쿠키가 이 date형식의 데이터를 읽을 수 있게 변환해 주는 것이다. toUTCString이 그 역할을 한다. 그리고 document.cookie 문서내의 쿠키를 설정한다. 쿠키 값(바로 밑에서 만들것임) 과 만기 날짜를 넣는다.


1
2
3
4
5
6
7
8
9
setCookie : function(cvalue) {
        var d = new Date();
        
        d.setTime(d.getTime() + (1*24*60*60*1000));
        
        var expires = "expires=" + d.toUTCString();
        
        document.cookie = "trCookie=" + cvalue + "; " + expires;
    },
cs



두 번째 프로퍼티인 setCookieArray이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
setCookieArray : function(carray) {
        var str = "";
        
        for(var key in carray) {
            if(str != "") {
                str += ",";
            }
            
            str += key + ":" + carray[key];
        }
        
        this.setCookie(str);
    },
cs


받은 값으로 쿠키 문자열을 만든다. for문에 var in 구문이 나오는데 이것은 일반 for문에서 key가 i에 해당하는 같은 형태이다. 첫 빠따는 암것도 없으니 if문을 안타고 key 에 다가 (0) ":" 콜론을 더하고 배열의 0번째 요소 즉 (위에서 index(!!) 라고 했다) 클릭된 인덱스가 들어간다. 두 번째 부터 if를 타면서 쉼표를 하나씩 찍게 된다. 그리고 첫 번째 프로퍼티인 setCookie에 던진다.


세 번째, 네 번째 프로퍼티는 그냥 보면 알게된다. getCookie는 만든 쿠키를 가져온다. 앞에 trCookie= 어쩌구는 substring으로 잘라버린다.

getCookieArray는 만들어진 쿠키 스트링을 다시 하나씩 잘라서 내보낸다. 즉 인덱스만 튀어나온다. 예를들어 1,5 이런식으로.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
getCookie : function() {
        var name = "trCookie=";
        var c = document.cookie;
        return c.substring(name.length, c.length);
    },
    
    getCookieArray : function() {
        var str = this.getCookie();        
        var tmp1 = str.split(",");
        alert("tmp1 : "+tmp1);
        var reData = [];
        
        for(var i in tmp1) {
            var tmp2 = tmp1[i].split(":");
            reData[tmp2[0]] = tmp2[1];
        }
        
        return reData;
    }
cs


이제 두 객체의 정의는 끝났다. $(document).ready에서 나머지 코드를 작성하자.


lineCheck.init();

lineCheck.initCookieArray();

lineCheck.initFn();으로 초기화를 시켜주고 배열을 하나 만든다.


var arr = new Array();

arr = myCookie.getCookieArray(); 로 쿠키를 가져온다.


for(i=0; i<arr.length; i++) {

$("tbody tr:eq("+arr[i]+")").addClass("trLine");

}


그리고 이렇게 반복문 타면서 인덱스값으로 표를 하나씩 칠해준다.


그러면 쿠키로 셋팅이 완료가 된다!




참고로 라인 더블클릭시 이름에 해당하는 텍스트를 서로 맞바꾸는 예이다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var text = "";
var $that = "";
    
    $("tbody tr").dblclick(function() {
        var $this = $(this); // tr이 들어감
        
        if(!$this.hasClass("trLine")) {
            $this.addClass("trLine");
            
            if(text =="") {
                $that = $this;
                text = $this.find("td:eq(1)").text();
            } else {
                $that.find("td:eq(1)").html($(this).find("td:eq(1)").text());
                $this.find("td:eq(1)").html(text);
                text = "";
            }
        } else {
            $this.removeClass("trLine");
        }
    });
cs



이러한 기능들을 응용하여 개발을 하면 될 것이다.


글이 도움이 되셨다면 공감 한 번씩 눌러주세요~



반응형