身份验证
身份认证(Authentication)和授权(Authorization)是管理对你网站或应用的访问的两个安全过程。身份认证验证访问者的身份,而授权则授予对受保护区域和资源的访问权限。
身份认证允许你为已登录的用户定制网站的区域,并为个人或私密信息提供最大程度的保护。身份认证库(例如 Auth.js、Clerk)为多种身份认证方法(如电子邮件登录和 OAuth 提供商)提供实用工具。
Astro 没有官方的身份认证解决方案,但你可以在集成目录中找到社区的“auth”集成。
Auth.js
名为“Auth.js”的部分Auth.js 是一个与框架无关的身份认证解决方案。Astro 有一个社区框架适配器 auth-astro
可用。
使用你偏好的包管理器,通过 astro add
命令来添加 auth-astro
集成。
npx astro add auth-astro
pnpm astro add auth-astro
yarn astro add auth-astro
手动安装
名为“手动安装”的部分要手动安装 auth-astro
,请为你的包管理器安装所需的包
npm install auth-astro @auth/core@^0.18.6
pnpm add auth-astro @auth/core@^0.18.6
yarn add auth-astro @auth/core@^0.18.6
然后,使用 integrations
属性将此集成应用到你的 astro.config.*
文件中:
import { defineConfig } from 'astro/config';import auth from 'auth-astro';
export default defineConfig({ // ... integrations: [auth()],});
在你的项目根目录中创建一个 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 个字符的私有字符串。
AUTH_TRUST_HOST=trueAUTH_SECRET=<my-auth-secret>
你可以在脚本标签或客户端框架组件中使用 auth-astro/client
模块来添加登录和登出按钮。
---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
方法来获取用户的会话。
---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
名为“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"; // import your Better Auth instanceimport 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'
导入该辅助函数。
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">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
对象来获取用户的会话数据。下面的例子通过显示已认证用户的姓名来个性化页面内容
---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
对象通过中间件来保护你的路由。下面的例子检查尝试访问已登录仪表板路由的用户是否已认证,如果未认证,则将他们重定向到主页。
import { auth } from "../../../auth"; // import your Better Auth instanceimport { 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”的部分Clerk 是一套完整的可嵌入 UI、灵活的 API 和管理仪表盘,用于对用户进行身份认证和管理。Astro 有一个官方的 Clerk 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; // Not needed in 'server' mode---
<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”的部分Lucia 是一个用于在包括 Astro 在内的多种框架中实现基于会话的身份认证的资源。
- 使用你选择的数据库创建一个基本的会话 API。
- 使用端点和中间件添加会话 cookie。
- 使用你实现的 API 来实现 GitHub OAuth。
- Astro 中的 GitHub OAuth 示例
- Astro 中的 Google OAuth 示例
- Astro 中带 2FA 的电子邮件和密码示例
- Astro 中带 2FA 和 WebAuthn 的电子邮件和密码示例