【问题标题】:How to write authorize function correctly in typescript for nextauthjs如何在 typescript for nextauthjs 中正确编写授权函数
【发布时间】:2022-02-06 03:40:10
【问题描述】:

我正在尝试将Credentials Provider 与 NextJs(“next”:“^12.0.7”)和 NextAuth(“next-auth”:“^4.1.2”)一起使用。我正在用打字稿写这个,并且在正确获取函数方面遇到问题。

这是我的/pages/api/[...nextauth].ts

import NextAuth, {  } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { verifyOTP } from "@/lib/otp";

// {
//   user: {
//     id: 1,
//     username: null,
//     phone: '+919876543210',
//     phoneVerified: true,
//     email: null,
//     emailVerified: false,
//     active: true,
//     token: 'SOME TOKEN',
//     createDate: null
//   },
//   result: 'approved'
// }

export default NextAuth({
  pages: {
    signIn: '/signup',
    newUser: '/signup',
    error: '/signup'
  },
  debug: false,
  secret: "SOME_SECRET",
  // Configure one or more authentication providers
  providers: [
    CredentialsProvider({
      credentials: {
        username: {label: "username", type: "text", placeholder: "markandre"},
        phone: { label: "Phone ", type: "text", placeholder: "+919876543210" },
        otp: {  label: "OTP", type: "text" }
      },
      authorize: async (credentials, _req) => {
        try {
          const res = await verifyOTP(credentials!.phone,
            credentials!.otp, credentials?.username);
          if (res.result === "approved") {
            return Promise.resolve( {
              id: res.user.id,
              email: res.user.email,
              name: res.user.phone,
              token: res.user.token
            });
          }
        } catch (e: any) {
          //const errorMessage = e.response.data.message;
          //throw new Error(errorMessage);
          return Promise.reject(null);
        }
      }
    })
  ],
  session: {
    strategy: 'jwt',
    maxAge: 3 * 60 * 60, // 3 hours
  },
  callbacks: {
    jwt: async ({token, user}) => {
      if (user) {
        token.accessToken = user.token
      }

      return token;
    },
    session:async ({session, token}) => {
      if (token) {
        session.accessToken = token.accessToken;
      }
      return session;
    }
  },
  events: {
    signIn: async (message) => {
      console.log('signIn', message);
    },
    signOut: async (message) => {
      console.log('signOut', message);
    },
    createUser: async(message) => {
      console.log('createUser', message);
    },
    updateUser: async(message) => {
      console.log('updateUser', message);
    },
    linkAccount: async(message) => {
      console.log('linkAccount',message);
    },
    session: async(message) => {
      // console.log('session', message);
    }
  }
})

当我构建这个应用程序时,我不断收到错误

./src/pages/api/auth/[...nextauth].ts:36:7
Type error: Type '(credentials: Record<"username" | "phone" | "otp", string> | undefined, _req: Pick<IncomingRequest, "headers" | "body" | "query" | "method">) => Promise<...>' is not assignable to type '(credentials: Record<"username" | "phone" | "otp", string> | undefined, req: Pick<IncomingRequest, "headers" | "body" | "query" | "method">) => Awaitable<...>'.
  Type 'Promise<Omit<User, "id"> | null | undefined>' is not assignable to type 'Awaitable<Omit<User, "id"> | { id?: string | undefined; } | null>'.
    Type 'Promise<Omit<User, "id"> | null | undefined>' is not assignable to type 'Omit<User, "id">'.
      Index signature for type 'string' is missing in type 'Promise<Omit<User, "id"> | null | undefined>'.

  34 |         otp: {  label: "OTP", type: "text" }
  35 |       },
> 36 |       authorize: async (credentials, _req) => {
     |       ^
  37 |         try {
  38 |           const res = await verifyOTP(credentials!.phone,
  39 |             credentials!.otp, credentials?.username);
info  - Checking validity of types .%

我的.tsconfig 如下所示

{
  "compilerOptions": {
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "strict": true,
    "alwaysStrict": false,
    "strictNullChecks": true,
    "noUncheckedIndexedAccess": true,

    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowUnreachableCode": false,
    "noFallthroughCasesInSwitch": true,

    "target": "es5",
    "outDir": "out",
    "declaration": true,
    "sourceMap": true,

    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,

    "jsx": "preserve",
    "noEmit": true,
    "isolatedModules": true,
    "incremental": true,

    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@/public/*": ["./public/*"]
    }
  },
  "exclude": ["./out/**/*", "./node_modules/**/*"],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

【问题讨论】:

    标签: typescript next.js next-auth


    【解决方案1】:

    authorize 函数需要返回代表用户的对象或 false/null(如果凭据无效)。

    res.result === "approved" 检查为假时,您当前的逻辑没有显式返回false/null,因此类型错误。您可以通过在 if 块之后显式返回 null 来解决此问题。

    authorize: async (credentials, _req) => {
        try {
            const res = await verifyOTP(credentials!.phone, credentials!.otp, credentials?.username);
            if (res.result === "approved") {
                return {
                    id: res.user.id,
                    email: res.user.email,
                    name: res.user.phone,
                    token: res.user.token
                };
            }
            return null; // Add this line to satisfy the `authorize` typings
        } catch (e: any) {
            //const errorMessage = e.response.data.message;
            //throw new Error(errorMessage);
            return null;
        }
    }
    

    附带说明,您也不需要用Promise.resolve()/Promise.reject() 包装用户对象和null,所以我也省略了这些。

    【讨论】:

      猜你喜欢
      • 2020-04-29
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-09
      • 2021-05-13
      • 2019-10-17
      • 1970-01-01
      相关资源
      最近更新 更多