-
Axios 기초 배우기 #5 (헤더에 토큰 담아 보내기)front-end/Vue.js 2022. 2. 23. 10:13728x90
실제 로그인을 하기 위해 actions에 로그인 로직을 작성하여 준다.
src/views/Login.vue
<template> <v-container fill-height style="max-width:450px;"> <v-layout align-center row wrap> <v-flex xs12> <v-alert type="error" :value="isLoginError"> 아이디와 비밀번호를 확인하세요 </v-alert> <v-alert type="success" :value="isLogin"> 로그인 성공 </v-alert> <v-card> <v-toolbar flat color="blue-grey lighten-5"> <v-toolbar-title>로그인</v-toolbar-title> </v-toolbar> <div class="pa-3"> <v-text-field v-model="email" label="이메일을 입력하세요"> </v-text-field> <v-text-field v-model="password" type="password" label="패스워드를 입력하세요" > </v-text-field> <v-btn block large depressed color="primary" @click="login({ email, password })" >로그인</v-btn > </div> </v-card> </v-flex> </v-layout> </v-container> </template> \ <script> import { mapState, mapActions } from "vuex"; export default { data() { return { email: null, password: null, }; }, computed: { ...mapState(["isLogin", "isLoginError"]), }, methods: { ...mapActions(["login"]), }, }; </script>
테스트를 위한 버튼을 지워주고 axios통신은 로그인 버튼이 눌러졌을 때 처리할 것이기에 store 쪽에 붙여준다.
src/store/index.js
import Vue from "vue"; import Vuex from "vuex"; import router from "../router"; import axios from "axios"; Vue.use(Vuex); export default new Vuex.Store({ state: { userInfo: null, allUsers: [ { id: 1, name: "hoza", email: "hoza@gmail.com", password: "123456" }, { id: 2, name: "lego", email: "lego@gmail.com", password: "123456" }, ], isLogin: false, isLoginError: false, }, mutations: { // 로그인이 성공했을 때, loginSuccess(state, payload) { state.isLogin = true; state.isLoginError = false; state.userInfo = payload; }, // 로그인이 실패했을 때 loginError(state) { state.isLogin = false; state.isLoginError = true; }, logout(state) { state.isLogin = false; state.isLoginError = false; state.userInfo = null; }, }, actions: { //로그인 시도 login({ commit }, loginObj) { // eslint-disable-line no-unused-vars axios .post("https://reqres.in/api/login", loginObj) .then(res => { console.log(res); }) .catch(err => { console.log(err); }); // let selectedUser = null; // state.allUsers.forEach((user) => { // if (user.email === loginObj.email) selectedUser = user; // }); // if (selectedUser === null || selectedUser.password !== loginObj.password) // commit("loginError"); // else { // commit("loginSuccess", selectedUser); // router.push({ path: "/mypage" }); // } }, logout({ commit }) { commit("logout"); router.push({ path: "/" }); }, }, modules: {}, });
login 버튼이 눌러졌을 때 email과 password를 오브젝트로 받아오게 되고 이 정보는 loginObj로 인자로 사용한다.
store에 저장해놓은 데이터를 확인할 필요가 없으니 주석 처리하였고,
POST 방식으로 서버와 통신한다.reqres.in에 적힌 이메일과 패스워드로 로그인을 시도하였고 토큰을 받아왔다. POST 방식으로 받아온 토큰을 통해 다시 한번 GET 방식으로 요청을 보낸다.
이때, config에는 headers를 담아 보낼 수 있고 거기에 토큰을 담는다.
import Vue from "vue"; import Vuex from "vuex"; import router from "../router"; import axios from "axios"; Vue.use(Vuex); export default new Vuex.Store({ state: { userInfo: null, allUsers: [ { id: 1, name: "hoza", email: "hoza@gmail.com", password: "123456" }, { id: 2, name: "lego", email: "lego@gmail.com", password: "123456" }, ], isLogin: false, isLoginError: false, }, mutations: { // 로그인이 성공했을 때, loginSuccess(state, payload) { state.isLogin = true; state.isLoginError = false; state.userInfo = payload; }, // 로그인이 실패했을 때 loginError(state) { state.isLogin = false; state.isLoginError = true; }, logout(state) { state.isLogin = false; state.isLoginError = false; state.userInfo = null; }, }, actions: { //로그인 시도 login({ commit }, loginObj) { // eslint-disable-line no-unused-vars axios .post("https://reqres.in/api/login", loginObj) //파라미터(body) 를 넣어줄 수 있음 .then(res => { //성공 시 토큰을 받아옴 (실제로는 user_id 값을 받아옴) //토큰을 헤더에 포함시켜서 유저 정보를 요청 let config = { //config에 헤더 값을 넣을 수 있음 headers: { "access-token": res.data.token } } axios .get("https://reqres.in/api/users/2", config) .then(response => { console.log(response) }) .catch(error => { console.log(error) }) console.log(res) }) .catch(err => { console.log(err); }); // let selectedUser = null; // state.allUsers.forEach((user) => { // if (user.email === loginObj.email) selectedUser = user; // }); // if (selectedUser === null || selectedUser.password !== loginObj.password) // commit("loginError"); // else { // commit("loginSuccess", selectedUser); // router.push({ path: "/mypage" }); // } }, logout({ commit }) { commit("logout"); router.push({ path: "/" }); }, }, modules: {}, });
response의 headers에는 토큰에 대한 내용이 없다. 결과가 돌아오는 것에 대한 header이기 때문이다. Network를 통해 확인해 보면 토큰을 확인할 수 있다. import Vue from "vue"; import Vuex from "vuex"; import router from "../router"; import axios from "axios"; Vue.use(Vuex); export default new Vuex.Store({ state: { userInfo: null, allUsers: [ { id: 1, name: "hoza", email: "hoza@gmail.com", password: "123456" }, { id: 2, name: "lego", email: "lego@gmail.com", password: "123456" }, ], isLogin: false, isLoginError: false, }, mutations: { // 로그인이 성공했을 때, loginSuccess(state, payload) { state.isLogin = true; state.isLoginError = false; state.userInfo = payload; }, // 로그인이 실패했을 때 loginError(state) { state.isLogin = false; state.isLoginError = true; }, logout(state) { state.isLogin = false; state.isLoginError = false; state.userInfo = null; }, }, actions: { //로그인 시도 login({ commit }, loginObj) { axios .post("https://reqres.in/api/login", loginObj) //파라미터(body) 를 넣어줄 수 있음 .then((res) => { //성공 시 토큰을 받아옴 (실제로는 user_id 값을 받아옴) //토큰을 헤더에 포함시켜서 유저 정보를 요청 let config = { //config에 헤더 값을 넣을 수 있음 headers: { "access-token": res.data.token, }, }; axios .get("https://reqres.in/api/users/2", config) .then((response) => { let userInfo = { id: response.data.data.id, first_name: response.data.data.first_name, last_name: response.data.data.last_name, avatar: response.data.data.avatar, email: response.data.data.email, }; commit("loginSuccess", userInfo); }) .catch(() => { alert("이메일과 비밀번호를 확인하세요."); }); }) .catch(() => { alert("이메일과 비밀번호를 확인하세요."); }); }, logout({ commit }) { commit("logout"); router.push({ path: "/" }); }, }, modules: {}, });
코드를 정리하자면 axios로 로그인을 서버에 요청할 때 POST 방식으로 email과 password를 loginObj로 만들어 파라미터를 보낸다.
성공했다면 다시 한번 토큰을 활용해 GET 방식으로 유저 정보를 요청한다.
토큰은 POST 방식으로 값을 받아왔을 때의 axios 로직의 data에 담겨있다 (rse.data.token)
토큰은 config라는 오브젝트를 만들어 headers에 담아 보내게 된다.
토큰을 가지고 유저 정보를 반환했을 때의 값(id, email...)을 저장하고 mutations의 loginSuccess에 payload로 보내게 된다.
그럼 그 유저 정보는 결과적으로 state에 담기게 되어 사용할 수 있게 되고 commit 된 loginSuccess에서는 로그인 성공 신호를 보내주게 된다.state에 유저 정보를 담아온 모습이 조금 변하였기 때문에 Mypage를 수정해 준다.
src/views/Mypage.vue
<template> <div> <h1>{{ userInfo.first_name }} {{ userInfo.last_name }}님 환영합니다.</h1> </div> </template> <script> import { mapState } from "vuex"; export default { computed: { ...mapState(["userInfo"]), }, }; </script>
크롬의 Vue Dev 툴을 사용하게 되면 state와 mutation 등이 각각 어떻게 변하였는지 확인할 수 있다. 728x90'front-end > Vue.js' 카테고리의 다른 글
향상된 객체 리터럴(Enhanced Object Literal) / ES6 (0) 2022.02.23 Axios 기초 배우기 #6 (새로고침 시 로그인 해제 방지) (0) 2022.02.23 Axios 기초 배우기 #4 (토큰을 활용한 로그인 프로세스) (0) 2022.02.23 Axios 기초 배우기 #3 (POST 방식으로 통신하기) (0) 2022.02.23 Axios 기초 배우기 #2 (GET 방식으로 통신하기) (0) 2022.02.23