跳到主要内容

Google

@mastra/auth-google 包使用 Google Workspace 为 Mastra 提供身份验证和基于角色的访问控制。它支持使用加密会话 Cookie 的 OAuth 2.0 / OIDC 登录流程、验证 Google ID 令牌,并将 Google Workspace 群组映射到 Mastra 权限。

当 Studio 用户使用 Google 登录,并且访问应限制为一个或多个 Google Workspace 域时,请使用此包。

前置条件
前置条件的直接链接

本指南使用 Google Workspace 身份验证。请确保:

  1. 创建或选择 Google Cloud 项目
  2. 为 Web 应用设置 OAuth 客户端
  3. 将 Mastra SSO 回调 URL 添加到已获授权的重定向 URI
  4. 如果计划使用 RBAC,请配置 Google Workspace 群组

对于 Google Groups RBAC,还需配置具有全域委派的 Google Workspace 服务账户,并向其授予 Directory API 只读群组 scope:

https://www.googleapis.com/auth/admin.directory.group.readonly

请确保已设置环境变量。

.env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:4111/api/auth/sso/callback
GOOGLE_COOKIE_PASSWORD=a-random-string-at-least-32-characters-long
GOOGLE_ALLOWED_DOMAINS=example.com

GOOGLE_SERVICE_ACCOUNT_EMAIL=service-account@project.iam.gserviceaccount.com
GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
GOOGLE_WORKSPACE_ADMIN_EMAIL=admin@example.com
备注

GOOGLE_COOKIE_PASSWORD 用于加密会话 Cookie。如果省略,将使用无法在服务器重启后保留的自动生成值。请在生产环境中显式设置。

MastraAuthGoogle 会自动读取 GOOGLE_* 身份验证变量。上述服务账户变量由传递给 MastraRBACGoogle 的配置代码读取。

安装
安装的直接链接

在使用 MastraAuthGoogle 类之前,请安装 @mastra/auth-google 包。

npm install @mastra/auth-google

用法示例
用法示例的直接链接

使用环境变量的基本用法
使用环境变量的基本用法的直接链接

设置上述环境变量后,所有构造函数参数均为可选:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { MastraAuthGoogle } from '@mastra/auth-google'

export const mastra = new Mastra({
server: {
auth: new MastraAuthGoogle(),
},
})
注意

使用 allowedDomainsGOOGLE_ALLOWED_DOMAINS 强制实施 Workspace 访问限制。Mastra 检查的是 Google 已验证的 hd claim,而非电子邮箱地址后缀。

自定义配置
自定义配置的直接链接

如果不想依赖环境变量,请直接传递构造函数选项:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { MastraAuthGoogle } from '@mastra/auth-google'

export const mastra = new Mastra({
server: {
auth: new MastraAuthGoogle({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
redirectUri: process.env.GOOGLE_REDIRECT_URI,
allowedDomains: ['example.com'],
}),
},
})

使用 Google Groups RBAC 进行身份验证
使用 Google Groups RBAC 进行身份验证的直接链接

添加 MastraRBACGoogle,将 Google Workspace 群组映射到 Mastra 权限:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { MastraAuthGoogle, MastraRBACGoogle } from '@mastra/auth-google'

export const mastra = new Mastra({
server: {
auth: new MastraAuthGoogle(),
rbac: new MastraRBACGoogle({
serviceAccount: {
clientEmail: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL!,
privateKey: process.env.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY!,
subject: process.env.GOOGLE_WORKSPACE_ADMIN_EMAIL!,
},
roleMapping: {
'admins@example.com': ['*'],
'engineering@example.com': ['agents:*', 'workflows:*', 'tools:*'],
'viewers@example.com': ['agents:read', 'workflows:read'],
_default: [], // users with unmapped groups get no permissions
},
}),
},
})

跨 Provider 使用
跨 Provider 使用的直接链接

使用其他身份验证 Provider(Auth0、Clerk 等)进行登录,并使用 Google Workspace 群组执行 RBAC。传递 getUserKey 函数,从其他 Provider 的用户对象解析 Google Directory API 用户键:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { MastraAuthAuth0 } from '@mastra/auth-auth0'
import { MastraRBACGoogle } from '@mastra/auth-google'

