【问题标题】:custom session next js next-auth自定义会话 next js next-auth
【发布时间】:2021-08-17 08:29:45
【问题描述】:

迁移我的 js 文件 jo tsx 时遇到问题,我正在做的是使用凭据登录并将会话用户自定义到我的用户数据

// api/auth/[...nextauth].js

import NextAuth from "next-auth";
import Providers from "next-auth/providers";
import { ConnectDatabase } from "../../../lib/db";
import { VertifyPassword } from "../../../lib/password";
import { getSelectedUser } from "../../../helpers/database";
import { MongoClient } from "mongodb";
import { NextApiRequest } from "next";

interface credentialsData {
 data: string | number;
 password: string;
}
export default NextAuth({
 session: {
   jwt: true,
 },
 callbacks: {
   async session(session) {
     const data = await getSelectedUser(session.user.email);
     session.user = data.userData;

// inside data.userdata is a object
// {
//   _id: '60a92f328dc04f58207388d1',
//   email: 'user@user.com',
//   phone: '087864810221',
//   point: 0,
//   role: 'user',
//   accountstatus: 'false'
// }
     return Promise.resolve(session);
   },
 },
 providers: [
   Providers.Credentials({
     async authorize(credentials: credentialsData, req: NextApiRequest) {
       let client;
       try {
         client = await ConnectDatabase();
       } catch (error) {
         throw new Error("Failed connet to database.");
       }

       const checkEmail = await client
         .db()
         .collection("users")
         .findOne({ email: credentials.data });
       const checkPhone = await client
         .db()
         .collection("users")
         .findOne({ phone: credentials.data });

       let validData = {
         password: "",
         email: "",
       };

       if (!checkEmail && !checkPhone) {
         client.close();
         throw new Error("Email atau No HP tidak terdaftar.");
       } else if (checkEmail) {
         validData = checkEmail;
       } else if (checkPhone) {
         validData = checkPhone;
       }

       const checkPassword = await VertifyPassword(
         credentials.password,
         validData.password
       );
       if (!checkPassword) {
         client.close();
         throw new Error("Password Salah.");
       }
       client.close();

// inside validData is a object
// {
//   _id: '60a92f328dc04f58207388d1',
//   email: 'user@user.com',
//   phone: '087864810221',
//   point: 0,
//   role: 'user',
//   accountstatus: 'false'
// }

       return validData;
     },
   }),
 ],
});
// as default provider just return session.user just return email,name, and image, but I want custom the session.user to user data what I got from dababase

这个在客户端

// index.tsx

export const getServerSideProps: GetServerSideProps<{
  session: Session | null;
}> = async (context) => {
  const session = await getSession({ req: context.req });

  if (session) {
    if (session.user?.role === "admin") {
      return {
        redirect: {
          destination: "/admin/home",
          permanent: false,
        },
      };
    }
  }
  return {
    props: {
      session,
    },
  };
};

但在客户端我收到警告

Property 'role' does not exist on type '{ name?: string; email?: string; image?: string; 

实际上我的文件仍然可以正常工作,但是当我的文件采用js 格式时,它不会像那样发出警告

有人可以帮我解决吗?

【问题讨论】:

  • 你能告诉我你在 index.tsx 中使用的类型 Session 的实现吗?
  • 在我的问题的顶部,你可以看到我输入了“这个客户端”@RafaelUmbelino
  • 我真的很需要看到界面来帮助你。目前我怀疑问题是你的接口没有“角色”值,所以只有 cmets 说对象拥有的属性不是 enouth 因为在 TS 中你只能访问接口类型中声明的属性.

标签: javascript node.js typescript next.js next-auth


【解决方案1】:

您需要将角色类型添加到 defaultSession 接口去查找此路径./node_modules/next-auth/server/types.d.ts 并查找接口 DefaultSession 并添加此新行role?: string | null; to user?

【讨论】:

    【解决方案2】:

    不确定您是否找到了解决方法,但您还需要配置 jwt 回调!这是我的一个项目的一个例子:

    callbacks: {
            async session(session, token) {
                session.accessToken = token.accessToken;
                session.user = token.user;
                return session;
            },
            async jwt(token, user, account, profile, isNewUser) {
                if (user) {
                    token.accessToken = user._id;
                    token.user = user;
                }
                return token;
            },
        },

    解释事情。 jwt 函数始终在会话之前运行,因此您传递给 jwt 令牌的任何数据都将在会话函数上可用,您可以使用它做任何您想做的事情。在 jwt 函数中,我检查是否有用户,因为这只在您登录时才返回数据。

    【讨论】:

      猜你喜欢
      • 2022-12-25
      • 2022-12-11
      • 1970-01-01
      • 2023-01-18
      • 2022-12-09
      • 2021-11-26
      • 2019-11-14
      • 1970-01-01
      • 2023-01-15
      相关资源
      最近更新 更多