Denoder / nuxt-module-alternatives

Alternative modules to use while waiting for Nuxt 3 Compatibility
MIT License
144 stars 14 forks source link

No automatic redirect after login + null values for $auth.user on server (SSR) #114

Closed Arecsu closed 1 year ago

Arecsu commented 2 years ago

Environment


Reproduction

nuxt.config.ts

 auth: {
    globalMiddleware: false,
    enableMiddleware: true,
    redirect: {
       login: '/login',
       logout: '/login',
       callback: '/login',
       home: '/'
    },
    strategies: {
       local: {
          token: {
             property: 'access_token',
             // global: true,
             // required: true,
             type: 'Bearer'
          },
          user: {
             property: 'content.username',
             autoFetch: true
          },
          endpoints: {
             login: { url: '/api/user/login', method: 'post'},
             user: { url: '/api/user/me', method: 'get' },
             logout: false,
          }
       }
    }
 },
 proxy: {
    enableProxy: true,
    proxies: {
       '/api': {
          target: 'http://localhost:1234',
          changeOrigin: true,
       },

    },
 },

middleware/auth.global.js

export default defineNuxtRouteMiddleware(async (to) => {

   const { $auth } = useNuxtApp()
   const loggedIn = $auth.loggedIn;
   console.log(loggedIn)
}

pages/login/index.vue

<script setup>
const { $auth } = useNuxtApp()

const login = () => { 
   $auth.loginWith('local', { body: 
      {
         username: 'admin',
         password: 'password'
      }
   })
}

</script>

<template>
   <div>
      <button @click="login">login</button>
   </div>
</template>

No redirect after successful login

Login goes well on the backend JWT server. But no intention of redirect at all. Happens with globalMiddleware and enableMiddleware.

I think I found a hint of the problem: while trying to debug the 2nd problem, I wrote console.log($auth) inside the same middleware file above. No visible problem in the client/browser console. But in the server, there's an error:

/* ^^^^^^^^^ */
    options: {
      globalMiddleware: false,
      enableMiddleware: true,
      resetOnError: false,
      ignoreExceptions: false,
      scopeKey: 'scope',
      rewriteRedirects: true,
      fullPathRedirect: false,
      watchLoggedIn: true,
      redirect: [Object],
      pinia: [Object],
      cookie: [Object],
      localStorage: [Object],
      sessionStorage: [Object],
      defaultStrategy: 'local',
      initialState: [Object]
    },
    state: { user: null, loggedIn: false, strategy: 'local' }
  },
  '$state': { user: null, loggedIn: false, strategy: 'local' },
  error: FetchError: Headers.append: "append(name, value) {
          if (!(this instanceof Headers)) {
            throw new TypeError("Illegal invocation");
          }
          if (arguments.length < 2) {
            throw new TypeError(`Failed to execute 'append' on 'Headers': 2 arguments required, but only ${arguments.length} present.`);
          }
          name = webidl.converters.ByteString(name);
          value = webidl.converters.ByteString(value);
          value = headerValueNormalize(value);
          if (!isValidHeaderName(name)) {
            webidl.errors.invalidArgument({
              prefix: "Headers.append",
              value: name,
              type: "header name"
            });
          } else if (!isValidHeaderValue(value)) {
            webidl.errors.invalidArgument({
              prefix: "Headers.append",
              value,
              type: "header value"
            });
          }
          if (this[kGuard] === "immutable") {
            throw new TypeError("immutable");
          } else if (this[kGuard] === "request-no-cors") {
          }
          return this[kHeadersList].append(name, value);
        }" is an invalid header value. ()
      at async $fetchRaw2 (file:///web/node_modules/ohmyfetch/dist/shared/ohmyfetch.d1948a88.mjs:144:20)
      at async Auth.init (/web/node_modules/@nuxtjs-alt/auth/dist/runtime/core/auth.mjs:70:7)
      at async Object.callAsync (file:///web/node_modules/unctx/dist/index.mjs:53:16)
      at async applyPlugin (/web/node_modules/nuxt/dist/app/nuxt.mjs:94:23)
      at async Module.applyPlugins (/web/node_modules/nuxt/dist/app/nuxt.mjs:104:5)
      at async createNuxtAppServer (/web/node_modules/nuxt/dist/app/entry.mjs:30:7)
      at async default (file:///web/node_modules/@nuxt/vite-builder/dist/runtime/vite-node.mjs:27:18)
      at async Object.renderToString (file:///web/node_modules/vue-bundle-renderer/dist/runtime.mjs:172:19)
      at async file:///web/.nuxt/dev/index.mjs:704:21
      at async file:///web/.nuxt/dev/index.mjs:109:22

The line 70 of auth/dist/runtime/core/auth.mjs the error log mentions:

 try {
    await this.mounted();
  } catch (error) {
    this.callOnError(error);
  } finally {
    if (process.client && this.options.watchLoggedIn) {
      this.$storage.watchState("loggedIn", (loggedIn) => {   // <----------  line 70
        if (Object.prototype.hasOwnProperty.call(useRoute().meta, "auth") && !routeMeta("auth", false)) {
          this.redirect(loggedIn ? "home" : "logout");    /// <---------- there is a redirect here
        }
      });
    }
  }

I can do this to handle redirect, but it's just a workaround to a serious problem, or at least that's what it seems.

$auth.loginWith('local', { body: ... }).then(() => navigateTo('/'))

Null values for $auth.user on server (SSR)

I've tried a lot of things. Proxy is configured right AFAIK. I don't know how to get the state of each user in the middleware and handle my custom protected routes in the server from there. It's always null, while in the client/browser returns the user. Same for $auth.loggedIn.

The backend receives every request correctly from the client/browser. The console log in the server shows the proxy working for those client/browser calls: /api/user/me -> http://127.0.0.1:1234

Can it be that the error mentioned above in the first problem is making this value to be null?

Maybe I'm calling some functions or config the wrong way. Super appreciated your help. And thank you so much for making these modules compatible with Nuxt 3! Great work

Denoder commented 2 years ago

update to auth 2.1.1

Arecsu commented 2 years ago

Wow, that was really fast. Now the server gets the current user from the client :) awesome! Second problem is fixed. No errors in console.log($auth). It still doesn't redirect automatically for some reason, but I can manage to use the workaround. Thank you so much

steklopod commented 2 years ago

I think these changes broke other functionallity: https://github.com/Teranode/nuxt-module-alternatives/issues/116

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.