export const mastra = new Mastra({
server: {
auth: new MastraAuthAuth0(),
rbac: new MastraRBACGoogle({
getUserKey: user => {
if (!user || typeof user !== 'object') return undefined

const { email } = user as { email?: unknown }
return typeof email === 'string' ? email : undefined
},
serviceAccount: {
clientEmail: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL!,
privateKey: process.env.GOOGLE_SERVICE_ACCOUNT_PRIVATE_KEY!,
subject: process.env.GOOGLE_WORKSPACE_ADMIN_EMAIL!,
},
roleMapping: {
'engineering@example.com': ['agents:*', 'workflows:*'],
'admins@example.com': ['*'],
_default: [],
},
}),
},
})

有关所有可用配置选项,请参阅 MastraAuthGoogle

角色映射
角色映射的直接链接

roleMapping 选项将 Google Workspace 群组电子邮箱地址映射到 Mastra 权限字符串数组。权限遵循 resource:action 模式并支持通配符:

const rbac = new MastraRBACGoogle({
roleMapping: {
// full access to everything
'admins@example.com': ['*'],

// full access to agents and workflows
'engineering@example.com': ['agents:*', 'workflows:*'],

// read-only access
'viewers@example.com': ['agents:read', 'workflows:read'],

// users whose groups don't match any key above
_default: [],
},
})

默认使用群组电子邮箱地址作为角色 ID。如果要按群组名称或其他属性映射,请使用 mapGroupToRoles_default 键为 Google Workspace 群组与其他任何键都不匹配的用户分配权限。

客户端设置
客户端设置的直接链接

启用身份验证后,对 Mastra 路由的请求需要身份验证。使用 GOOGLE_CLIENT_SECRET 启用 SSO 后,MastraAuthGoogle 使用 Google 登录,并在登录后设置加密的会话 Cookie。

对于跨域请求(例如 :3000 上的前端调用 :4111 上的 Mastra),请在 Mastra 服务器上启用 CORS 凭据:

src/mastra/index.ts
export const mastra = new Mastra({
server: {
auth: new MastraAuthGoogle(),
cors: {
origin: 'http://localhost:3000',
credentials: true,
},
},
})

配置客户端以包含凭据:

lib/mastra-client.ts
import { MastraClient } from '@mastra/client-js'

export const mastraClient = new MastraClient({
baseUrl: 'http://localhost:4111',
credentials: 'include',
})

Bearer 令牌
Bearer 令牌的直接链接

也可以将 Google ID 令牌作为 Bearer 令牌传递。Mastra 会根据 Google 的 JSON Web Key Set (JWKS) 端点验证该令牌:

lib/mastra-client.ts
import { MastraClient } from '@mastra/client-js'

export const createMastraClient = (idToken: string) => {
return new MastraClient({
baseUrl: 'http://localhost:4111',
headers: {
Authorization: `Bearer ${idToken}`,
},
})
}

有关更多配置选项,请参阅 Mastra Client SDK

发出经过身份验证的请求
发出经过身份验证的请求的直接链接

src/api/agents.ts
import { mastraClient } from '../lib/mastra-client'

const agent = mastraClient.getAgent('weatherAgent')
const response = await agent.generate('Weather in London')
console.log(response)

故障排除
故障排除的直接链接

  • 登录后返回 401:检查 GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGOOGLE_REDIRECT_URI 是否与 Google Cloud OAuth 客户端匹配。
  • Workspace 用户被拒绝:验证 GOOGLE_ALLOWED_DOMAINS 是否与 Google ID 令牌的 hd claim 匹配。
  • 个人 Gmail 账户被拒绝:配置 allowedDomains 后,这是预期行为,因为 Gmail 账户没有 Workspace hd claim。
  • RBAC 返回默认权限:未能为用户解析角色。请验证用户电子邮箱或自定义 getUserKey、Google 群组成员资格和 roleMapping。如果 Directory API 查询失败,Provider 会抛出错误,而非返回 _default
  • 未跨域发送 Cookie:在 MastraClient 中设置 credentials: "include",并使用前端来源和 credentials: true 配置 server.cors
  • 重启后会话丢失:将 GOOGLE_COOKIE_PASSWORD 设置为至少 32 个字符的稳定值。否则,开发环境会使用自动生成的密钥,并在每次重启时更改。