vue2_frontend...

This commit is contained in:
최준흠 2022-09-16 16:57:23 +09:00
parent 3978156981
commit c608882682
11 changed files with 130 additions and 67 deletions

11
package-lock.json generated
View File

@ -14,7 +14,6 @@
"core-js": "^3.8.3", "core-js": "^3.8.3",
"vee-validate": "^3.4.14", "vee-validate": "^3.4.14",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-cookies": "^1.8.1",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"vue2-editor": "^2.10.3", "vue2-editor": "^2.10.3",
"vuex": "^3.6.2" "vuex": "^3.6.2"
@ -10644,11 +10643,6 @@
"csstype": "^3.1.0" "csstype": "^3.1.0"
} }
}, },
"node_modules/vue-cookies": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.8.1.tgz",
"integrity": "sha512-PDq1EaiRRyau5PBQVscXboHW+iWtcG4wRY2UKIz1j0nrjb3KESRU1PUyNUDdOajAwy4RH1IfiNR0suhWRXQdrA=="
},
"node_modules/vue-eslint-parser": { "node_modules/vue-eslint-parser": {
"version": "8.3.0", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
@ -19491,11 +19485,6 @@
"csstype": "^3.1.0" "csstype": "^3.1.0"
} }
}, },
"vue-cookies": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.8.1.tgz",
"integrity": "sha512-PDq1EaiRRyau5PBQVscXboHW+iWtcG4wRY2UKIz1j0nrjb3KESRU1PUyNUDdOajAwy4RH1IfiNR0suhWRXQdrA=="
},
"vue-eslint-parser": { "vue-eslint-parser": {
"version": "8.3.0", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",

View File

@ -14,7 +14,6 @@
"core-js": "^3.8.3", "core-js": "^3.8.3",
"vee-validate": "^3.4.14", "vee-validate": "^3.4.14",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-cookies": "^1.8.1",
"vue-router": "^3.5.1", "vue-router": "^3.5.1",
"vue2-editor": "^2.10.3", "vue2-editor": "^2.10.3",
"vuex": "^3.6.2" "vuex": "^3.6.2"

View File

@ -59,18 +59,19 @@ export default {
...authStore.mapGetters(['isAuthenticated']) ...authStore.mapGetters(['isAuthenticated'])
}, },
methods: { methods: {
redirect() { async redirect() {
if (!this.isAuthenticated && this.$router.name != 'home') { if (!this.isAuthenticated && this.$router.name != 'home') {
this.$router.push({ name: 'home' }).catch((e) => { await this.$router.push({ name: 'home' })
console.log(e + ':' + this.$router)
})
} }
}, },
logout() { async logout() {
this.$store try {
.dispatch('AuthStore/logout', {}) await this.$store
.then(() => this.redirect()) .dispatch('AuthStore/logout', {})
.catch(({ message }) => alert(message)) .then(() => this.redirect())
} catch (e) {
alert(e.message)
}
} }
} }
} }

View File

