Skip to content

Commit

Permalink
fix(token): fix token error from nuxt-oidc-auth in k8s
Browse files Browse the repository at this point in the history
  • Loading branch information
brucetony committed Aug 13, 2024
1 parent 047d4f7 commit e56fae9
Show file tree
Hide file tree
Showing 28 changed files with 200 additions and 346 deletions.
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules
.nuxt
.env.backup
.env
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ tsconfig.tsbuildinfo
tsconfig.build.tsbuildinfo

# local env files
.env.backup
.env
.env.*.local
.env.production
.env
.env.backup

# Logs
/logs
Expand Down
17 changes: 14 additions & 3 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@
NUXT_PUBLIC_BASE_URL="http://localhost:3000" # URL of the website
NUXT_PUBLIC_HUB_ADAPTER_URL="http://urlForHubAdapterApi.de" # URL for hub adapter API
NUXT_KEYCLOAK_BASE_URL="http://your.keycloak.instance.de/realms/flame" # Keycloak endpoint and realm
NUXT_KEYCLOAK_CLIENT_ID="node-ui"
NUXT_KEYCLOAK_CLIENT_SECRET="someSecret"
NUXT_OIDC_PROVIDERS_KEYCLOAK_BASE_URL="http://your.keycloak.instance.de/realms/flame"
NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_ID="node-ui"
NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET="someSecret"
# Nuxt OIDC Tokens
# https://nuxt.com/modules/nuxt-oidc-auth#_3-set-secrets
# NOTE: These will automatically be generated in helm/docker so they do not need to be explicitly set
# NUXT_OIDC_TOKEN_KEY is a cryptographic AES key in base64 used to encrypt the server side token store
NUXT_OIDC_TOKEN_KEY=xxx
# NUXT_OIDC_SESSION_SECRET is a 48 character random string that encrypts the user session
NUXT_OIDC_SESSION_SECRET=xxx
# NUXT_OIDC_AUTH_SESSION_SECRET is a 48 character random string that encrypts individual sessions during OAuth flows
NUXT_OIDC_AUTH_SESSION_SECRET=xxx
```
19 changes: 5 additions & 14 deletions components/KeycloakAuth.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
<script setup lang="ts">
import { useAuth } from "~/stores/auth";
import { useServices } from "~/composables/useServices";
const authStore = useAuth();
const services = useServices();
const user = authStore.user;
const signIn = () => services.$auth.signInRedirect();
const signOut = () => services.$auth.logout();
const { loggedIn, user, login, logout } = useOidcAuth();
</script>

<template>
<div class="keycloakLoginButton">
<div v-if="user">
<h3>Welcome {{ user.profile.name }}!</h3>
<Button @click="signOut" severity="warning" outlined>Logout</Button>
<div v-if="loggedIn">
<h3>Welcome {{ user.providerInfo.preferred_username }}!</h3>
<Button @click="logout()" severity="warning" outlined>Logout</Button>
</div>
<div v-else>
<Button @click="signIn" severity="success" outlined
<Button @click="login()" severity="success" outlined
>Login with Keycloak</Button
>
</div>
Expand Down
19 changes: 9 additions & 10 deletions components/MenuHeader.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<script setup lang="ts">
import { ref } from "vue";
import AvatarButton from "~/components/login/AvatarButton.vue";
const services = useServices();
const user = ref();
onMounted(async () => {
user.value = await services.$auth.getUser();
});
const { loggedIn } = useOidcAuth();
const items = ref([
{
label: "Home",
icon: "pi pi-home",
route: "/",
},
{
label: "Test",
icon: "pi pi-at",
route: "/test",
},
{
label: "Projects",
icon: "pi pi-objects-column",
Expand Down Expand Up @@ -71,7 +70,7 @@ const items = ref([
:href="href"
v-bind="props.action"
@click="navigate"
:class="!user && item.label != 'Home' ? 'p-disabled' : ''"
:class="!loggedIn && item.label != 'Home' ? 'p-disabled' : ''"
>
<span :class="item.icon" />
<span class="ml-2">{{ item.label }}</span>
Expand All @@ -83,7 +82,7 @@ const items = ref([
:href="item.url"
:target="item.target"
v-bind="props.action"
:class="!user && item.label != 'Home' ? 'p-disabled' : ''"
:class="!loggedIn && item.label != 'Home' ? 'p-disabled' : ''"
>
<span :class="item.icon" />
<span class="ml-2">{{ item.label }}</span>
Expand Down
2 changes: 1 addition & 1 deletion components/data-stores/managers/DataStoreCreator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import InputNumber from "primevue/inputnumber";
const name = ref("");
const host = ref("");
const path = ref("");
const port = ref(443);
const port = ref(80);
const protocol = ref("http");
const loading = ref(false);
Expand Down
20 changes: 6 additions & 14 deletions components/login/AvatarButton.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script setup lang="ts">
import { useServices } from "~/composables/useServices";
const services = useServices();
import { ref } from "vue";
const { loggedIn, logout, login, user } = useOidcAuth();
const menu = ref();
const loggedOutUserMenuItems = ref([
Expand All @@ -12,7 +11,7 @@ const loggedOutUserMenuItems = ref([
label: "Login",
icon: "pi pi-sign-in",
command: () => {
services.$auth.signInRedirect();
login();
},
},
],
Expand All @@ -26,29 +25,22 @@ const loggedInUserMenuItems = ref([
label: "Logout",
icon: "pi pi-sign-out",
command: () => {
services.$auth.logout();
logout();
},
},
],
},
]);
const user = ref();
onMounted(async () => {
user.value = await services.$auth.getUser();
});
const toggle = (event) => {
menu.value.toggle(event);
};
</script>

<template>
<div v-if="user" class="authAvatarSection">
<div v-if="loggedIn" class="authAvatarSection">
<div class="usernameMenuBar">
<p>
{{ user.profile.name }}
{{ user.providerInfo.preferred_username }}
</p>
</div>
<Button
Expand Down
44 changes: 7 additions & 37 deletions composables/useAPIFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,17 @@ import type {
ListServices,
Service,
} from "~/services/Api";
import { useServices } from "~/composables/useServices";

export const useAPIFetch: typeof useFetch = (request, options?) => {
const config = useRuntimeConfig();
const nuxtApp = useNuxtApp();
const baseUrl = config.public.hubAdapterUrl as string;

const services = useServices();

const token = services.$application.getToken();
import type { UseFetchOptions } from "#app";

export function useAPIFetch<T>(
request: string | (() => string),
options: UseFetchOptions<T> = {},
) {
return useFetch(request, {
baseURL: baseUrl,
onRequest({ options }) {
// Annoying workaround to avoid typescript from complaining - cast to Headers then set explicitly
const headers = options.headers
? new Headers(options.headers)
: new Headers();
headers.set("Authorization", `Bearer ${token}`);
options.headers = headers;
},
onRequestError({ request, options, error }) {
console.log(request);
console.log(options);
console.log(error);
},
onResponse({ response }) {
// Process the response data
localStorage.setItem("token", response._data.token);
},
onResponseError({ response }) {
// Handle the response errors
console.log(response);
if (response.status === 401 || response.status === 403) {
console.log("User signed out, routing to login");
nuxtApp.runWithContext(() => navigateTo("/"));
}
},
...options,
$fetch: useNuxtApp().$hubApi,
});
};
}

// Hub endpoints
export function approveRejectProjectProposal(
Expand Down
12 changes: 0 additions & 12 deletions composables/useServices.ts

This file was deleted.

21 changes: 11 additions & 10 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ services:
environment:
NODE_ENV: "development"
# The "NUXT_" prefix overrides the env variable set during build time (for prod only)
NUXT_BASE_URL: "http://localhost:3000" # URL of the website
NUXT_HUB_ADAPTER_URL: "http://localhost:5000"
NUXT_KEYCLOAK_BASE_URL: "http://localhost:8080/realms/flame"
NUXT_KEYCLOAK_CLIENT_ID: "node-ui"
NUXT_KEYCLOAK_CLIENT_SECRET: "xxx"
NUXT_PUBLIC_BASE_URL: "http://localhost:3000" # URL of the website
NUXT_PUBLIC_HUB_ADAPTER_URL: "http://localhost:5000"
NUXT_OIDC_PROVIDERS_KEYCLOAK_BASE_URL: "http://localhost:8080/realms/flame"
NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_ID: "node-ui"
NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET: "xxx"
ports:
- '3000:3000'
restart: always
Expand All @@ -32,11 +32,12 @@ services:
# environment:
# NODE_ENV: "production"
# # The "NUXT_" prefix overrides the env variable set during build time (for prod only)
# NUXT_BASE_URL: "http://localhost:3000" # URL of the website
# NUXT_HUB_ADAPTER_URL: "http://localhost:8081"
# NUXT_KEYCLOAK_BASE_URL: "http://some.keycloak.com/realms/flame"
# NUXT_KEYCLOAK_CLIENT_ID: "node-ui"
# NUXT_KEYCLOAK_CLIENT_SECRET: ""
# NUXT_PUBLIC_BASE_URL: "http://localhost:3000" # URL of the website
# NUXT_PUBLIC_HUB_ADAPTER_URL: "http://localhost:8081"
# NUXT_OIDC_PROVIDERS_KEYCLOAK_BASE_URL: "http://some.keycloak.com/realms/flame"
# NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_ID: "node-ui"
# NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET: ""
# NUXT_OIDC_PROVIDERS_KEYCLOAK_REDIRECT_URI: "http://localhost:3000/auth/keycloak/callback"
## ports:
## - '3000:3000'
# restart: always
Expand Down
23 changes: 0 additions & 23 deletions middleware/auth.global.ts

This file was deleted.

7 changes: 7 additions & 0 deletions middleware/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default defineNuxtRouteMiddleware(async (to) => {
const { loggedIn, login } = useOidcAuth();
if (!loggedIn.value && to.path !== "/") {
console.warn("Not logged in");
return login();
}
});
46 changes: 38 additions & 8 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,61 @@
import { defineNuxtConfig } from "nuxt/config";

export default defineNuxtConfig({
ssr: false,
ssr: true,
devtools: { enabled: false },
modules: ["nuxt-primevue", "@pinia/nuxt"],
modules: ["nuxt-primevue", "nuxt-oidc-auth"],

runtimeConfig: {
public: {
baseUrl: process.env.NUXT_BASE_URL || "http://localhost:3000",
baseUrl: process.env.NUXT_PUBLIC_BASE_URL || "http://localhost:3000",
hubAdapterUrl:
process.env.NUXT_HUB_ADAPTER_URL || "http://localhost:5000",
keycloakUrl: process.env.NUXT_KEYCLOAK_BASE_URL as string,
keycloakClientId: process.env.NUXT_KEYCLOAK_CLIENT_ID,
keycloakClientSecret: process.env.NUXT_KEYCLOAK_CLIENT_SECRET,
process.env.NUXT_PUBLIC_HUB_ADAPTER_URL || "http://localhost:5000",
},
},

primevue: {
options: {
ripple: true,
},

directives: {
include: ["Ripple", "Tooltip", "Toast"],
},
},

oidc: {
defaultProvider: "keycloak",
providers: {
keycloak: {
clientId:
process.env.NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_ID || "node-ui",
clientSecret: process.env
.NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET as string,
redirectUri:
process.env.NUXT_PUBLIC_BASE_URL + "/auth/keycloak/callback",
exposeAccessToken: true,
// The auth is different since that is accessed via a frontend client
authorizationUrl:
process.env.KEYCLOAK_LOGIN_URL + "/protocol/openid-connect/auth",
tokenUrl:
process.env.KEYCLOAK_SERVICE_URL + "/protocol/openid-connect/token",
userinfoUrl:
process.env.KEYCLOAK_SERVICE_URL +
"/protocol/openid-connect/userinfo",
logoutUrl:
process.env.KEYCLOAK_SERVICE_URL + "/protocol/openid-connect/auth",
},
},
session: {
expirationCheck: false,
automaticRefresh: true,
maxAge: 3600,
},
middleware: {
globalMiddlewareEnabled: false,
customLoginPage: false,
},
},

css: [
"primevue/resources/themes/lara-dark-amber/theme.css",
"primeicons/primeicons.css",
Expand Down
Loading

0 comments on commit e56fae9

Please sign in to comment.