public 폴더의 index.html이 애플리케이션의 가장 첫번째 진입점이다.
- 여기에 폰트, 아이콘 추가 하는것
Token
- 사용자가 인증 되었을때만 발급되는것
로그인한 사용자의 토큰을 넣어서 API에 넘길거다. 토큰값을 어딘가에 저장하고 API 호출할때마다 사용할것
1. axios.create에 headers 추가하기
- Authorization 속성에 test1234 라고 쓴 후 API 요청을 실행했을때 네트워크 패널에서 Authorization에 test1234가 있는걸 확인 할 수 있다.
import axios from 'axios';
// axios.create 할때 주입한 속성은 인스턴스로 데이터 요청 할때마다 무조건 이 속성들이 정의된 상태로 수행된다.
const instance = axios.create({
baseURL: process.env.VUE_APP_API_URL,
// HTTP 헤더에 있는 속성
headers: {
Authorization: 'test1234',
},
});
function registerUser(userData) {
return instance.post('signup', userData);
}
function loginUser(userData) {
return instance.post('login', userData);
}
export { registerUser, loginUser };
2. store에 Token 추가
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
username: '',
token: '', //token
},
getters: {
isLogin(state) {
return state.username !== '';
},
},
mutations: {
setUsername(state, username) {
state.username = username;
},
clearUsername(state) {
state.username = '';
},
setToken(state, token) {
state.token = token; //token
},
},
});
3. loginForm 로그인 후 Token 값 store에 저장
<template>
<div class="contents">
<div class="form-wrapper form-wrapper-sm">
<form @submit.prevent="submitForm" class="form">
<div>
<label for="username">id:</label>
<input id="username" type="text" v-model="username" />
<p class="validation-text">
<span class="warning" v-if="!isUsernameValid && username">
Please enter an email address
</span>
</p>
</div>
<div>
<label for="password">pw:</label>
<input id="password" type="text" v-model="password" />
</div>
<button
:disabled="!isUsernameValid || !password"
type="submit"
class="btn"
>
로그인
</button>
</form>
<p class="log">{{ logMessage }}</p>
</div>
</div>
</template>
<script>
import { loginUser } from '@/api/index';
import { validateEmail } from '@/utils/validation';
export default {
data() {
return {
// form values
username: '',
password: '',
// log
logMessage: '',
};
},
computed: {
isUsernameValid() {
return validateEmail(this.username);
},
},
methods: {
async submitForm() {
try {
// 비즈니스 로직
const userData = {
username: this.username,
password: this.password,
};
const { data } = await loginUser(userData);
console.log(data.token);
this.$store.commit('setToken', data.token); //token
this.$store.commit('setUsername', data.user.username);
this.$router.push('/main');
} catch (error) {
// 에러 핸들링할 코드
console.log(error.response.data);
this.logMessage = error.response.data;
} finally {
this.initForm();
}
},
initForm() {
this.username = '';
this.password = '';
},
},
};
</script>
<style>
.btn {
color: white;
}
</style>
4. api 폴더 index.js에 Authorization: store.state.token
import axios from 'axios';
import store from '@/store/index'; //import 꼭 해줘야함
// axios.create 할때 주입한 속성은 인스턴스로 데이터 요청 할때마다 무조건 이 속성들이 정의된 상태로 수행된다.
const instance = axios.create({
baseURL: process.env.VUE_APP_API_URL,
// HTTP 헤더에 있는 속성
headers: {
// 토큰을 여기에 실을것
Authorization: store.state.token,
},
});
function registerUser(userData) {
return instance.post('signup', userData);
}
function loginUser(userData) {
return instance.post('login', userData);
}
export { registerUser, loginUser };
5. Interceptors 사용 (그냥 쓰면 API 호출 하기전에 Request에 Token 값 보내는게 됨)
- Interceptors 는 서버 요청, 응답을 처리하기 전에 추가 로직을 넣을수 있는것
- 말 그대로 가로채기
https://github.com/axios/axios#interceptors
- api 폴더에 common 폴더 추가, interceptors.js 파일 추가
- index.js 파일에 늘어놓으면 뭐하는 컴포넌트인지 한눈에 보기 어려워짐으로 분리한것
6. interceptors.js 파일에 setInterceptors 함수 생성 (인터셉터의 모듈화)
// 무분별하게 늘어놓는것보단 함수로 묶기 + export 시키기 + instance 받아오기
export function setInterceptors(instance) {
// aixos → instance 로 설정 변경
// Add a request interceptor
instance.interceptors.request.use(
function(config) {
// Do something before request is sent
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
},
);
// aixos → instance 로 설정 변경
// Add a response interceptor
instance.interceptors.response.use(
function(response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
},
function(error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
},
);
// aixos → instance 설정 다 하고 return
return instance;
}
7. api폴더 index.js 파일에 createInstance 함수 생성 (인터셉터의 모듈화)
import axios from 'axios';
import store from '@/store/index';
// interceptors.js 에서 setInterceptors 함수 받아오기
import { setInterceptors } from './common/interceptors';
// createInstance 함수로 하나로 묶기.
// 이렇게 하면 이 함수의 결과는 instance를 셋업하고 interceptors를 설정하게됨
function createInstance() {
// axios.create 할때 주입한 속성은 인스턴스로 데이터 요청 할때마다 무조건 이 속성들이 정의된 상태로 수행된다.
const instance = axios.create({
baseURL: process.env.VUE_APP_API_URL,
// HTTP 헤더에 있는 속성
headers: {
// 토큰을 여기에 실을것
Authorization: store.state.token,
},
});
// setInterceptors 함수에 instance 보내기
return setInterceptors(instance);
}
// createInstance함수 값 받아오기
const instance = createInstance();
function registerUser(userData) {
return instance.post('signup', userData);
}
function loginUser(userData) {
return instance.post('login', userData);
}
export { registerUser, loginUser };
8. 인터셉터에 Token 넣기
- config.headers.Authorization = store.state.token;
- config를 console 로 확인해보면 headers가 있는걸 확인 할 수 있다.
- 여기에 Authorization 추가 후 token 값 넣기
이런식으로 매 API 요청마다 일일이 실어주는게 아니라 Authorization 속성, interceptors 라는 속성을 이용해서
매번 Store에 있는 state의 값을 들고와서 담아준단것을 확인 할 수 있다.
import store from '@/store/index';
// 무분별하게 늘어놓는것보단 함수로 묶기 + export 시키기 + instance 받아오기
export function setInterceptors(instance) {
// aixos → instance 로 설정 변경
// Add a request interceptor
instance.interceptors.request.use(
function(config) {
// Do something before request is sent Request에 요청을 보내기 직전 코드
// HTTP 헤더에 있는 속성 - headers
config.headers.Authorization = store.state.token;
return config;
},
function(error) {
// Do something with request error
// 보냈을때 에러가나면 처리
return Promise.reject(error);
},
);
// aixos → instance 로 설정 변경
// Add a response interceptor
instance.interceptors.response.use(
function(response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
return response;
},
function(error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
},
);
// aixos → instance 설정 다 하고 return
return instance;
}
'vue.js > vue.js 2' 카테고리의 다른 글
122. 학습 노트 목록 아이템 컴포넌트화 | Props 내려주고 받는 방법 (0) | 2023.02.13 |
---|---|
121. Main Page - 학습 노트 조회 API 함수 구현 | v-for로 Data 바인딩 (0) | 2023.02.05 |
119. 로그아웃 기능 구현 | mutations에 clearUsernmae 함수 추가 (0) | 2023.01.24 |
118. 로그인 후 처리 | 컴포넌트 간 데이터 전달방법 3가지 | vuex store 사용 (0) | 2023.01.24 |
117. 로그인 후 Main 페이지 이동 | this.$router.push('/main'); (0) | 2023.01.18 |