最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

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 by:

  1. composable - A composable to store the User data
  2. server middleware - Parsing the JWT in a server middleware and storing user data in the event context object
  3. server plugin - Leveraging a server plugin to get the user data from the context object and storing it using useState.
  4. 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.

发布评论

评论列表(0)

  1. 暂无评论