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

nuxt.js - oAuth provider is not triggered in a Nuxt authenticated app - Stack Overflow

programmeradmin2浏览0评论

I am building a simple application based on Nuxt (3.16) and @sidebase/nuxt-auth and I've been trying for now two days to get through that. I am a beginner in Nuxt but I have been developing for a long time for fun (and to learn).

I tried to use ChatGPT to give me some insights but we've been running in loops for some time. You can see one of the sessions at (this is just for reference).

My problem: when accessing the http://localhost:3000/api/auth/signin endpoint, I get a gray screen with a white rounded square in the middle. There are no errors neither in Nuxt log, nor in the console log.

This is my nuxt.config.ts file:

import Aura from '@primeuix/themes/aura';

import { PrismaClient } from '@prisma/client'
import { PrismaAdapter } from '@next-auth/prisma-adapter'

const prisma = new PrismaClient()

export default defineNuxtConfig({
  modules: [
    '@nuxtjs/tailwindcss',
    '@primevue/nuxt-module',
    '@sidebase/nuxt-auth',
  ],
  auth: {
    isEnabled: true,
    debug: true,
    origin: 'http://localhost:3000',
    baseURL: 'http://localhost:3000/api/auth',
    basePath: '/api/auth',

    enableSession: true,
    session: {
      strategy: 'database',        // <-- persist sessions in SQLite
      maxAge: 30 * 24 * 60 * 60,   // 30 days session validity
    },

    adapter: PrismaAdapter(prisma), // <-- connect Nuxt Auth to SQLite DB

    providers: [
      {
        provider: 'google',
        options: {
          clientId: process.env.GOOGLE_CLIENT_ID,
          clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        }
      }
    ],

    callbacks: {
      async session({ session, user }) {
        session.user.id = user.id // attach user id (optional)
        return session
      }
    }
  },
  primevue: {
    options: {
      theme: {
        preset: Aura
      }
    }
  },
  css: [
    '@/assets/css/main.css',
    '@/assets/css/fonts.css',
  ],
  buildModules: ['@nuxtjs/tailwindcss'],

  compatibilityDate: '2025-03-16'
})

The server/api/auth/[...].ts file is:

import { NuxtAuthHandler } from '#auth'

export default NuxtAuthHandler({
    secret: process.env.AUTH_SECRET, // Use a secret for JWT or session cookie
    providers: [
        {
            provider: 'google',
            options: {
                clientId: process.env.GOOGLE_CLIENT_ID,
                clientSecret: process.env.GOOGLE_CLIENT_SECRET,
            },
        },
        // Add other providers as needed
    ],
    callbacks: {
        async session(session, user) {
            console.log('Session callback:', session, user)
            return session
        },
        async signIn(user, account, profile) {
            console.log('SignIn callback:', user, account, profile)
            return true
        },
    },
})

I have defined the Google oAuth secrets in .env.

The authentication flow is not even triggered, in the Network console I see only a call to signin but no attempts to go to Google are made.


For reference, package.json

{
  "name": "nuxt-app",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "dependencies": {
    "@next-auth/prisma-adapter": "^1.0.7",
    "@primeuix/themes": "^1.0.0",
    "@primevue/forms": "^4.3.2",
    "@prisma/client": "^6.5.0",
    "@sidebase/nuxt-auth": "^0.10.1",
    "nuxt": "^3.16.0",
    "primevue": "^4.3.2",
    "vue": "^3.5.13",
    "vue-router": "^4.5.0"
  },
  "devDependencies": {
    "@nuxtjs/tailwindcss": "^6.13.2",
    "@primevue/nuxt-module": "^4.3.2",
    "autoprefixer": "^10.4.21",
    "postcss": "^8.5.3",
    "prisma": "^6.5.0",
    "tailwindcss": "^3.4.17"
  }
}

