Using Nuxt 3. Currently I can parse a JWT in the server middleware to get the logged in user, but I want to save that logged in user info to a global variable. Then, on the client side I want to get that logged in user.
In the environment where my Nuxt web app will be hosted, authentication happens at the infrastructure level (K8s), so I don't really need to implement OAuth mechanisms. I just need to parse the JWT from the request header.
I've been reading into the Nuxt context but I'm still confused about how to actually implement it. Do you recommend this approach, or something else like an auth library?
Using Nuxt 3. Currently I can parse a JWT in the server middleware to get the logged in user, but I want to save that logged in user info to a global variable. Then, on the client side I want to get that logged in user.
In the environment where my Nuxt web app will be hosted, authentication happens at the infrastructure level (K8s), so I don't really need to implement OAuth mechanisms. I just need to parse the JWT from the request header.
I've been reading into the Nuxt context but I'm still confused about how to actually implement it. Do you recommend this approach, or something else like an auth library?
Share Improve this question asked Feb 4 at 0:51 Pablo SettecasePablo Settecase 235 bronze badges2 Answers
Reset to default 1I think the best approach for your use case is to use a composable to manage the user state in conjunction with a server plugin. Here's an example:
composables/useAuth.ts
interface User {
// define the shape you expect from the token
sub: string
email?: string
}
export const useAuth = () => {
// Create a global state named 'user'.
// Nuxt automatically serializes this state from SSR to client.
return useState<User | null>('user', () => null)
}
And then have a plugin that runs on server to read the token from Authorization header and fill the user state in the store, like below:
plugins/auth.server.ts
import { parse } from 'some-jwt-library'
import { getHeader } from 'h3' // <-- make sure to import from h3
export default defineNuxtPlugin((nuxtApp) => {
const event = useRequestEvent()
const token = getHeader(event, 'Authorization')
if (!token) return
const user = useState('user', () => null)
// parse token...
user.value = parse(token)
})
and then in your .vue files you can use it like this:
app.vue
<script setup lang="ts">
import {useAuth} from "~/composables/useAuth";
const user = useAuth()
</script>
<template>
<div>
Hello: {{ user }}
</div>
</template>
I solved this by:
- composable - A composable to store the User data
- server middleware - Parsing the JWT in a server middleware and storing user data in the event context object
- server plugin - Leveraging a server plugin to get the user data from the context object and storing it using useState.
- template - Getting the user using useState.
composables/useAuth.ts
interface User {
// define the shape you expect from the token
sub: string
email?: string
}
export const useAuth = () => {
// Create a global state named 'user'.
// Nuxt automatically serializes this state from SSR to client.
return useState<User | null>('user', () => null)
}
server/middleware/auth.ts
import { jwtDecode } from "jwt-decode";
export default defineEventHandler((event) => {
const headers = getRequestHeaders(event)
const token = headers[config.awsHeaderName]
event.context.user = jwtDecode(token);
})
plugins/auth.server.ts
export default defineNuxtPlugin((nuxtApp) => {
const event = useRequestEvent()
const u = event?.context.user
const y = 1
if (!u) return
const user = useState('user', () => null)
user.value = u
})
app.vue
<script setup lang="ts">
import {useAuth} from "~/composables/useAuth";
const user = useAuth()
</script>
<template>
<div>
Hello: {{ user }}
</div>
</template>
This works for me for now. I know there is more I can do, such as create a session using an auth library.
Credit to @fernando-del-cantão on helping me figure this out.