跳转到内容

身份验证

身份认证(Authentication)和授权(Authorization)是管理对你网站或应用的访问的两个安全过程。身份认证验证访问者的身份,而授权则授予对受保护区域和资源的访问权限。

身份认证允许你为已登录的用户定制网站的区域,并为个人或私密信息提供最大程度的保护。身份认证库(例如 Auth.jsClerk)为多种身份认证方法(如电子邮件登录和 OAuth 提供商)提供实用工具。

请在我们为这些后端服务提供的专门指南中查看如何使用 Supabase 添加身份认证使用 Firebase 添加身份认证

Auth.js 是一个与框架无关的身份认证解决方案。Astro 有一个社区框架适配器 auth-astro 可用。

使用你偏好的包管理器,通过 astro add 命令来添加 auth-astro 集成。

终端窗口
npx astro add auth-astro

要手动安装 auth-astro,请为你的包管理器安装所需的包

终端窗口
npm install auth-astro @auth/core@^0.18.6

然后,使用 integrations 属性将此集成应用到你的 astro.config.* 文件中:

astro.config.mjs
import { defineConfig } from 'astro/config';
import auth from 'auth-astro';
export default defineConfig({
// ...
integrations: [auth()],
});

在你的项目根目录中创建一个 auth.config.ts 文件。添加任何你希望支持的身份认证提供商或方法,以及它们需要的任何环境变量。

auth.config.ts
import GitHub from '@auth/core/providers/github';
import { defineConfig } from 'auth-astro';
export default defineConfig({
providers: [
GitHub({
clientId: import.meta.env.GITHUB_CLIENT_ID,
clientSecret: import.meta.env.GITHUB_CLIENT_SECRET,
}),
],
});

如果你的项目根目录中不存在 .env 文件,请创建一个。添加以下两个环境变量。 AUTH_SECRET 应该是一个至少有 32 个字符的私有字符串。

.env
AUTH_TRUST_HOST=true
AUTH_SECRET=<my-auth-secret>

你可以在脚本标签或客户端框架组件中使用 auth-astro/client 模块来添加登录和登出按钮。

src/pages/index.astro
---
import Layout from 'src/layouts/Base.astro';
---
<Layout>
<button id="login">Login</button>
<button id="logout">Logout</button>
<script>
const { signIn, signOut } = await import("auth-astro/client")
document.querySelector("#login").onclick = () => signIn("github")
document.querySelector("#logout").onclick = () => signOut()
</script>
</Layout>

你可以使用 getSession 方法来获取用户的会话。

src/pages/index.astro
---
import Layout from 'src/layouts/Base.astro';
import { getSession } from 'auth-astro/server';
export const prerender = false; // Not needed in 'server' mode
const session = await getSession(Astro.request);
---
<Layout>
{
session ? (
<p>Welcome {session.user?.name}</p>
) : (
<p>Not logged in</p>
)
}
</Layout>

Better Auth 是一个用于 TypeScript 的与框架无关的身份认证(和授权)框架。它开箱即用地提供了一套全面的功能,并包含一个插件生态系统,可以简化高级功能的添加。

它开箱即支持 Astro,你可以用它来为你的 Astro 项目添加身份认证。

终端窗口
npm install better-auth

有关详细的设置说明,请查看 Better Auth 安装指南

按照 Better Auth 安装指南中的描述,配置你的数据库表以存储用户数据和你偏好的身份认证方法。然后,你需要在你的 Astro 项目中挂载 Better Auth 处理程序。

src/pages/api/auth/[...all].ts
import { auth } from "../../../lib/auth"; // import your Better Auth instance
import type { APIRoute } from "astro";
export const prerender = false; // Not needed in 'server' mode
export const ALL: APIRoute = async (ctx) => {
return auth.handler(ctx.request);
};

请遵循 Better Auth Astro 指南以了解更多信息。

Better Auth 为各种框架提供了一个 createAuthClient 辅助函数,包括 Vanilla JS、React、Vue、Svelte 和 Solid。

例如,要为 React 创建一个客户端,请从 'better-auth/react' 导入该辅助函数。

src/lib/auth-client.ts
import { createAuthClient } from 'better-auth/react';
export const authClient = createAuthClient();
export const { signIn, signOut } = authClient;

客户端设置好后,你就可以用它在你的 Astro 组件或任何特定于框架的文件中对用户进行身份认证。下面的例子通过你配置的 signIn()signOut() 函数添加了登录或登出的功能。

src/pages/index.astro
---
import Layout from 'src/layouts/Base.astro';
---
<Layout>
<button id="login">Login</button>
<button id="logout">Logout</button>
<script>
const { signIn, signOut } = await import("./lib/auth-client")
document.querySelector("#login").onclick = () => signIn.social({
provider: "github",
callbackURL: "/dashboard",
})
document.querySelector("#logout").onclick = () => signOut()
</script>
</Layout>

然后,你可以在服务器端代码中使用 auth 对象来获取用户的会话数据。下面的例子通过显示已认证用户的姓名来个性化页面内容

src/pages/index.astro
---
import { auth } from "../../../lib/auth"; // import your Better Auth instance
export const prerender = false; // Not needed in 'server' mode
const session = await auth.api.getSession({
headers: Astro.request.headers,
});
---
<p>{session.user?.name}</p>

你也可以使用 auth 对象通过中间件来保护你的路由。下面的例子检查尝试访问已登录仪表板路由的用户是否已认证,如果未认证,则将他们重定向到主页。

src/middleware.ts
import { auth } from "../../../auth"; // import your Better Auth instance
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async (context, next) => {
const isAuthed = await auth.api
.getSession({
headers: context.request.headers,
})
if (context.url.pathname === "/dashboard" && !isAuthed) {
return context.redirect("/");
}
return next();
});

Clerk 是一套完整的可嵌入 UI、灵活的 API 和管理仪表盘,用于对用户进行身份认证和管理。Astro 有一个官方的 Clerk SDK

使用你选择的包管理器安装 @clerk/astro

终端窗口
npm install @clerk/astro

请遵循 Clerk 自己的 Astro 快速入门指南,在你的 Astro 项目中设置 Clerk 集成和中间件。

Clerk 提供的组件可以让你根据用户的身份认证状态来控制页面的可见性。向未登录的用户显示一个登录按钮,而不是向已登录的用户显示内容

src/pages/index.astro
---
import Layout from 'src/layouts/Base.astro';
import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/astro/components';
export const prerender = false; // Not needed in 'server' mode
---
<Layout>
<SignedIn>
<UserButton />
</SignedIn>
<SignedOut>
<SignInButton />
</SignedOut>
</Layout>

Clerk 还允许你使用中间件在服务器上保护路由。指定哪些路由是受保护的,并提示未认证的用户登录

src/middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/astro/server';
const isProtectedRoute = createRouteMatcher([
'/dashboard(.*)',
'/forum(.*)',
]);
export const onRequest = clerkMiddleware((auth, context) => {
if (!auth().userId && isProtectedRoute(context.request)) {
return auth().redirectToSignIn();
}
});

Lucia 是一个用于在包括 Astro 在内的多种框架中实现基于会话的身份认证的资源。

  1. 使用你选择的数据库创建一个基本的会话 API
  2. 使用端点和中间件添加会话 cookie
  3. 使用你实现的 API 来实现 GitHub OAuth
贡献 社区 赞助