Also for reference - the gray page above. To me there are no embedded actions at all:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
      :root {
        --border-width: 1px;
        --border-radius: 0.5rem;
        --color-error: #c94b4b;
        --color-info: #157efb;
        --color-info-text: #fff;
      }
      .__next-auth-theme-auto,
      .__next-auth-theme-light {
        --color-background: #ececec;
        --color-background-card: #fff;
        --color-text: #000;
        --color-primary: #444;
        --color-control-border: #bbb;
        --color-button-active-background: #f9f9f9;
        --color-button-active-border: #aaa;
        --color-seperator: #ccc;
      }
      .__next-auth-theme-dark {
        --color-background: #161b22;
        --color-background-card: #0d1117;
        --color-text: #fff;
        --color-primary: #ccc;
        --color-control-border: #555;
        --color-button-active-background: #060606;
        --color-button-active-border: #666;
        --color-seperator: #444;
      }
      @media (prefers-color-scheme: dark) {
        .__next-auth-theme-auto {
          --color-background: #161b22;
          --color-background-card: #0d1117;
          --color-text: #fff;
          --color-primary: #ccc;
          --color-control-border: #555;
          --color-button-active-background: #060606;
          --color-button-active-border: #666;
          --color-seperator: #444;
        }
      }
      body {
        background-color: var(--color-background);
        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
          Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif,
          Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
        margin: 0;
        padding: 0;
      }
      h1 {
        font-weight: 400;
        margin-bottom: 1.5rem;
        padding: 0 1rem;
      }
      h1,
      p {
        color: var(--color-text);
      }
      form {
        margin: 0;
        padding: 0;
      }
      label {
        font-weight: 500;
        margin-bottom: 0.25rem;
        text-align: left;
      }
      input[type],
      label {
        color: var(--color-text);
        display: block;
      }
      input[type] {
        background: var(--color-background-card);
        border: var(--border-width) solid var(--color-control-border);
        border-radius: var(--border-radius);
        box-sizing: border-box;
        font-size: 1rem;
        padding: 0.5rem 1rem;
        width: 100%;
      }
      input[type]:focus {
        box-shadow: none;
      }
      p {
        font-size: 1.1rem;
        line-height: 2rem;
        margin: 0 0 1.5rem;
        padding: 0 1rem;
      }
      a.button {
        line-height: 1rem;
        text-decoration: none;
      }
      a.button:link,
      a.button:visited {
        background-color: var(--color-background);
        color: var(--color-primary);
      }
      button span {
        flex-grow: 1;
      }
      a.button,
      button {
        align-items: center;
        background-color: var(--provider-bg, var(--color-background-card));
        border-color: rgba(0, 0, 0, 0.1);
        border-radius: var(--border-radius);
        color: var(--provider-color, var(--color-primary));
        display: flex;
        font-size: 1.1rem;
        font-weight: 500;
        justify-content: center;
        margin: 0 0 0.75rem;
        min-height: 62px;
        padding: 0.75rem 1rem;
        position: relative;
        transition: all 0.1s ease-in-out;
      }
      @media (max-width: 450px) {
        a.button,
        button {
          font-size: 0.9rem;
        }
      }
      a.button:active,
      a.button:hover,
      button:active,
      button:hover {
        cursor: pointer;
      }
      a.button #provider-logo,
      button #provider-logo {
        display: block;
        width: 25px;
      }
      a.button #provider-logo-dark,
      button #provider-logo-dark {
        display: none;
      }
      #submitButton {
        background-color: var(--brand-color, var(--color-info));
        color: var(--button-text-color, var(--color-info-text));
        width: 100%;
      }
      @media (prefers-color-scheme: dark) {
        a.button,
        button {
          background-color: var(--provider-dark-bg, var(--color-background));
          color: var(--provider-dark-color, var(--color-primary));
        }
        #provider-logo {
          display: none !important;
        }
        #provider-logo-dark {
          display: block !important;
          width: 25px;
        }
      }
      a.site {
        color: var(--color-primary);
        font-size: 1rem;
        line-height: 2rem;
        text-decoration: none;
      }
      a.site:hover {
        text-decoration: underline;
      }
      .page {
        display: grid;
        height: 100%;
        margin: 0;
        padding: 0;
        place-items: center;
        position: absolute;
        width: 100%;
      }
      .page > div {
        text-align: center;
      }
      .error a.button {
        display: inline-block;
        margin-top: 0.5rem;
        padding-left: 2rem;
        padding-right: 2rem;
      }
      .error .message {
        margin-bottom: 1.5rem;
      }
      .signin input[type="text"] {
        display: block;
        margin-left: auto;
        margin-right: auto;
      }
      .signin hr {
        border: 0;
        border-top: 1px solid var(--color-seperator);
        display: block;
        margin: 2rem auto 1rem;
        overflow: visible;
      }
      .signin hr:before {
        background: var(--color-background-card);
        color: #888;
        content: "or";
        padding: 0 0.4rem;
        position: relative;
        top: -0.7rem;
      }
      .signin .error {
        background: #f5f5f5;
        background: var(--color-error);
        border-radius: 0.3rem;
        font-weight: 500;
      }
      .signin .error p {
        color: var(--color-info-text);
        font-size: 0.9rem;
        line-height: 1.2rem;
        padding: 0.5rem 1rem;
        text-align: left;
      }
      .signin form,
      .signin > div {
        display: block;
      }
      .signin form input[type],
      .signin > div input[type] {
        margin-bottom: 0.5rem;
      }
      .signin form button,
      .signin > div button {
        width: 100%;
      }
      .signin form,
      .signin > div {
        max-width: 300px;
      }
      .logo {
        display: inline-block;
        margin-bottom: 25px;
        margin-top: 20px;
        max-height: 70px;
        max-width: 150px;
      }
      @media screen and (min-width: 450px) {
        .card {
          width: 350px;
        }
      }
      @media screen and (max-width: 450px) {
        .card {
          width: 200px;
        }
      }
      .card {
        background-color: var(--color-background-card);
        border-radius: 30px;
        margin: 20px 0;
        padding: 20px 50px;
      }
      .card .header {
        color: var(--color-primary);
      }
      .section-header {
        color: var(--color-text);
      }
    </style>
    <title>Sign In</title>
  </head>
  <body class="__next-auth-theme-auto">
    <div class="page">
      <div class="signin"><div class="card"></div></div>
    </div>
  </body>
</html>
发布评论

评论列表(0)

  1. 暂无评论