@ -136,14 +136,13 @@
</div> </div>
</template> </template>
<script> <script>
import createNamespacedHelpers from 'vuex'
import todoService from '@/service/todo.service' import todoService from '@/service/todo.service'
const store = createNamespacedHelpers('TodoStore') import { createNamespacedHelpers } from 'vuex'
// : https://vuejsexamples.com/vuejs-tables-and-select-all-checkbox/ const todoStore = createNamespacedHelpers('TodoStore')
export default { export default {
components: {}, components: {},
computed: { computed: {
...store.mapGetters(['getTotal', 'getRows']) ...todoStore.mapGetters(['getTotal', 'getRows'])
}, },
created: function () { created: function () {
this.setDatas() this.setDatas()
@ -249,7 +248,7 @@ export default {
methods: { methods: {
async setDatas(page = 1) { async setDatas(page = 1) {
try { try {
const datas = await todoService.setDatas({ const params = {
page: page, page: page,
perPage: this.perPage, perPage: this.perPage,
sortBy: this.sortBy, sortBy: this.sortBy,
@ -260,11 +259,11 @@ export default {
filterField: this.filterField, filterField: this.filterField,
filterDateStart: this.filterDateStart, filterDateStart: this.filterDateStart,
filterDateEnd: this.filterDateEnd filterDateEnd: this.filterDateEnd
}) }
console.log(datas) const datas = await todoService.getDatas(params)
this.$store.dispatch('TodoStore/setDatas', datas)
} catch (e) { } catch (e) {
console.log(e) alert(e.message)
alert(e.response.data.message)
} }
}, },
searchClick() { searchClick() {

View File

@ -29,9 +29,13 @@ instance.interceptors.request.use(
//Response 처리용 //Response 처리용
instance.interceptors.response.use( instance.interceptors.response.use(
(response) => { (response) => {
console.log('성공')
console.log(response)
return response return response
}, },
async (err) => { async (err) => {
console.log('실패')
console.log(err)
//err.config->이전에 보냈던 api (url등)정보 전달용 //err.config->이전에 보냈던 api (url등)정보 전달용
//err.response->오류 상태를 알기 위해 //err.response->오류 상태를 알기 위해
//originalConfig._retry는 처음 시도용인지 알기 위해 //originalConfig._retry는 처음 시도용인지 알기 위해

View File

@ -1,5 +1,73 @@
import axios from 'axios' import axios from 'axios'
const todoApi = axios.create({ import authApi from './auth.api'
import tokenService from '../service/token.service'
const instance = axios.create({
baseURL: process.env.VUE_APP_TODO_HOST baseURL: process.env.VUE_APP_TODO_HOST
}) })
export default todoApi
//API Request 전 처리용
instance.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded'
instance.defaults.headers.get['Accepts'] = 'application/json'
instance.defaults.timeout = 2500
//Request 처리용
instance.interceptors.request.use(
(config) => {
const token = tokenService.getLocalAccessToken()
if (token) {
config.headers['Authorization'] = 'Bearer ' + token // for Spring Boot back-end
config.headers['x-access-token'] = token // for Node.js Express back-end
}
return config
},
(error) => {
// Do something with request error
Promise.reject(error)
}
)
//Response 처리용
instance.interceptors.response.use(
(response) => {
console.log('성공')
console.log(response)
return response
},
async (err) => {
console.log('실패')
console.log(err)
//err.config->이전에 보냈던 api (url등)정보 전달용
//err.response->오류 상태를 알기 위해
//originalConfig._retry는 처음 시도용인지 알기 위해
const originalConfig = err.config
if (originalConfig.url !== '/auth/login' && err.response) {
if (err.response.status === 401 && !originalConfig._retry) {
return await reloadAccessToken(originalConfig)
}
}
return Promise.reject(err)
}
)
//AccessToken이 만료된경우 다시 받기위한 함수
const reloadAccessToken = async (originalConfig) => {
// Access Token이 expired,오류로 인한 response 401 답볍을 받은경우
originalConfig._retry = true
try {
//Refresh Token으로 다시 Access Token 재생성 후 로그인 다시하라고 오류보냄
await authApi
.post('/auth/reload', {
refresh_token: tokenService.getLocalRefreshToken()
})
.then((rs) => {
const { access_token } = rs.data
tokenService.updateLocalAccessToken(access_token)
})
//reload로 access_token을 재발급을 받았으면 이전 APICall 다시 호출
return await instance(originalConfig)
} catch (_error) {
return Promise.reject(_error)
}
}
export default instance

View File

@ -1,5 +1,5 @@
import api from '../interceptors/auth.api' import api from '../interceptors/auth.api'
import tokenService from './token.service' import tokenService from '../service/token.service'
class AuthService { class AuthService {
async login(email, password) { async login(email, password) {
return await api return await api
@ -9,7 +9,6 @@ class AuthService {
if (data.access_token) { if (data.access_token) {
tokenService.setUser(data) tokenService.setUser(data)
} }
return data
}) })
} }
@ -25,7 +24,6 @@ class AuthService {
if (data.access_token) { if (data.access_token) {
tokenService.setUser(data) tokenService.setUser(data)
} }
return data
}) })
} }
} }

View File

@ -1,13 +1,9 @@
import api from '../interceptors/todo.api' import api from '../interceptors/todo.api'
import tokenService from './token.service'
class TodoService { class TodoService {
async login(params) { async getDatas(params) {
console.log(params) //console.log(params)
return await api.get('/todo', { params: params }).then((response) => { return await api.get('/todo', { params: params }).then((response) => {
const { data } = response const { data } = response
if (data.access_token) {
tokenService.setUser(data)
}
return data return data
}) })
} }

View File

@ -1,4 +1,9 @@
class TokenService { class TokenService {
isAuthenticated() {
const isAuthenticated =
!!this.getLocalAccessToken() || !!this.getLocalRefreshToken()
return isAuthenticated
}
getLocalAccessToken() { getLocalAccessToken() {
const user = this.getUser() const user = this.getUser()
return user?.access_token return user?.access_token
@ -16,10 +21,11 @@ class TokenService {
return JSON.parse(localStorage.getItem('user')) return JSON.parse(localStorage.getItem('user'))
} }
setUser(user) { setUser(user) {
console.log(JSON.stringify(user)) console.log('set User..')
localStorage.setItem('user', JSON.stringify(user)) localStorage.setItem('user', JSON.stringify(user))
} }
removeUser() { removeUser() {
console.log('remove User..')
localStorage.removeItem('user') localStorage.removeItem('user')
} }
} }

View File

@ -3,45 +3,48 @@ import tokenService from '../service/token.service'
// count state 속성 추가 // count state 속성 추가
const state = { const state = {
takens: {} tokenService: tokenService
} }
const getters = { const getters = {
getTokens: function (state) { isAuthenticated: function (state) {
return state.takens return state.tokenService.isAuthenticated()
}, },
isAuthenticated: function () { getUser: function (state) {
const isAuthenticated = return state.tokenService.getUser()
!!tokenService.getLocalAccessToken() || },
!!tokenService.getLocalRefreshToken() getTokens: function (state) {
return isAuthenticated return {
access_token: state.tokenService.getLocalAccessToken(),
refresh_toke: state.tokenService.getLocalRefreshToken()
}
} }
} }
const mutations = { const mutations = {
register: function (state, tokens) { register: function (state, user) {
state.takens = tokens state.tokenService.setUser(user)
}, },
login: function (state, tokens) { login: function (state, user) {
state.takens = tokens state.tokenService.setUser(user)
}, },
logout: function (state) { logout: function (state) {
state.takens = {} state.tokenService.removeUser()
}, },
reload: function (state, access_token) { reload: function (state, access_token) {
state.takens.access_token = access_token state.tokenService.updateLocalAccessToken(access_token)
} }
} }
const actions = { const actions = {
register: async function (context, tokens) { register: function (context, user) {
context.commit('register', tokens) context.commit('register', user)
}, },
login: async function (context, tokens) { login: function (context, user) {
context.commit('login', tokens) context.commit('login', user)
}, },
logout: async function (context) { logout: function (context) {
return await context.commit('logout') return context.commit('logout')
}, },
reload: async function (context, access_token) { reload: function (context, access_token) {
return await context.commit('reload', access_token) return context.commit('reload', access_token)
} }
} }
export default { namespaced: true, state, getters, mutations, actions } export default { namespaced: true, state, getters, mutations, actions }

View File

@ -11,14 +11,14 @@ const getters = {
} }
} }
const mutations = { const mutations = {
setDatas: function (state, datas) { setDatas: async function (state, datas) {
state.total = datas.total state.total = datas.total
state.rows = datas.rows state.rows = datas.rows
} }
} }
const actions = { const actions = {
setDatas: function (context, datas) { setDatas: async function (context, datas) {
context.commit('setDatas', datas.data) await context.commit('setDatas', datas)
} }
} }
export default { namespaced: true, state, getters, mutations, actions } export default { namespaced: true, state, getters, mutations, actions }