🤖정보보안/💠1분지식

[Auth.js] [auth][error] AccessDenied: AccessDenied. Read more at https://errors.authjs.dev#accessdenied

TwoIceFish 2024. 7. 2. 21:23

문제점

[auth][error] AccessDenied: AccessDenied. Read more at https://errors.authjs.dev#accessdenied

 

Auth.js | Errors

Authentication for the Web

authjs.dev

 

 

해결방법

OAuth의 경우 SignIn 로직을 타고 회원가입이 SignUp 없이 진행된다.

true false로 SignIn 처리를 하느넛을 알게되었다.

// auth.ts
import authConfig from "@/auth.config";
import { PrismaAdapter } from "@auth/prisma-adapter";
import db from "@/lib/db";
import { getUserById } from "@/data/user";
import NextAuth from "next-auth";
import { getAccountByUserId } from "@/data/account";

export const {
  handlers: { GET, POST },
  auth,
  signIn,
  signOut,
} = NextAuth({
  pages: {
    signIn: "/auth",
  },
  callbacks: {
    async session({ token, session }) {
      if (token.sub && session.user) {
        session.user.id = token.sub;
      }

      if (token.role && session.user) {
        session.user.role = token.role;
      }

      if (token.tag && session.user) {
        session.user.tag = token.tag;
      }

      if (session.user) {
        session.user.isTwoFactorEnabled = token.isTwoFactorEnabled;
      }

      if (session.user) {
        session.user.email = token.email;
        session.user.username = token.username;
        session.user.isOAuth = token.isOAuth;
      }

      return session;
    },
    async jwt({ token }) {
      if (!token.sub) return token;

      const existingUser = await getUserById(token.sub);

      if (!existingUser) return token;

      const existingAccount = await getAccountByUserId(existingUser.id);

      token.isOAuth = !!existingAccount;
      token.username = existingUser.username as string;
      token.email = existingUser.email as string;

      token.role = existingUser.role;
      token.isTwoFactorEnabled = existingUser.isTwoFactorEnabled;

      token.tag = existingUser.tag as string;

      return token;
    },
    async signIn({ user, account, profile }) {
      // OAuth인 경우 이로직을 타고 true로 흐름을 흘려보내서 로그인 성공하게 한다!
      if (account?.provider !== "credentials") return true;

      // 여기서는 ID/PW 처리를 위한 로직을 수행하게 된다!
      const existingUser = await getUserById(user.id);

      
      if (!existingUser?.emailVerified) return false;

      return !!existingUser;
    },
  },
  jwt: {
    maxAge: 60 * 60, // 1 hour
  },
  adapter: PrismaAdapter(db),
  session: {
    strategy: "jwt",
    maxAge: 60 * 60, // 1 hour
    updateAge: 60, // 1 minute
  },
  ...authConfig,
});

 

그다음 에러는 다음과 같이 일어난다. 그래서 null 값이 아닌 기본 빈값으로 한다.

Null constraint violation on the fields: (`username`)
model User {
  id                 String          @id @default(cuid())
  name               String?
  username           String?         @unique @default("")
  email              String?         @unique