Vue.js 3 & NodeJS/Vue 3

Vue CLI Store 데이터 유지(페이지 새로고침 - 초기화 방지, 쿠키) - Vue CLI Vuex Store State, Page Refresh, Cookie

carrotweb 2022. 1. 31. 19:10
728x90
반응형

두 번째로 Cookie(쿠키)를 사용하는 방법을 알아보도록 하겠습니다.

Cookie(쿠키)는 웹 브라우저에 데이터가 저장됩니다.

Vue 3에서 Cookie(쿠키)를 사용하기 위해서는 vue3-cookies 라이브러리를 설치해야 합니다.

Vue Cookies 설치하기

콘솔을 실행하고 Vue 프로젝트가 있는 C:\workspaces\nodeserver\testvue 폴더로 이동합니다.

Vue 프로젝트에 vue3-cookies를 설치하기 위해 콘솔에서 npm install 명령어를 실행합니다.

npm install --save vue3-cookies

또는 버전 적용
npm install --save vue3-cookies@1.0.6

npm install에 옵션으로 --save를 추가하면 자동으로 package.json 파일의 "dependencies"에 "vue3-cookies" 항목이 추가됩니다.

 

 

package.json 파일의 "dependencies"입니다.

"dependencies": {
  "axios": "^0.21.1",
  "core-js": "^3.6.5",
  "vue": "^3.0.0",
  "vue-router": "^4.0.0-0",
  "vue3-cookies": "^1.0.6", --> 추가
  "vuex": "^4.0.2"
}

 

Node.js 레스트 API 서버를 실행시킵니다.

콘솔을 실행하고 Node.js 레스트 API 서버 프로젝트가 있는 C:\workspaces\nodeserver\testrestapi 폴더로 이동합니다. 그리고 npm run 명령어를 실행합니다.

npm run start

 

Vue를 실행시킵니다.

콘솔을 실행하고 Vue 프로젝트가 있는 C:\workspaces\nodeserver\testvue 폴더로 이동합니다. 그리고 콘솔에서 npm run 명령어를 실행합니다.

npm run serve

 

 

Cookie(쿠키)를 사용하는 방법

웹 브라우저에서 F12 키를 누르면 개발자 툴이 나타납니다.

여기서 Application를 클릭하고 Cookies를 클릭합니다.

 

cookie는 다음과 같이 구성되어 저장됩니다.

Name : 쿠키 이름

Value : 쿠키 값

Domain : 도메인 - 쿠키를 수신하도록 허용된 호스트입니다.

Path : 경로 - 쿠키 헤더를 보내기 위해 요청된 URL입니다.

Expires / Max-Age : 쿠키 만료 기간 / 쿠키 최대 사용기간

Size : 쿠키 크기(byte)

HTTP : HTTP 사용 여부 - true / false

true 이면 HTTP를 통해서만 쿠키를 서버로 보낼 수 있습니다.

Secure : HTTPS 사용 여부 - true / false

true 이면 HTTPS를 통해서만 쿠키를 서버로 보낼 수 있습니다.

SameSite : 사이트 제한 설정 - none, strict(기본값), lax로 설정합니다.

쿠키를 자사(www.home.com) 또는 동일 사이트(dev.home.com) 컨텍스트로 제한해야 하는지를 선언할 수 있습니다. CSRF(Cross-Site Request Forgery - 교차 사이트 요청 위조) 공격을 방지하기 위해 HTTP 쿠키에서 설정할 수 있는 속성입니다.

- none : 모든 도메인에 쿠키가 전송됩니다.

- strict : 동일한 사이트 내의 요청에만 전송됩니다.

- lax : 동일한 사이트 내의 요청 또는 "안전한" HTTP 메서드를 사용하는 최상위 경로(/)인 경우 전송됩니다.

SameParty : 동일 사이트 사용 여부 - true / false

true 이면 동일한 사이트 내의 요청에서 최상위 경로(/)인 경우 쿠키를 설정하거나 전송할 수 있습니다.

