【问题标题】:Get supabase `user` server side in next.js在 next.js 中获取 supabase `user` 服务器端
【发布时间】:2022-01-11 05:48:49
【问题描述】:

我正在尝试在服务器端获取当前登录的 supabase 用户。

我曾尝试使用const user = supabase.auth.user();,但我总是收到null 响应。

我也尝试过const user = supabase.auth.getUserByCookie(req),但它也返回null。我想是因为从钩子调用它时我没有向 api 发送 cookie。

我尝试将user.id 从挂钩传递给 api,但 api 没有接收到参数。

我也尝试过这种方法,但从未获取过令牌。 req.cookies 中似乎不存在。

    let supabase = createClient(supabaseUrl, supabaseKey);
    let token = req.cookies['sb:token'];
    if (!token) {
        return 
    }
    let authRequestResult = await fetch(`${supabaseUrl}/auth/v1/user`, {
        headers: {
            'Authorization': `Bearer ${token}`,
            'APIKey': supabaseKey
        }
    });
`

有谁知道如何在服务器端代码中获取当前登录的用户?

【问题讨论】:

    标签: next.js supabase supabase-database


    【解决方案1】:

    如果您需要在服务器端获取用户,则需要使用给定的 Next.js API 在服务器中设置 Auth Cookie。

    // pages/api/auth.js
    import { supabase } from "../path/to/supabaseClient/definition";
    
    export default function handler(req, res) {
        if (req.method === "POST") {
            supabase.auth.api.setAuthCookie(req, res);
        } else {
            res.setHeader("Allow", ["POST"]);
            res.status(405).json({
                message: `Method ${req.method} not allowed`,
            });
        }
    }
    

    每次用户状态改变时都需要调用这个端点,即事件SIGNED_INSIGNED_OUT

    您可以在 _app.js 或用户上下文文件中设置 useEffect。

    // _app.js
    
    import "../styles/globals.css";
    import { supabase } from '../path/to/supabaseClient/def'
    
    function MyApp({ Component, pageProps }) {
    
        useEffect(() => {
        const { data: authListener } = supabase.auth.onAuthStateChange((event, session) => {
          handleAuthChange(event, session)
          if (event === 'SIGNED_IN') {
             // TODO: Actions to Perform on Sign In
          }
          if (event === 'SIGNED_OUT') {
             // TODO: Actions to Perform on Logout
          }
        })
        checkUser()
        return () => {
          authListener.unsubscribe()
        }
      }, [])
    
        return <Component {...pageProps} />;
    }
    
    async function handleAuthChange(event, session) {
        await fetch('/api/auth', {
          method: 'POST',
          headers: new Headers({ 'Content-Type': 'application/json' }),
          credentials: 'same-origin',
          body: JSON.stringify({ event, session }),
        })
      }
    
    export default MyApp;
    

    您现在可以使用状态处理此用户并将其传递给应用程序或任何您想要的方式。

    您可以在任何 Next.js 页面中获取服务器端的用户

    // pages/user_route.js
    
    import { supabase } from '../path/to/supabaseClient/def'
    
    export default function UserPage ({ user }) {
    
      return (
        <h1>Email: {user.email}</h1>
      )
    
    }
    
    export async function getServerSideProps({ req }) {
      const { user } = await supabase.auth.api.getUserByCookie(req)
    
      if (!user) {
        return { props: {}, redirect: { destination: '/sign-in' } }
      }
    
      return { props: { user } }
    }
    
    

    这是来自 Nader Dabit 的 YouTube 教程 - https://www.youtube.com/watch?v=oXWImFqsQF4
    还有他的 GitHub 存储库 - https://github.com/dabit3/supabase-nextjs-auth

    【讨论】:

    • 我遵循了这个并且我得到了_app.tsx 中的代码来工作,但是当我在pages/api/testing.tsx 中调用const user = supabase.auth.api.getUserByCookie(req); 时,我仍然得到null
    • 尝试在控制台中记录 req.cookies["sb:token"]) 以检查 Supabase 令牌是否存在。如果是这样,您可以尝试 - const { user } = await supabase.auth.api.getUser(req.cookies["sb:token"]);
    • 是的,当我将 supbase 令牌登录到控制台时,它就存在了。但是当我运行const { user } = await supabase.auth.api.getUser(req.cookies["sb:token"]); 时,我仍然得到null
    【解决方案2】:

    我今天在学习一个教程并且遇到了类似的问题,下面是我设法解决它的方法。

    我已经安装了这个包 github.com/jshttp/cookie 这就是我调用 cookie.parse 的原因。

    Supabase 实例:

    `//../../../utils/supabase`
    
    import { createClient } from "@supabase/supabase-js";
    
    export const supabase = createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL,
    process.env.NEXT_PUBLIC_SUPABASE_KEY
    );
    

    在我的例子中,这是我的 API 页面:

    import { supabase } from "../../../utils/supabase";
    import cookie from "cookie";
    import initStripe from "stripe";
    
    const handler = async (req, res) => {
    const { user } = await supabase.auth.api.getUserByCookie(req);
    
      if (!user) {
        return res.status(401).send("Unathorized");
      }
    
      const token = cookie.parse(req.headers.cookie)["sb-access-token"];
    
      supabase.auth.session = () => ({
        access_token: token,
       });`
    
      const {
        data: { stripe_customer },
      } = await supabase
        .from("profile")
        .select("stripe_customer")
        .eq("id", user.id)
        .single();
    

    【讨论】:

      猜你喜欢
      • 2018-08-31
      • 1970-01-01
      • 2011-12-26
      • 2021-01-08
      • 1970-01-01
      • 2021-08-30
      • 2020-10-17
      • 2021-09-21
      • 2021-06-18
      相关资源
      最近更新 更多