---
title: "注册第一个客户端 | FoxAuth"
description: "控制台中的组、项目和客户端，公开与机密客户端的区别，以及客户端为哪些用户提供登录。"
canonical: "https://foxauth.dev/zh-cn/docs/get-started/first-client/"
lastmod: "2026-10-12T23:12:26+03:00"
---
注册第一个客户端

客户端是向本服务器请求令牌的应用。客户端位于项目之中，项目归属于组，而项目指向一个用户桶，其中的客户端从该用户桶登录用户。这是四个概念，但它们层层嵌套，所以控制台会按顺序依次引导你。

组、项目、用户桶Section titled “组、项目、用户桶”

组拥有资源。每个项目和每个用户桶都有一个所属组，属于该组就是获得其访问权限的方式，不存在单独的具名管理者列表。每个管理员都已经有一个 Personal（个人）组，通常很适合用来放第一个客户端；regular（常规）组则对应公司，或你与同事共享的团队。

项目是属于同一个应用或同一个产品的一组客户端，外加其用户所来自的用户桶。

用户桶是一群最终用户：他们的账户，以及他们如何注册和验证身份的策略。你创建的用户桶同时也是一个拥有自己的签发者（issuer）的租户——它在 <ISSUER>/<slug> 下或在自己的主机名下提供服务，签发的令牌也带有这个签发者，因此指向它的项目中的客户端要对接这个地址，而不是不带路径的根地址。默认的 redfox 用户桶是例外：它沿用不带路径的签发者，正因如此，现有部署才能保持原样。

选择组。创建项目或用户桶的对话框会询问它归入哪个组，默认是控制台顶部选中的那个组。第一个客户端放在你的 Personal 组里就可以，但该组只有你一个成员，所以需要与他人共享的工作应放在常规组中：在 Groups 下创建一个，或者以后再把工作移过去。

在 Buckets 下创建用户桶，除非你想使用默认的 redfox 用户桶。它需要一个名称和一个地址：一个路径（会成为其令牌中签发者的最后一部分），或者一个独立的主机名。请慎重选择：签发者标识符是对每个按它配置的客户端作出的承诺，以后更改地址会影响使用该用户桶的每个应用，因此会先预览影响并要求确认。新用户桶默认不开放注册，除非你选择 Anyone who can reach the sign-in page；以后可以在它的 Sign-in 标签页上更改。

Buckets 表在 Address 列中显示每个用户桶的地址。保留的用户桶在这一列显示的是 served at the root（在根路径提供服务），而不是路径，因为它们沿用不带路径的签发者。

在 Projects 下创建项目。它需要一个名称、一个 slug（小写字母、数字和连字符），以及一个 Bucket，从该组的用户桶中选择——选上一步创建的那个。留空即表示使用默认的 redfox 用户桶，显示为 Default bucket；它不属于任何组，因此永远不会出现在列表中。以后可以通过 Change bucket… 或在项目的 Settings 标签页上更改。如果已经有人通过该项目的应用登录过，控制台会先预览影响并请你确认，因为这些人需要重新登录。

在项目的 Clients 下创建客户端。选择应用类型和令牌端点认证方式，然后填写重定向 URI。下一节讨论的正是这个选择。

项目的客户端：生成的 client id、应用类型，以及决定其是否拥有密钥的令牌端点认证方式。

公开客户端还是机密客户端Section titled “公开客户端还是机密客户端”

这个选择就是令牌端点认证方式，它取决于你的应用能否保守密钥：

方式
适用于
凭据

none（公开 / PKCE）
浏览器 SPA、移动和桌面应用、CLI：任何交付到用户手中的程序
无。PKCE 就是证明。

client_secret_basic
服务端 Web 应用和后端服务
一个密钥，通过 Authorization 请求头发送

client_secret_post
同上，但客户端库只能把凭据放在表单正文中
一个密钥，作为表单字段发送

在这里，无论哪种客户端，PKCE 都不是可选的。每个 response_type=code 的授权请求如果没有 code_challenge 都会被拒绝，而 S256 是唯一接受的方法。携带 plain 的请求会被拒绝，发现文档也只公布 S256。因此，没有密钥的公开客户端并不是更弱的客户端；它收到的授权码对没有生成 verifier 的人毫无用处。

密钥只显示一次

创建机密客户端时，或在客户端表中轮换其密钥时，密钥值会出现在一个对话框中，提示 “Copy this secret now — it will not be shown again.”（立即复制此密钥——它不会再次显示。）之后无法找回。唯一的补救办法是轮换，这会使旧密钥失效。

重定向 URI 精确匹配Section titled “重定向 URI 精确匹配”

重定向 URI 必须事先注册，请求中的 redirect_uri 会与已注册的集合按原样比较：scheme、主机、端口、路径和查询字符串都必须一致。https://app.example.com/cb 和 https://app.example.com/cb/ 是两个不同的 URI。

只有一处例外，也就是 RFC 8252 §7.3 所要求的那一处：应用类型为 native 的客户端，重定向到回环主机上的 http: 地址时，可以使用任意端口。其余部分仍须精确匹配。这个例外是刻意收窄的：

仅限 native 客户端；Web 客户端的重定向目标是它所控制的真实主机，没有任何部分是临时的；

仅限回环主机上的 http:；claimed https 重定向或私有 scheme 重定向仍须精确匹配；

并且 localhost 和 127.0.0.1 不被视为可以互换。如果你的客户端可能用到其中任何一种，就把两种形式都注册上。

仍然存在的是本地端口竞争：用户机器上的另一个进程可能抢先绑定该端口并收到授权码。PKCE 堵住了这个漏洞，这也是它被强制要求的原因。

客户端为哪些用户提供登录Section titled “客户端为哪些用户提供登录”

登录路由由客户端所属的项目决定，而绝不由客户端本身决定：

保留的控制台客户端总是进入管理员用户桶；

分配给某个项目的客户端进入该项目的用户桶；

在某个用户桶的地址（其 /reg）动态注册的客户端属于该用户桶；

其他情况（未分配的客户端，或在根地址注册的客户端）进入默认的 redfox 用户桶。

所以没有项目的客户端会从默认用户桶登录用户，这通常不是你想要的。请为项目设置用户桶。

用户桶也是注册引导策略所在之处：是否开放注册（registrationOpen）、新账户是否必须验证电子邮件（emailVerificationRequired）、验证是通过链接还是六位数验证码（verificationMethod）、是否提供密码登录（passwordLogin），以及是否要求使用身份验证器应用（totpRequired）。这些都不在客户端上设置。同一项目中的两个客户端共享全部这些设置，因为它们共享同一批账户。

注意

授权同意默认开启（新客户端的 consent.require 默认为 true），因此第一次授权请求会显示授权同意页面。保留的控制台客户端是例外：它是第一方客户端，会跳过这一步。

下一步：获取你的第一个令牌。

上一页创建第一个管理员下一页获取第一个令牌
