🛂 Auth guard

This commit is contained in:
LittleSheep 2024-08-12 23:51:42 +08:00
parent 6162f8f891
commit 1130e6a574
9 changed files with 33 additions and 38 deletions

View File

@ -20,8 +20,6 @@ onMounted(() => {
theme.global.name.value = event.matches ? "dark" : "light" theme.global.name.value = event.matches ? "dark" : "light"
}) })
if (checkLoggedIn()) {
auth.readProfiles() auth.readProfiles()
}
}) })
</script> </script>

View File

@ -16,7 +16,7 @@
<v-divider class="border-opacity-50 my-2" /> <v-divider class="border-opacity-50 my-2" />
<v-list-item title="Dashboard" prepend-icon="mdi-account-supervisor" exact to="/users/me" /> <v-list-item title="Dashboard" prepend-icon="mdi-account-supervisor" exact to="/users/me" />
<v-list-item title="Sign out" prepend-icon="mdi-logout" @click="signout"></v-list-item> <v-list-item title="Sign out" prepend-icon="mdi-logout" @click="signOut"></v-list-item>
</v-list> </v-list>
</v-menu> </v-menu>
</template> </template>
@ -24,7 +24,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { defaultUserinfo, useUserinfo } from "@/stores/userinfo" import { defaultUserinfo, useUserinfo } from "@/stores/userinfo"
import { computed } from "vue" import { computed } from "vue"
import Cookie from "universal-cookie"
const config = useRuntimeConfig() const config = useRuntimeConfig()
@ -48,11 +47,10 @@ const avatar = computed(() => {
return id.userinfo.data?.avatar ? `${config.public.solarNetworkApi}/cgi/files/attachments/${id.userinfo.data?.avatar}` : void 0 return id.userinfo.data?.avatar ? `${config.public.solarNetworkApi}/cgi/files/attachments/${id.userinfo.data?.avatar}` : void 0
}) })
function signout() { function signOut() {
const ck = new Cookie() useCookie("__hydrogen_atk", { watch: "shallow" }).value = null
ck.remove("__hydrogen_atk") useCookie("__hydrogen_rtk", { watch: "shallow" }).value = null
ck.remove("__hydrogen_rtk")
id.userinfo = defaultUserinfo id.userinfo = defaultUserinfo
window.location.reload() reloadNuxtApp()
} }
</script> </script>

View File

@ -130,7 +130,7 @@ async function readTickets({ page, itemsPerPage }: { page?: number; itemsPerPage
offset: ((pagination.tickets.page - 1) * pagination.tickets.pageSize).toString(), offset: ((pagination.tickets.page - 1) * pagination.tickets.pageSize).toString(),
}), }),
{ {
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { Authorization: `Bearer ${useAtk().value}` },
credentials: "include", credentials: "include",
}, },
) )
@ -156,7 +156,7 @@ async function readEvents({ page, itemsPerPage }: { page?: number; itemsPerPage?
offset: ((pagination.events.page - 1) * pagination.events.pageSize).toString(), offset: ((pagination.events.page - 1) * pagination.events.pageSize).toString(),
}), }),
{ {
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { Authorization: `Bearer ${useAtk().value}` },
credentials: "include", credentials: "include",
}, },
) )
@ -176,7 +176,7 @@ async function killTicket(item: any) {
reverting.sessions = true reverting.sessions = true
const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/users/me/tickets/${item.id}`, { const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/users/me/tickets/${item.id}`, {
method: "DELETE", method: "DELETE",
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { Authorization: `Bearer ${useAtk().value}` },
credentials: "include", credentials: "include",
}) })
if (res.status !== 200) { if (res.status !== 200) {

View File

@ -51,8 +51,6 @@ async function getToken(tk: string) {
error.value = err error.value = err
throw new Error(err) throw new Error(err)
} else { } else {
const out = await res.json()
setTokenSet(out["access_token"], out["refresh_token"])
error.value = null error.value = null
} }
} }

7
middleware/auth.ts Normal file
View File

