Files
chatgpt-ui/plugins/auth.js
2023-03-02 23:10:56 +08:00

138 lines
3.5 KiB
JavaScript

const AUTH_ROUTE = {
home: '/',
login: '/account/signin',
}
const COOKIE_OPTIONS = {
prefix: '_Secure-auth',
path: '/',
tokenName: 'access-token',
refreshTokenName: 'refresh-token',
}
const ENDPOINTS = {
login: {
url: '/api/account/login/'
},
refresh: {
url: '/api/auth/token/refresh'
},
user: {
url: '/api/account/user/'
}
}
export default defineNuxtPlugin(() => {
const tokenKey = COOKIE_OPTIONS.prefix + '.' + COOKIE_OPTIONS.tokenName
const refreshTokenKey = COOKIE_OPTIONS.prefix + '.' + COOKIE_OPTIONS.refreshTokenName
const tokenOptions = {
maxAge: 60 * 5,
}
const refreshTokenOptions = {
maxAge: 60 * 60 * 24,
}
const token = useCookie(tokenKey, tokenOptions)
const refreshToken = useCookie(refreshTokenKey, refreshTokenOptions)
class Auth {
constructor() {
this.loginIn = useState('loginIn', () => false)
this.user = useState('user')
}
async login (username, password) {
const { data, error } = await useFetch(ENDPOINTS.login.url, {
method: 'POST',
body: {
username,
password
}
})
if (!error.value) {
token.value = data.value.access
refreshToken.value = data.value.refresh
return null
}
if (error.value.status === 401) {
return error.value.data.detail
}
return 'Request failed, please try again.'
}
async logout () {
this.loginIn.value = false
this.user.value = null
await this.redirectToLogin()
}
async fetchUser () {
const { data, error } = await useFetch(ENDPOINTS.user.url, {
// withCredentials: true
})
if (!error.value) {
this.user = data.value
this.loginIn.value = true
return null
}
return error
}
async refresh () {
const { data, error } = await useFetch(ENDPOINTS.refresh.url, {
method: 'POST',
body: {
'refresh': refreshToken.value
}
})
if (!error.value) {
token.value = data.value.access
return data.value.access
}
return null
}
async callback () {
return await navigateTo(AUTH_ROUTE.home)
}
async redirectToLogin () {
return await navigateTo(AUTH_ROUTE.login)
}
async retrieveToken () {
const token = useCookie(tokenKey, tokenOptions)
const refreshToken = useCookie(refreshTokenKey, refreshTokenOptions)
if (!refreshToken.value) {
return null
}
if (!token.value) {
return await this.refresh()
}
return token.value
}
}
const auth = new Auth()
addRouteMiddleware('auth', async (to, from) => {
if (!auth.loginIn.value) {
// const token = await auth.retrieveToken()
// if (!token) {
// return await auth.redirectToLogin()
// }
const error = await auth.fetchUser()
if (error) {
return await auth.redirectToLogin()
}
}
})
return {
provide: {
auth
}
}
})