mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-07-16 09:38:49 +02:00
141 lines
3.7 KiB
Vue
141 lines
3.7 KiB
Vue
<template>
|
|
<div id="app">
|
|
<h1>OAuth2 Authentication with Vue 3</h1>
|
|
<p>Public Content: {{ publicContent }}</p>
|
|
|
|
<div v-if="authenticated">
|
|
<h2>Private Content</h2>
|
|
<p>{{ privateContent }}</p>
|
|
<button @click="logout">Logout</button>
|
|
</div>
|
|
<div v-else>
|
|
<p>Please log in to see the private content.</p>
|
|
<ul>
|
|
<li v-for="provider in authProviders" :key="provider.name">
|
|
<a :href="provider.authURL + redirectUri" @click="storeProvider(provider)">
|
|
Login with {{ provider.name }}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import {ref, onMounted, Ref} from 'vue';
|
|
import PocketBase, {AuthProviderInfo} from 'pocketbase';
|
|
|
|
// Reactive state variables
|
|
const authenticated = ref(false);
|
|
const publicContent = ref('');
|
|
const privateContent = ref('');
|
|
const accessToken = ref<string | null>(null);
|
|
const authProviders: Ref<AuthProviderInfo[]> = ref([]); // Array for OAuth2 providers
|
|
|
|
// PocketBase instance and redirect URI
|
|
const pb = new PocketBase('http://127.0.0.1:8090');
|
|
const redirectUri = 'http://localhost:8000/callback';
|
|
|
|
// Load OAuth2 providers
|
|
const loadLinks = async () => {
|
|
try {
|
|
const authMethods = await pb.collection('users').listAuthMethods();
|
|
authProviders.value = authMethods.oauth2.providers || [];
|
|
} catch (error) {
|
|
console.error('Error loading OAuth2 providers:', error);
|
|
}
|
|
};
|
|
|
|
// Store provider data in localStorage for later use
|
|
const storeProvider = (provider: AuthProviderInfo) => {
|
|
localStorage.setItem('provider', JSON.stringify(provider));
|
|
};
|
|
|
|
// Fetch public content
|
|
const fetchPublicContent = async () => {
|
|
try {
|
|
const response = await fetch('http://localhost:8081/public');
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch public content');
|
|
}
|
|
publicContent.value = await response.text();
|
|
} catch (error) {
|
|
console.error('Error fetching public content:', error);
|
|
}
|
|
};
|
|
|
|
// Fetch private content
|
|
const fetchPrivateContent = async () => {
|
|
if (accessToken.value) {
|
|
try {
|
|
const response = await fetch('http://localhost:8081/private', {
|
|
headers: {
|
|
Authorization: `Bearer ${accessToken.value}`,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch private content');
|
|
}
|
|
privateContent.value = await response.text();
|
|
} catch (error) {
|
|
console.error('Error fetching private content:', error);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Handle OAuth2 callback
|
|
const handleCallback = async () => {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const code = urlParams.get('code');
|
|
const state = urlParams.get('state');
|
|
|
|
if (code && state) {
|
|
try {
|
|
// Exchange authorization code for access token
|
|
const provider = JSON.parse(localStorage.getItem('provider') || '{}');
|
|
const authData = await pb.collection('users').authWithOAuth2(
|
|
provider.name,
|
|
code,
|
|
state,
|
|
redirectUri
|
|
);
|
|
|
|
accessToken.value = authData.token;
|
|
authenticated.value = true;
|
|
|
|
// Fetch private content after successful login
|
|
fetchPrivateContent();
|
|
} catch (error) {
|
|
console.error('Error handling OAuth2 callback:', error);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Logout function
|
|
const logout = () => {
|
|
authenticated.value = false;
|
|
accessToken.value = null;
|
|
window.location.href = '/';
|
|
};
|
|
|
|
// Lifecycle hook
|
|
onMounted(() => {
|
|
fetchPublicContent();
|
|
loadLinks();
|
|
|
|
// Check for OAuth2 callback
|
|
if (window.location.pathname === '/callback') {
|
|
handleCallback();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
#app {
|
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
text-align: center;
|
|
color: #2c3e50;
|
|
}
|
|
</style>
|