@ -0,0 +1,7 @@
export default defineNuxtRouteMiddleware((to, from) => {
const state = useLoggedInState();
if (!state.value) {
return navigateTo(`/auth/sign-in?redirect_uri=${to.fullPath}`)
}
})

View File

@ -17,7 +17,6 @@
"@pinia/nuxt": "^0.5.3", "@pinia/nuxt": "^0.5.3",
"nuxt": "^3.12.4", "nuxt": "^3.12.4",
"pinia": "^2.2.1", "pinia": "^2.2.1",
"universal-cookie": "^7.2.0",
"vue": "latest" "vue": "latest"
}, },
"devDependencies": { "devDependencies": {

View File

@ -68,28 +68,26 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from "vue" import { ref } from "vue"
import { useRoute } from "vue-router"
definePageMeta({
middleware: ["auth"],
})
const config = useRuntimeConfig() const config = useRuntimeConfig()
const route = useRoute() const route = useRoute()
const error = ref<string | null>(null) const error = ref<string | null>(null)
const loading = ref(false) const loading = ref(false)
const metadata = ref<any>(null) const metadata = ref<any>(null)
const requestedClaims = computed(() => {
const scope: string = (route.query["scope"] as string) ?? ""
return scope.split(" ")
})
const panel = ref("confirm") const panel = ref("confirm")
async function tryAuthorize() { async function tryAuthorize() {
const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/auth/o/authorize` + window.location.search, { const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/auth/o/authorize` + window.location.search, {
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { Authorization: `Bearer ${useAtk().value}` },
credentials: "include", credentials: "include",
}) })
@ -102,7 +100,6 @@ async function tryAuthorize() {
panel.value = "callback" panel.value = "callback"
callback(data["ticket"]) callback(data["ticket"])
} else { } else {
document.title = `Solarpass | Connect to ${data["client"]?.name}`
metadata.value = data["client"] metadata.value = data["client"]
loading.value = false loading.value = false
} }
@ -123,7 +120,7 @@ async function approve() {
loading.value = true loading.value = true
const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/auth/o/authorize` + window.location.search, { const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/auth/o/authorize` + window.location.search, {
method: "POST", method: "POST",
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { Authorization: `Bearer ${useAtk().value}` },
credentials: "include", credentials: "include",
}) })

View File

@ -43,6 +43,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
definePageMeta({
middleware: ["auth"],
})
const config = useRuntimeConfig() const config = useRuntimeConfig()
const auth = useUserinfo() const auth = useUserinfo()

View File

@ -1,4 +1,3 @@
import Cookie from "universal-cookie"
import { defineStore } from "pinia" import { defineStore } from "pinia"
import { ref } from "vue" import { ref } from "vue"
@ -14,17 +13,12 @@ export const defaultUserinfo: Userinfo = {
data: null, data: null,
} }
export function getAtk(): string { export function useAtk() {
return new Cookie().get("__hydrogen_atk") return useCookie("__hydrogen_atk", { watch: "shallow" })
} }
export function checkLoggedIn(): boolean { export function useLoggedInState() {
return new Cookie().get("__hydrogen_rtk") return computed(() => useAtk().value != null)
}
export function setTokenSet(atk: string, rtk: string) {
new Cookie().set("__hydrogen_atk", atk, { path: "/" })
new Cookie().set("__hydrogen_rtk", rtk, { path: "/" })
} }
export const useUserinfo = defineStore("userinfo", () => { export const useUserinfo = defineStore("userinfo", () => {
@ -32,14 +26,14 @@ export const useUserinfo = defineStore("userinfo", () => {
const isReady = ref(false) const isReady = ref(false)
async function readProfiles() { async function readProfiles() {
if (!checkLoggedIn()) { if (!useLoggedInState().value) {
isReady.value = true isReady.value = true
} }
const config = useRuntimeConfig() const config = useRuntimeConfig()
const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/users/me`, { const res = await fetch(`${config.public.solarNetworkApi}/cgi/auth/users/me`, {
headers: { Authorization: `Bearer ${getAtk()}` }, headers: { Authorization: `Bearer ${useAtk().value}` },
credentials: "include", credentials: "include",
}) })