authentication - How to store global user object in Nuxt3 server middleware? - Stack Overflow

admin2025-04-16  4

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 badges
Add a comment  | 

2 Answers 2

Reset to default 1

I 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 using @fernando-del-cantão suggestion:

  1. composable - store the User State
  2. server plugin - get the user data state, or if it doesn't exist, parse the JWT and then store the User State.
  3. template - Get the user using the composable from #1.

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

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)
})

app.vue

<script setup lang="ts">
import {useAuth} from "~/composables/useAuth";
const user = useAuth()
</script>

<template>
  <div>
    Hello: {{  user }}
  </div>
</template>

This works 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.

转载请注明原文地址:http://www.anycun.com/QandA/1744743776a86992.html