create authAxios and normalAxios instance
This commit is contained in:
parent
3a3f427daa
commit
375e1ab4e5
@ -1,6 +1,22 @@
|
|||||||
import axios from '@/utils/axios'
|
import { authAxios, normalAxios } from '@/utils/axios'
|
||||||
import { EmailSendDto, EmailSendResponse } from './email.interface'
|
import {
|
||||||
|
EmailSendDto,
|
||||||
|
EmailSendResponse,
|
||||||
|
EmailVerifyCodeScene,
|
||||||
|
} from './email.interface'
|
||||||
|
|
||||||
export async function sendEmailVerifyCode(params: EmailSendDto) {
|
export async function sendEmailVerifyCode(params: EmailSendDto) {
|
||||||
return axios.get<EmailSendResponse>('/api/email/verifyCode', { params })
|
if (
|
||||||
|
[
|
||||||
|
EmailVerifyCodeScene.register,
|
||||||
|
EmailVerifyCodeScene.forgetPassword,
|
||||||
|
].includes(params.scene)
|
||||||
|
) {
|
||||||
|
return normalAxios.get<EmailSendResponse>('/api/email/verifyCode', {
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return authAxios.get<EmailSendResponse>('/api/email/verifyCode', {
|
||||||
|
params,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import axios from '@/utils/axios'
|
import { authAxios, normalAxios } from '@/utils/axios'
|
||||||
import { type AxiosResponse } from 'axios'
|
|
||||||
import {
|
import {
|
||||||
LoginInputDto,
|
LoginInputDto,
|
||||||
RegisterInputDto,
|
RegisterInputDto,
|
||||||
@ -10,35 +9,25 @@ import {
|
|||||||
} from './user.interface'
|
} from './user.interface'
|
||||||
|
|
||||||
export async function register(data: RegisterInputDto) {
|
export async function register(data: RegisterInputDto) {
|
||||||
return axios.post<AccessToken>('/api/users', data)
|
return normalAxios.post<AccessToken>('/api/users', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function login(data: LoginInputDto) {
|
export async function login(data: LoginInputDto) {
|
||||||
return axios.post<AccessToken>('/api/users/token', data)
|
return normalAxios.post<AccessToken>('/api/users/token', data)
|
||||||
}
|
|
||||||
|
|
||||||
export async function logout() {
|
|
||||||
return axios.delete('/api/users/me/token')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function forgetPassword(data: ForgetPasswordInputDto) {
|
export async function forgetPassword(data: ForgetPasswordInputDto) {
|
||||||
return axios.patch<AccessToken>('/api/users/password', data)
|
return normalAxios.patch<AccessToken>('/api/users/password', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function logout() {
|
||||||
|
return authAxios.delete('/api/users/me/token')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUser(data: DeleteUser) {
|
export async function deleteUser(data: DeleteUser) {
|
||||||
return axios.delete('/api/users/me', { data })
|
return authAxios.delete('/api/users/me', { data })
|
||||||
}
|
|
||||||
|
|
||||||
let refreshing: Promise<AxiosResponse<AccessToken>> | null
|
|
||||||
export async function refreshToken() {
|
|
||||||
if (!refreshing) {
|
|
||||||
refreshing = axios.put<AccessToken>('/api/users/me/token').finally(() => {
|
|
||||||
refreshing = null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return refreshing
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUserInfo() {
|
export async function getUserInfo() {
|
||||||
return axios.get<User>('/api/users/me')
|
return authAxios.get<User>('/api/users/me')
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
import axios, { type AxiosError } from 'axios'
|
|
||||||
import Router from 'next/router'
|
|
||||||
import status from 'http-status'
|
|
||||||
import * as api from '@/api'
|
|
||||||
import { toast } from 'react-toastify'
|
|
||||||
|
|
||||||
interface ErrorResponse {
|
|
||||||
statusCode: number
|
|
||||||
message: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const throwError = (error: AxiosError<ErrorResponse>) => {
|
|
||||||
toast.error(
|
|
||||||
error.response?.data.message.toString() ?? error.response?.statusText,
|
|
||||||
)
|
|
||||||
return Promise.reject(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
axios.interceptors.request.use(function (config) {
|
|
||||||
const accessToken = localStorage.getItem('accessToken')
|
|
||||||
config.headers.Authorization = `Bearer ${accessToken}`
|
|
||||||
return config
|
|
||||||
})
|
|
||||||
|
|
||||||
axios.interceptors.response.use(
|
|
||||||
function (response) {
|
|
||||||
return response
|
|
||||||
},
|
|
||||||
async function (error: AxiosError<ErrorResponse>) {
|
|
||||||
// fail to refresh token
|
|
||||||
if (
|
|
||||||
error.config &&
|
|
||||||
error.config.url === '/api/users/me/token' &&
|
|
||||||
error.config.method === 'put'
|
|
||||||
) {
|
|
||||||
Router.push('/login')
|
|
||||||
return throwError(error)
|
|
||||||
}
|
|
||||||
switch (error.response?.status) {
|
|
||||||
case status.UNAUTHORIZED: {
|
|
||||||
if (error.config?.url === '/api/users/token') {
|
|
||||||
throw throwError(error)
|
|
||||||
}
|
|
||||||
const res = await api.user.refreshToken()
|
|
||||||
localStorage.setItem('accessToken', res.data)
|
|
||||||
return error.config && axios.request(error.config)
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return throwError(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
export default axios
|
|
53
src/utils/axios/authAxios.ts
Normal file
53
src/utils/axios/authAxios.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import axios, { AxiosError, type AxiosResponse } from 'axios'
|
||||||
|
import Router from 'next/router'
|
||||||
|
import status from 'http-status'
|
||||||
|
import { AccessToken } from '@/api/user.interface'
|
||||||
|
import { throwError, ErrorResponse } from './throwError'
|
||||||
|
import normalAxios from './normalAxios'
|
||||||
|
|
||||||
|
/** 需要Authorization的axios */
|
||||||
|
const authAxios = axios.create()
|
||||||
|
|
||||||
|
authAxios.interceptors.request.use(function (config) {
|
||||||
|
const accessToken = localStorage.getItem('accessToken')
|
||||||
|
config.headers.Authorization = `Bearer ${accessToken}`
|
||||||
|
return config
|
||||||
|
})
|
||||||
|
|
||||||
|
authAxios.interceptors.response.use(
|
||||||
|
(response) => response,
|
||||||
|
async (error: AxiosError<ErrorResponse>) => {
|
||||||
|
switch (error.response?.status) {
|
||||||
|
case status.UNAUTHORIZED: {
|
||||||
|
const res = await refreshToken()
|
||||||
|
localStorage.setItem('accessToken', res.data)
|
||||||
|
return error.config && axios.request(error.config)
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return throwError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const refreshToken = (() => {
|
||||||
|
let refreshingToken: Promise<AxiosResponse<AccessToken>> | null = null
|
||||||
|
return async function () {
|
||||||
|
if (!refreshingToken) {
|
||||||
|
refreshingToken = normalAxios
|
||||||
|
.put<AccessToken>('/api/users/me/token')
|
||||||
|
.finally(() => {
|
||||||
|
refreshingToken = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
refreshingToken?.catch((error) => {
|
||||||
|
if (error instanceof AxiosError) {
|
||||||
|
Router.push('/login')
|
||||||
|
throwError(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return refreshingToken
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
export default authAxios
|
4
src/utils/axios/index.ts
Normal file
4
src/utils/axios/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import authAxios from './authAxios'
|
||||||
|
import normalAxios from './normalAxios'
|
||||||
|
|
||||||
|
export { authAxios, normalAxios }
|
17
src/utils/axios/normalAxios.ts
Normal file
17
src/utils/axios/normalAxios.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import axios, { AxiosError } from 'axios'
|
||||||
|
import { throwError, ErrorResponse } from './throwError'
|
||||||
|
|
||||||
|
const normalAxios = axios.create()
|
||||||
|
|
||||||
|
normalAxios.interceptors.response.use(
|
||||||
|
(response) => response,
|
||||||
|
async (error: AxiosError<ErrorResponse>) => {
|
||||||
|
switch (error.response?.status) {
|
||||||
|
default: {
|
||||||
|
return throwError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export default normalAxios
|
14
src/utils/axios/throwError.ts
Normal file
14
src/utils/axios/throwError.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { AxiosError } from 'axios'
|
||||||
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
|
export interface ErrorResponse {
|
||||||
|
statusCode: number
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const throwError = (error: AxiosError<ErrorResponse>) => {
|
||||||
|
toast.error(
|
||||||
|
error.response?.data.message.toString() ?? error.response?.statusText,
|
||||||
|
)
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user