Priority : 우선순위 - low, medium(기본값), high로 설정합니다.

 

cookie 테스트를 위해 Local Storage(로컬 스토리지)의 데이터는 삭제해 주시기 바랍니다.

Cookie(쿠키)에 state 저장하고 읽기

1. C:\workspaces\nodeserver\testvue\src\store\modules\login.js 파일을 오픈합니다.

vue3-cookies를 import 하고 쿠키를 사용하기 위해 useCookies() 메서드를 가져옵니다.

import { useCookies } from "vue3-cookies";

useCookies() 메서드를 사용하여 cookie를 생성합니다.

const { cookies } = useCookies();

 

2. cookie에 state를 저장하기 위해서 mutations에 saveStateToStorage() 함수를 수정합니다.

memberId, accessToken, refreshToken를 cookie의 set() 메서드로 저장합니다.

기존 소스는 주석 처리나 삭제하시기 바랍니다.

// Storage에 state를 저장합니다.
saveStateToStorage(state) {
	cookies.set("testvue.login.memberId", state.memberId);
	cookies.set("testvue.login.accessToke", state.accessToken);
	cookies.set("testvue.login.refreshToken", state.refreshToken);
}

 

cookie의 set() 메서드의 파라미터는 이름(Name), 값(Value), 만료 기간(Expires)입니다.

만료 기간을 설정하지 않으면 하루(1d)로 설정됩니다. 만료 기간은 1초 단위로 계산됩니다.

cookies.set(Name, Value, Expires);

 

그리고 cookie에서 저장된 state를 읽기 위해서 mutations에 readStateFromStorage() 함수를 수정합니다. 저장된 정보를 cookie의 get() 메서드로 읽어 들어 state에 적용합니다.

// Storage에서 state를 읽어옵니다.
readStateFromStorage(state) {
	if (cookies.get("testvue.login.memberId") != null) {
		state.memberId = cookies.get("testvue.login.memberId");
	}
	if (cookies.get("testvue.login.accessToken") != null) {
		state.accessToken = cookies.get("testvue.login.accessToken");
	}
	if (cookies.get("testvue.login.refreshToken") != null) {
		state.refreshToken = cookies.get("testvue.login.refreshToken");
	}
}

 

반응형

 

cookie의 get() 메서드의 파라미터는 이름(Name)입니다.

cookies.set(Name);

 

3. 로그아웃되면 cookie에서 저장된 state를 삭제시키기 위해 reset() 함수를 수정합니다.

// 초기화시킵니다.
reset(state) {
	state.memberId = '';
	state.accessToken = '';
	state.refreshToken = '';
	cookies.remove("testvue.login.memberId");
	cookies.remove("testvue.login.accessToke");
	cookies.remove("testvue.login.refreshToken");
}

 

cookie의 remove() 메서드의 파라미터는 이름(Name)입니다.

cookies.remove(Name);

 

4. 로그인을 합니다. 그러면 Application의 Cookies에 state가 저장되어 있는 것을 확인할 수 있습니다.

그리고 웹 브라우저에서 새로고침(F5)을 하여도 로그인이 유지되는 것을 확인할 수 있습니다.

 

Application의 Cookies에 저장된 state의 내용은 다음과 같습니다.

Name : testvue.login.accessToke
Value : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZW1iZXJJZCI6InRlc3RpZDEiLCJtZW1iZXJOYW1lIjoi7ZmN6ri464-ZIiwiaWF0IjoxNjQzNTQzMzIzLCJleHAiOjE2NDM1NDMzODN9.jrqn-GXh--Y4hqz3AUG9cB9bbwXnICJEQcHN2YO6xXU
Domain : localhost
Path : /
Expires / Max-Age : 2022-01-31T11:48:43.176Z
Size : 213
HTTP :
Secure :
SameSite : Lax
SameParty :
Priority : Medium	

Name : testvue.login.memberId
Value : testid1
Domain : localhost
Path : /
Expires / Max-Age : 2022-01-31T11:48:43.176Z
Size : 29
HTTP :
Secure :
SameSite : Lax
SameParty :
Priority : Medium	

Name : testvue.login.refreshToken
Value : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZW1iZXJJZCI6InRlc3RpZDEiLCJpYXQiOjE2NDM1NDMzMjMsImV4cCI6MTY0MzYyOTcyM30.C5RZjWnBe1Gygu3dTTUtqa1w0gi6mjBZjA4PzovsZxs\
Domain : localhost
Path : /
Expires / Max-Age : 2022-01-31T11:48:43.176Z
Size : 182
HTTP :
Secure :
SameSite : Lax
SameParty :
Priority : Medium

 

cookie의 set() 메서드에서 만료 기간을 지정하지 않으면 현재 시간에서 하루(1d)가 추가되어 설정됩니다. 그리고 경로(Path)도 설정하지 않았기 때문에 최상위 경로(/)로 설정됩니다.

하루가 지난 후 cookie가 만료가 되어 accessToken과 refreshToken가 삭제되면 토큰을 사용하는 이유가 없어집니다. 그래서 토큰의 만료 기간은 refreshToken의 만료 기간과 같이 해야 합니다.

"Node.js 레스트 API 인증처리(토큰 재발급)"에서 refreshToken의 토큰 만료 기간이 1일로 되어 있습니다. 그래서 만료 기간을 설정하지 않아도 되지만 cookie의 만료 기간을 1일(60 * 60 * 24)로 설정합니다.

// Storage에 state를 저장합니다.
saveStateToStorage(state) {
	cookies.set("testvue.login.memberId", state.memberId, 60 * 60 * 24);
	cookies.set("testvue.login.accessToke", state.accessToken, 60 * 60 * 24);
	cookies.set("testvue.login.refreshToken", state.refreshToken, 60 * 60 * 24);
}

 

 

실제로 Node.js 레스트 API 서버를 제작하실 때는 만료 시간을 프로젝트에 따라 조절하시기 바랍니다.

state 정보를 JSON 객체로 관리할 경우에는 다음과 같이 수정하시면 됩니다.

cookie에서 get() 메서드로 JSON 객체를 가져올 때는 자동으로 JSON 객체로 변환됩니다. JSON.parse() 메서드를 사용하지 않아도 됩니다.

// 초기화시킵니다.
reset(state) {
	state.memberId = '';
	state.accessToken = '';
	state.refreshToken = '';
	//cookies.remove("testvue.login.memberId");
	//cookies.remove("testvue.login.accessToke");
	//cookies.remove("testvue.login.refreshToken");
	cookies.remove("testvue.login");
},
// Storage에 state를 저장합니다.
saveStateToStorage(state) {
	//cookies.set("testvue.login.memberId", state.memberId, 60 * 60 * 24 * 30);
	//cookies.set("testvue.login.accessToke", state.accessToken, 60 * 60 * 24 * 30);
	//cookies.set("testvue.login.refreshToken", state.refreshToken, 60 * 60 * 24 * 30);
	cookies.set("testvue.login", JSON.stringify(state), 60 * 60 * 24 * 30);
},
// Storage에서 state를 읽어옵니다.
readStateFromStorage(state) {
	//if (cookies.get("testvue.login.memberId") != null) {
	//	state.memberId = cookies.get("testvue.login.memberId");
	//}
	//if (cookies.get("testvue.login.accessToken") != null) {
	//	state.accessToken = cookies.get("testvue.login.accessToken");
	//}
	//if (cookies.get("testvue.login.refreshToken") != null) {
	//	state.refreshToken = cookies.get("testvue.login.refreshToken");
	//}
	if (cookies.get("testvue.login") != null) {
		let storage = cookies.get("testvue.login");
		if (storage.memberId != null) {
			state.memberId = storage.memberId;
		}
		if (storage.accessToken != null) {
			state.accessToken = storage.accessToken;
		}
		if (storage.memberId != null) {
			state.refreshToken = storage.refreshToken;
		}
	}
}

728x90
반응형