Files
member-frontend/src/pages/LoginPage.vue

79 lines
2.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="flex items-center justify-center min-h-[70vh]">
<el-card class="w-full max-w-md shadow-md">
<template #header>
<div class="text-center">
<h1 class="text-xl font-bold text-gray-800">member.ose.tw</h1>
<p class="text-sm text-gray-500 mt-1">按下按鈕前往 Keycloak 登入</p>
</div>
</template>
<el-alert
v-if="error"
:title="error"
type="error"
show-icon
:closable="false"
class="mb-4"
/>
<el-button
type="primary"
class="w-full"
:loading="loginLoading"
@click="handleLogin"
>
前往 Keycloak 登入
</el-button>
<div class="mt-4 text-xs text-gray-400 text-center space-y-1">
<p>登入會統一跳轉到 Keycloak 登入頁完成後自動返回</p>
<p>登入成功後 access token 會存於本機 localStorage</p>
</div>
</el-card>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { getOidcAuthorizeUrl } from '@/api/auth'
const route = useRoute()
const loginLoading = ref(false)
const error = ref('')
function getPostLoginRedirect() {
const redirect = route.query.redirect || '/me'
return typeof redirect === 'string' ? redirect : '/me'
}
async function handleLogin() {
loginLoading.value = true
error.value = ''
try {
await redirectToOidc({
prompt: 'login'
})
} catch (err) {
error.value = err.message || '登入失敗,請稍後再試'
} finally {
loginLoading.value = false
}
}
async function redirectToOidc(options = {}) {
sessionStorage.setItem('post_login_redirect', getPostLoginRedirect())
const callbackUrl = `${window.location.origin}/auth/callback`
const res = await getOidcAuthorizeUrl(callbackUrl, options)
const authorizeUrl = res.data.authorize_url
const parsed = new URL(authorizeUrl)
const state = parsed.searchParams.get('state')
if (state) {
sessionStorage.setItem('oidc_expected_state', state)
}
window.location.href = authorizeUrl
}
</script>