身份认证
认证和授权是两种安全过程,用来管理对你的网站或应用的访问。身份认证用于验证访客的身份,而授权则允许访问受保护的区域和资源。
认证允许你为登录的个人定制你的网站的特定区域,并为个人或私人信息提供最大程度的保护。认证库(例如 Better Auth、Clerk)为多种认证方法提供了实用工具,如电子邮件登录和 OAuth 提供商。
:::tipAstro 没有官方的认证解决方案,但你可以在集成目录中找到 社区的“auth”集成。:::
Better Auth
Better Auth 是一个与框架无关的 TypeScript 身份验证(和授权)框架。它提供了一套全面的开箱即用功能,并包含一个插件生态系统,可简化添加高级功能的过程。
它开箱即用地支持 Astro,你可以使用它为你的 astro 项目添加身份验证。
安装
npm install better-auth
pnpm add better-auth
yarn add better-auth
有关详细的设置说明,请查看 Better Auth 安装指南。
配置
依照 Better Auth 安装指南 中所述,配置数据库表以存储用户数据和你的首选身份验证方法。然后,你需要在 Astro 项目中挂载 Better Auth 处理程序。
import { auth } from "../../../lib/auth"; // 导入你的 Better Auth 实例
import type { APIRoute } from "astro";
export const prerender = false; // 'server' 模式下,无需配置
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 导入助手:
import { createAuthClient } from 'better-auth/react';
export const authClient = createAuthClient();
export const { signIn, signOut } = authClient;
import { createAuthClient } from 'better-auth/solid';
export const authClient = createAuthClient();
export const { signIn, signOut } = authClient;
import { createAuthClient } from 'better-auth/svelte';
export const authClient = createAuthClient();
export const { signIn, signOut } = authClient;
import { createAuthClient } from 'better-auth/vue';
export const authClient = createAuthClient();
export const { signIn, signOut } = authClient;
设置客户端后,你可以使用它来验证 Astro 组件或任何位于特定框架下的文件中的用户。以下示例添加了使用配置的 signIn() 和 signOut() 函数以验证登录或注销的功能。
---
import Layout from 'src/layouts/Base.astro';
---
<Layout>
<button id="login">登录</button>
<button id="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 对象以在服务器端代码中获取用户的会话数据。以下示例展示了一种个性化页面内容的方式,它通过显示经过了身份验证的用户名来实现:
---
import { auth } from "../../../lib/auth"; // 导入你的 Better Auth 实例
export const prerender = false; // 'server' 模式下,无需配置
const session = await auth.api.getSession({
headers: Astro.request.headers,
});
---
<p>{session.user?.name}</p>你还可以使用 auth 对象来通过中间件以保护你的路由。以下示例检查了尝试访问登录仪表板路由的用户是否已通过身份验证,如果未通过身份验证,则将其重定向到主页。
import { auth } from "../../../auth"; // 导入你的 Better Auth 实例
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
Clerk 是一套完整的系统,它拥有嵌入式 UI、灵活的 API 以及用于验证和管理用户的仪表盘。Clerk 的官方 Astro SDK 现已推出。
安装
使用你选择的包管理器安装 @clerk/astro。
npm install @clerk/astro
pnpm add @clerk/astro
yarn add @clerk/astro
配置
按照 Clerk 自己的 Astro 快速入门指南 在你的 Astro 项目中设置 Clerk 集成和中间件。
使用方法
Clerk 提供的组件允许你根据用户的身份验证状态控制页面的可见性。向已注销的用户显示登录按钮,而不是向已登录的用户显示可用的内容:
---
import Layout from 'src/layouts/Base.astro';
import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/astro/components';
export const prerender = false; // 'server' 模式下,无需配置
---
<Layout>
<SignedIn>
<UserButton />
</SignedIn>
<SignedOut>
<SignInButton />
</SignedOut>
</Layout>Clerk 还允许你使用中间件以保护服务器上的路由。指定受保护的路由,并提示未经身份验证的用户登录:
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();
}
});下一步
- 阅读 官方
@clerk/astro文档 - 从 Clerk + Astro 快速入门项目 的模板开始
Lucia
Lucia 是一个用于在许多框架(包括 Astro)中实现基于会话的身份验证的资源。
指南
- 使用你选择的数据库创建一个 基本会话 API。
- 使用端点和中间件添加 会话 cookie。
- 使用你创建的 API 实现 GitHub OAuth。
示例
- Astro 中的 GitHub OAuth 示例
- Astro 中的 Google OAuth 示例
- 在 Astro 中使用 2FA 的电子邮件和密码的示例
- 在 Astro 中使用 2FA 和 WebAuthn 的电子邮件和密码的示例