如何在 next-auth 中向客户端 API 添加数据?

Posted

技术标签:

【中文标题】如何在 next-auth 中向客户端 API 添加数据?【英文标题】:How do I add data to the client API in next-auth? 【发布时间】:2022-01-04 02:47:59 【问题描述】:

我目前正在使用 next-auth 使用凭据提供程序进行授权,我有会话工作并且用户可以登录等。但是,在会话中我需要使用客户端 API、用户、名字传递一些数据、姓氏、用户名和电子邮件。

默认情况下客户端API通过,名称,电子邮件和图像,但是,我如何更改它以添加上述数据,这是我目前所拥有的。

index.js

import  useState, useEffect   from 'react';
import  getSession  from 'next-auth/client'
import  useRouter  from 'next/router';
import Link from 'next/link';
import Head from 'next/head';
import Sidebar from '../components/Sidebar';

export default function Dashboard( user) 
  return (
    <div>
      <Head>
        <title>Dashboard</title>
      </Head>

      <Sidebar />

      <section className="content dashboard-content">
        <h1>Dashboard</h1>

        <h3>Welcome to Ellis development user.firstname </h3>
      </section>
    </div>
  )


export async function getServerSideProps(ctx) 
  const session = await getSession(ctx);
  
  if (!session) 
    return 
      redirect: 
        destination: '/dashboard/auth/login',
        permanent: false
      ,
    
  

  console.log(session);

  return 
    props: 
      user: 
        firstname: session.user.firstname,
        lastname: session.user.lastname,
        username: session.user.username,
        email: session.user.email,
      
    ,
  

[...nextauth.js]

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

import  verifyPassword  from '../../../lib/auth';
import  connectToDatabase  from '../../../lib/mongodb';

export default NextAuth(
  session: 
    jwt: true,
  ,
  providers: [
    Providers.Credentials(
      async authorize(credentials) 
        const client = await connectToDatabase();
        const usersCollection = client.db().collection('users');

        const user = await usersCollection.findOne(
          email: credentials.email,
        );

        if (!user) 
          client.close();
          throw new Error('No user found!');
        

        const isValid = await verifyPassword(
          credentials.password,
          user.password
        );

        if (!isValid) 
          client.close();
          throw new Error('Could not log you in!');
        

        client.close();

        return 
          firstname: user.firstname,
          lastname: user.lastname,
          username: user.username,
          email: user.email
        ;
      ,
    ),
  ],
);

任何帮助都会很棒,谢谢。

编辑

我已将以下内容添加到 [...next-auth] 页面

callbacks: 
  session: async (session) => 
    if (!session) return;

    const client = await connectToDatabase();
    const usersCollection = client.db().collection('users');
    
    const userData = await usersCollection.findOne(
      email: session.user.email,
    );

    return 
      session: 
        user: 
          id: userData._id,
          firstname: userData.firstname,
          lastname: userData.lastname,
          username: userData.username,
          email: userData.email
        
      
    ;
  ,
,

这给了我以下结果


  session: 
    user: 
      id: '61a107f29ca24c12146d1b22',
      firstname: 'Ben',
      lastname: 'Bagley',
      username: 'benbagley',
      email: 'benbagley@pm.me'
    
  

所以我现在有了我需要的值,但是,我如何将数据呈现到我现在拥有以下内容的页面上

import  getSession  from 'next-auth/client'
import Head from 'next/head';
import Sidebar from '../components/Sidebar';

export default function Dashboard( session ) 
  return (
    <div>
      <Head>
        <title>Dashboard</title>
      </Head>

      <Sidebar />

      <section className="content dashboard-content">
        <h1>Dashboard</h1>

        <h3>Welcome session.user.firstname to Ellis development</h3>
      </section>
    </div>
  )


export async function getServerSideProps(ctx) 
  const session = await getSession(ctx);
  
  if (!session) 
    return 
      redirect: 
        destination: '/dashboard/auth/login',
        permanent: false
      ,
    
  

  console.log(session);

  return 
    props: 
      session: 
        user: 
          id: session.user.id,
          firstname: session.user.firstname,
          lastname: session.user.lastname,
          username: session.user.username,
        
      
    ,
  

但是,我收到了TypeError: Cannot read properties of undefined (reading 'id')

【问题讨论】:

【参考方案1】:

您应该检查下一个身份验证回调。用户对象将包含电子邮件、图像和名称。您可以使用它来获取内部 api 左右,并将信息附加到将在 jwt 中编码的会话对象。

callbacks: 
        session: async (session, user) => 
            if (!session) return;
            const userServerData = fetch(...); // or some internal logic
            
            session.user.firstName = userServerData.firstName;
            session.user.lastname = userServerData.lastname;
            session.user.username = userServerData.username;
            
            return Promise.resolve(session);
        ,
    ,

【讨论】:

请根据您的回复查看对问题的修改,我不确定您希望我在这里获取什么?【参考方案2】:

这里有两个问题,

a) 未使用适当的回调来添加和覆盖 next-auth api,例如:

callbacks: 
  session: async (session) => 
    if (!session) return;

    const client = await connectToDatabase();
    const usersCollection = client.db().collection('users');
    
    const userData = await usersCollection.findOne(
      email: session.user.email,
    );

    return 
      session: 
        user: 
          id: userData._id,
          firstname: userData.firstname,
          lastname: userData.lastname,
          username: userData.username,
          email: userData.email
        
      
    ;
  ,
,

现在这是在传递值,下一个问题支持......

b) 传递 props 时不使用扩展运算符

export async function getServerSideProps(ctx) 
  const session = await getSession(ctx);
  
  if (!session) 
    return 
      redirect: 
        destination: '/dashboard/auth/login',
        permanent: false
      ,
    
  

  return 
    props: 
      ...session,
    
  

调用...session 获取所有返回对象并允许将其作为session.user.firstname 传递,非常方便。

【讨论】:

【参考方案3】:

这就是我在项目中解决同样问题的方法

第 1 步:将以下内容添加到 ...[nextauth].ts

  pages: 
    // signIn: '/auth/signin',
    // signOut: '/auth/signout',
    // error: '/auth/error', // Error code passed in query string as ?error=
    // verifyRequest: '/auth/verify-request', // (used for check email message)
    newUser: '/auth/newuser' // New users will be directed here on first sign in 
  ,

第 2 步:现在您可以更新用户数据并发布到您的 api

'/auth/newuser.ts'

    React.useEffect(() => 
   

       post updated user data to -> "/api/auth/newuserwelcome"

      , [])

//
Step 3: create api endpoint to save updated user data to DB
    /api/auth/newuserwelcome.ts
      

【讨论】:

以上是关于如何在 next-auth 中向客户端 API 添加数据?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:如何在查询中向日期时间字段添加一天

使用 next-auth 时,如何从浏览器调用我的 Cognito 安全 Rest API?

Next-auth - 如何更新会话客户端?

在Android应用程序中向GridView添加一组按钮

使用 Next-Auth 进行身份验证时如何修复内部服务器错误

在 Tigase 中向客户端发送自定义消息