reactjs 使用Magic Link使用Astro中的Supplement登录用户不起作用

pkmbmrz7  于 11个月前  发布在  React
关注(0)|答案(1)|浏览(86)

正如描述所说,当你点击电子邮件时,它会把你带到主页,你可以在url和console.log的日志中看到访问令牌,用户为null。
产品编号:https://github.com/polooner/diverse-stem/blob/main/src/auth.ts
src/auth.ts

import { createClient } from '@supabase/supabase-js';
import cookie from 'cookie';

export const supabase = createClient(
  import.meta.env.PUBLIC_SUPABASE_URL,
  import.meta.env.PUBLIC_SUPABASE_ANON_KEY
);

export async function getUser(req: Request) {
  const c = cookie.parse(req.headers.get('cookie') ?? '');
  if (!c.sbat) {
    return null;
  }
  console.log(c.sbat);

  const {
    data: { user },
  } = await supabase.auth.getUser(c.sbat);
  if (!user || user.role !== 'authenticated') {
    return null;
  }
  console.log(user);
  return user;
}

export async function isLoggedIn(req: Request) {
  return (await getUser(req)) != null;
}

字符串
src/pages/API/login.astro

---
import {supabase} from "../../auth"

const body = await Astro.request.json();
Astro.response.headers.set('Set-Cookie', `sbat=${body.access_token}; Path=/;`);
---

lmvvr0a8

lmvvr0a81#

您要查找的是getSession而不是getUser。请参见https://supabase.com/docs/guides/auth/server-side-rendering
我们大致使用以下Astro中间件来实现这一点:

import {
  type AuthError,
  createClient,
  type Session,
  type SupabaseClient,
  type SupportedStorage,
  type User,
} from '@supabase/supabase-js'
import type { AstroCookies } from 'astro'
import { defineMiddleware } from 'astro:middleware'
import jwt from 'jsonwebtoken'

export interface UserData {
  email: string;
  id: string;
  isAdmin: boolean;
}

export const authMiddleware = defineMiddleware(async (context, next) => {
  const { cookies, locals } = context

  locals.supabase = createSupabaseClient(cookies)

  // Returns the session, refreshing it if necessary.
  // - retrieves the current local session (i.e cookie)
  // - if the session expired, will use refresh token to get new session.
  // @see https://supabase.com/docs/reference/javascript/auth-getsession
  try {
    const res = await supaToResult(locals.supabase.auth.getSession())
    locals.user = verifyAndGetUserData(res.session.access_token)
  } catch (e) {
  }

  return next()
})

// A simple storage handler to persist Supabase data (i.e. current auth token)
// Uses AstroCookies to store data in cookies
const createStorage = (cookies: AstroCookies): SupportedStorage => ({
  getItem: (key) => {
    if (!key) {
      return null
    }

    return cookies.get(key)?.value ?? null
  },
  setItem: (key, value) => {
    cookies.set(
      key,
      value,
      {
        httpOnly: true,
        maxAge: 1000 * 60 * 60 * 24 * 365, // a year
        path: '/',
        // sameSite lax because Safari (at least 16.3-16.6) sometimes doesn't send cookies otherwise
        // @see https://bugs.webkit.org/show_bug.cgi?id=255524
        sameSite: 'lax',
        // Disable "secure" flag in development; Safari refuses to set a "secure" cookie
        secure: import.meta.env.NODE_ENV === 'production',
      },
    )
  },
  removeItem: (key) => {
    cookies.delete(
      key,
      { path: '/' },
    )
  },
})

const createSupabaseClient = (cookies: AstroCookies): SupabaseClient => {
  return createClient(
    import.meta.env.SUPA_URL,
    import.meta.env.SUPA_KEY,
    {
      auth: {
        flowType: 'pkce',
        persistSession: true,
        storage: createStorage(cookies),

        // disable unwanted client-side behaviours
        autoRefreshToken: false,
        detectSessionInUrl: false,
      },
    },
  )
}

const verifyAndGetUserData = (accessToken: string): UserData | undefined => {
  if (!accessToken) {
    return
  }

  let payload
  try {
    payload = jwt.verify(accessToken, import.meta.env.SUPA_JWT_SECRET)
  } catch (e) {} // swallow verify error

  if (typeof payload === 'object') {
    const { sub, email } = payload

    if (sub && email) {
      return {
        email,
        id: sub,
      }
    }
  }
}

字符串

相关问题