> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 获取你的 Chrome Web Store 凭据

> 注册 5 美元的 Chrome Web Store 开发者账号，手动创建第一个商品，并生成自动化提交所需的 OAuth 或服务账号凭据。

自动化提交到 Chrome Web Store 需要两个标识符和一组凭据：

| 值                    | 长什么样                                              | 从哪里来                                                        |
| -------------------- | ------------------------------------------------- | ----------------------------------------------------------- |
| Extension ID         | 32 个小写字母，例如 `abcdefghijklmnopabcdefghijklmnop`    | 第一次手动上传之后，开发者后台里该商品的 URL                                    |
| Publisher ID         | 一个 UUID，例如 `f1e2d3c4-0000-4000-8000-a1b2c3d4e5f6` | 你的开发者控制台 URL：`chrome.google.com/webstore/devconsole/<UUID>` |
| OAuth client ID      | 以 `.apps.googleusercontent.com` 结尾                | Google Cloud Console 的凭据页面                                  |
| OAuth client secret  | 以 `GOCSPX-` 开头                                    | 与 client ID 一起生成                                            |
| OAuth refresh token  | 以 `1//` 开头                                        | 针对该 client ID 生成，见下文                                        |
| Service account JSON | 一个 JSON 密钥文件                                      | Google Cloud Console，OAuth 三件套的替代方案                         |

你只需要 OAuth 三件套或服务账号其中之一，不需要两者都配。两者都配置时，服务账号优先。

## 前置条件

<Warning>
  Chrome Web Store API 无法创建新商品。一个新扩展的第一次上传必须在开发者后台
  （Developer Dashboard）里手动完成。那 32 个字符的 extension ID 只有在那次上传
  之后才存在。
</Warning>

1. 在 [Chrome Web Store 开发者后台](https://chrome.google.com/webstore/devconsole)
   注册一个开发者账号。注册需要一次性支付 5 美元。
2. 构建一个商店 zip（`npx extension build --browser chrome --zip`）。
3. 在后台里手动上传这个 zip，以创建该商品。
4. 从商品的后台 URL 中复制 extension ID。
5. 复制 publisher ID：它就是你的开发者控制台 URL
   `chrome.google.com/webstore/devconsole/<UUID>` 里的那个 UUID。

Extension.js 不会替你提交到任何商店，因此它从来不会向你索要这些值。
本页讲的是手动路径：自己创建 OAuth 客户端，自己生成 refresh token。

<Note>
  不要用 Google OAuth Playground 来生成 refresh token。Playground 需要一个 Web
  application 类型的客户端及其重定向 URI，而 Chrome Web Store 的流程需要
  Desktop app 类型的客户端。把两者凑在一起会以 `redirect_uri_mismatch` 失败。
</Note>

## 创建 OAuth 客户端

1. 在 [Google Cloud Console](https://console.cloud.google.com) 中创建或选择一个项目。
2. 为该项目启用
   [Chrome Web Store API](https://console.cloud.google.com/apis/library/chromewebstore.googleapis.com)。
3. 在[凭据页面](https://console.cloud.google.com/apis/credentials)创建一个
   OAuth client ID，应用类型选 **Desktop app**（桌面应用）。Web application
   类型的客户端在这里不管用。
4. 复制 client ID 和 client secret。
5. 用 `127.0.0.1` 上的本地回环授权流程为该客户端生成一个 refresh token，
   这正是 Desktop app 类型客户端所接受的重定向。该令牌必须获得
   `https://www.googleapis.com/auth/chromewebstore` 这个 scope 的授权。
   使用服务账号可以跳过这一步，下一节会讲到。

<Warning>
  如果你的 OAuth 同意屏幕还处于 **Testing**（测试）状态，Google 会在 7 天后
  吊销 refresh token。你的第一次提交能成功，而这份凭据一周后就失效了。请把同意
  屏幕发布出去（In production），或者改用服务账号，服务账号没有这种过期问题。
</Warning>

## 备选方案：服务账号

Google Cloud 的服务账号完全绕开了 OAuth 授权同意，是 CI 场景下最稳定的选择：

1. 在 Google Cloud Console 中，于那个已启用 Chrome Web Store API 的同一个项目里
   创建一个服务账号。
2. 为它创建一个 JSON 密钥并下载该文件。
3. 在 Chrome Web Store 开发者控制台中打开 **Account**（账号），把这个服务账号的
   邮箱地址添加到你的发布者账号下。一个发布者账号对应一个服务账号。

把 JSON 密钥的内容（或指向该文件的路径）作为凭据提供。配置了服务账号时，
它优先于 OAuth 三件套。

## 影响范围与轮换

<Warning>
  Chrome 凭据是发布者账号级别的，而不是按扩展划分的。一个能发布某个商品的令牌，
  也能发布同一个发布者账号下的每一个商品。请据此对待 refresh token 和服务账号
  密钥；如果你在为别人管理扩展，最好为每个客户使用一个独立的发布者账号。
</Warning>

要轮换凭据，就生成一个新的 refresh token 或新的服务账号密钥，并在存放它的地方
重新填入。

## 名称对照

每个值对应的环境变量：

| 值                    | 环境变量                          |
| -------------------- | ----------------------------- |
| OAuth client ID      | `CHROME_CLIENT_ID`            |
| OAuth client secret  | `CHROME_CLIENT_SECRET`        |
| Refresh token        | `CHROME_REFRESH_TOKEN`        |
| Service account JSON | `CHROME_SERVICE_ACCOUNT_JSON` |
| Extension ID         | `CHROME_EXTENSION_ID`         |
| Publisher ID         | `CHROME_PUBLISHER_ID`         |

## 商品页元数据仍然要手动填

Chrome Web Store API 不接受任何商品页元数据。商店文案、截图和权限说明都要在开发者
后台里手动填写。把它们放在 [STORE.md](/docs/workflows/store-metadata) 的 Chrome
小节里，这样每次重新提交都从同一份纳入版本控制的来源复制。
