added refresh token logic
This commit is contained in:
parent
08201b954c
commit
bae8d26e59
|
|
@ -6,4 +6,27 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { IonApp, IonRouterOutlet } from '@ionic/vue';
|
import { IonApp, IonRouterOutlet } from '@ionic/vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { AppStore } from '@/store';
|
||||||
|
import { onMounted, onBeforeUnmount } from "vue";
|
||||||
|
import EventBus from "./common/EventBus";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const store = useStore<AppStore>();
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
store.dispatch('auth/logout');
|
||||||
|
router.push('/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
EventBus.on("logout", () => {
|
||||||
|
logout();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
EventBus.remove("logout", null);
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
const eventBus = {
|
||||||
|
on(event: string, callback) {
|
||||||
|
document.addEventListener(event, (e) => callback(e.detail));
|
||||||
|
},
|
||||||
|
dispatch(event: string, data) {
|
||||||
|
document.dispatchEvent(new CustomEvent(event, { detail: data }));
|
||||||
|
},
|
||||||
|
remove(event: string, callback) {
|
||||||
|
document.removeEventListener(event, callback);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default eventBus;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router';
|
import router from './router';
|
||||||
import Vuex from 'vuex'
|
import setupInterceptors from './services/SetupInterceptors';
|
||||||
|
|
||||||
import { IonicVue } from '@ionic/vue';
|
import { IonicVue } from '@ionic/vue';
|
||||||
|
|
||||||
|
|
@ -37,6 +37,8 @@ import './theme/variables.css';
|
||||||
|
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
|
setupInterceptors(store);
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
.use(store)
|
.use(store)
|
||||||
.use(IonicVue)
|
.use(IonicVue)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const instance = axios.create({
|
||||||
|
baseURL: "http://localhost:8080/api",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default instance;
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
import axios from 'axios';
|
import api from './Api';
|
||||||
|
import TokenService from './TokenService';
|
||||||
const API_URL = 'http://localhost:8080/api/auth/';
|
|
||||||
|
|
||||||
class AuthService {
|
class AuthService {
|
||||||
public login(email: string, password: string) {
|
public login(email: string, password: string) {
|
||||||
return axios
|
return api
|
||||||
.post(API_URL + 'login', {
|
.post('/auth/login', {
|
||||||
email,
|
email,
|
||||||
password
|
password
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
if (response.data.accessToken) {
|
if (response.data.accessToken) {
|
||||||
localStorage.setItem('user', JSON.stringify(response.data));
|
TokenService.setUser(response.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|
@ -19,12 +18,11 @@ class AuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public logout() {
|
public logout() {
|
||||||
localStorage.removeItem('user');
|
TokenService.removeUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
public register(username: string, email: string, password: string) {
|
public register(email: string, password: string) {
|
||||||
return axios.post(API_URL + 'register', {
|
return api.post('/auth/register', {
|
||||||
username,
|
|
||||||
email,
|
email,
|
||||||
password
|
password
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
import PitchType from "@/types/PitchType";
|
import PitchType from "@/types/PitchType";
|
||||||
import axios, {AxiosInstance} from "axios";
|
import api from './Api';
|
||||||
|
|
||||||
const apiClient: AxiosInstance = axios.create({
|
|
||||||
baseURL: "http://localhost:8080/api",
|
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
class PitchTypeService {
|
class PitchTypeService {
|
||||||
private static instance: PitchTypeService;
|
private static instance: PitchTypeService;
|
||||||
|
|
@ -22,12 +15,12 @@ class PitchTypeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllPitchTypes(): Promise<PitchType[]> {
|
async getAllPitchTypes(): Promise<PitchType[]> {
|
||||||
const users = await apiClient.get('/pitch_types');
|
const users = await api.get('/pitch_types');
|
||||||
return users.data;
|
return users.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPitchType(id: number): Promise<PitchType> {
|
async getPitchType(id: number): Promise<PitchType> {
|
||||||
const pitchType = await apiClient.get(`/pitch_types/${id}`);
|
const pitchType = await api.get(`/pitch_types/${id}`);
|
||||||
return pitchType.data;
|
return pitchType.data;
|
||||||
// if (pitcher !== undefined) {
|
// if (pitcher !== undefined) {
|
||||||
// return pitcher;
|
// return pitcher;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
import Pitcher from "@/types/Pitcher";
|
import Pitcher from "@/types/Pitcher";
|
||||||
import axios, { AxiosInstance } from "axios";
|
import api from './Api';
|
||||||
|
|
||||||
const apiClient: AxiosInstance = axios.create({
|
|
||||||
baseURL: "http://localhost:8080/api",
|
|
||||||
headers: {
|
|
||||||
"Content-type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
class PitcherService {
|
class PitcherService {
|
||||||
private static instance: PitcherService;
|
private static instance: PitcherService;
|
||||||
|
|
||||||
|
|
@ -21,12 +15,12 @@ class PitcherService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllPitchers(): Promise<Pitcher[]> {
|
async getAllPitchers(): Promise<Pitcher[]> {
|
||||||
const users = await apiClient.get('/users');
|
const users = await api.get('/users');
|
||||||
return users.data;
|
return users.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPitcher(id: number): Promise<Pitcher> {
|
async getPitcher(id: number): Promise<Pitcher> {
|
||||||
const pitcher = await apiClient.get(`/users/${id}`);
|
const pitcher = await api.get(`/users/${id}`);
|
||||||
return pitcher.data;
|
return pitcher.data;
|
||||||
// const pitcher = pitchers.get(id);
|
// const pitcher = pitchers.get(id);
|
||||||
// if (pitcher !== undefined) {
|
// if (pitcher !== undefined) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
import axiosInstance from "./Api";
|
||||||
|
import TokenService from "./TokenService";
|
||||||
|
import { Store } from 'vuex';
|
||||||
|
import {RootState} from '@/store';
|
||||||
|
|
||||||
|
const setup = (store: Store<RootState>) => {
|
||||||
|
axiosInstance.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) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
axiosInstance.interceptors.response.use(
|
||||||
|
(res) => {
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
async (err) => {
|
||||||
|
const originalConfig = err.config;
|
||||||
|
|
||||||
|
if (originalConfig.url !== "/auth/login" && err.response) {
|
||||||
|
// Access Token was expired
|
||||||
|
if (err.response.status === 401 && !originalConfig._retry) {
|
||||||
|
originalConfig._retry = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rs = await axiosInstance.post("/auth/refreshtoken", {
|
||||||
|
refreshToken: TokenService.getLocalRefreshToken(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { accessToken } = rs.data;
|
||||||
|
|
||||||
|
await store.dispatch('auth/refreshToken', accessToken);
|
||||||
|
TokenService.updateLocalAccessToken(accessToken);
|
||||||
|
|
||||||
|
return axiosInstance(originalConfig);
|
||||||
|
} catch (_error) {
|
||||||
|
return Promise.reject(_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default setup;
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import UserInfo from '@/types/UserInfo';
|
||||||
|
|
||||||
|
class TokenService {
|
||||||
|
getLocalRefreshToken() {
|
||||||
|
const user = JSON.parse(localStorage.getItem("user") || '""');
|
||||||
|
return user?.refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLocalAccessToken() {
|
||||||
|
const user = JSON.parse(localStorage.getItem("user")|| '""');
|
||||||
|
return user?.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLocalAccessToken(token: string) {
|
||||||
|
const user: UserInfo = JSON.parse(localStorage.getItem("user")|| '""');
|
||||||
|
user.accessToken = token;
|
||||||
|
localStorage.setItem("user", JSON.stringify(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
getUser() {
|
||||||
|
return JSON.parse(localStorage.getItem("user")|| '""');
|
||||||
|
}
|
||||||
|
|
||||||
|
setUser(user: UserInfo) {
|
||||||
|
console.log(JSON.stringify(user));
|
||||||
|
localStorage.setItem("user", JSON.stringify(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeUser() {
|
||||||
|
localStorage.removeItem("user");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new TokenService();
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
export default interface UserInfo {
|
||||||
|
id: number,
|
||||||
|
email: string,
|
||||||
|
roles: string[],
|
||||||
|
accessToken: string,
|
||||||
|
refreshToken: string
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue