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

通过 Go SDK 调用扣子编程 OpenAPI 时，需要在请求中配置访问密钥，以进行身份验证和权限校验。扣子编程 OpenAPI 提供了两种鉴权方式：个人访问密钥（PAT）和 OAuth。开发者可以根据当前业务场景选择合适的鉴权方式，并获取相应的访问密钥。

对于 OAuth 授权码等复杂的授权方式，Coze API Go SDK 已经封装了相关的逻辑，并处理了不同的错误返回代码，从而简化开发者的操作。

## 配置方式 {#785bdf2d}

扣子编程 OpenAPI 目前支持的鉴权方式如下。

<!-- @cols-width: 169,173,335,279 -->
|**访问密钥类型** |**鉴权方式** |**说明** |**示例文件** |
|---|---|---|---|
|个人访问密钥 |个人访问密钥 |Personal Access Token，简称 PAT。扣子编程中生成的个人访问令牌。PAT 生成与使用便捷，适用于测试环境调试等场景。每个令牌可以关联多个空间，并开通指定的接口权限。生成方式可参考[添加个人访问令牌](/developer_guides/pat)。 |[pat_example.go](https://github.com/coze-dev/coze-go/blob/main/examples/auth/token/main.go) |
|服务访问令牌（SAT） |服务访问令牌（SAT） |Service Access Token（简称 SAT）是以服务身份创建的访问凭证，可**长期有效**访问扣子编程资源，通常用于服务/应用程序的身份验证和授权。生成方式可参考[添加服务访问令牌](/developer_guides/service_token)。 |\
| | | |\
| | |SAT 的示例代码与 PAT 通用，可直接参考 PAT 的示例文件。 |[pat_example.go](https://github.com/coze-dev/coze-go/blob/main/examples/auth/token/main.go) |
|OAuth 认证 |授权码授权 |\
| | |\
| |（Authorization Code Flow） |适用于有显著前后端之分的应用程序授权场景。其中前端模块负责与用户交互，后端服务处理前端请求，与扣子编程授权服务器和 OpenAPI 交互。 实现流程可参考[OAuth 授权码授权](/developer_guides/oauth_code)。 |[web_oauth_example.go](https://github.com/coze-dev/coze-go/blob/main/examples/auth/web_oauth/main.go) |
|^^| | | | \
| |PKCE 授权 |\
| | |\
| |（Authorization Code Flow with PKCE） |应用程序无后端服务，所有操作都发生在应用程序的前端。 实现流程可参考[OAuth PKCE](/developer_guides/oauth_pkce)。 |[pkce_example.go](https://github.com/coze-dev/coze-go/blob/main/examples/auth/pkce_oauth/main.go) |
|^^| | | | \
| |设备码授权 |\
| | |\
| |（Device Code Flow） |应用程序无后端服务，所有操作都发生在应用程序的 Command Line，且 Command Line 无法提供“同意授权”的操作。 实现流程可参考[OAuth 设备授权](/developer_guides/oauth_device_code)。 |[device_example.go](https://github.com/coze-dev/coze-go/blob/main/examples/auth/device_oauth/main.go) |
|^^| | | | \
| |JWT 授权 |\
| | |\
| |（JWT Flow） |应用程序服务端直接调用扣子编程 OpenAPI。 |\
| | | |\
| | |应用程序后端服务代理应用程序自己的用户获取身份凭据，应用程序用户基于凭据直接访问 OpenAPI。 实现流程可参考[OAuth JWT 授权（开发者）](/developer_guides/oauth_jwt)。 |[jwt_example.go](https://github.com/coze-dev/coze-go/blob/main/examples/auth/jwt_oauth/main.go) |

## 配置个人访问密钥（PAT） {#37ca4042}

如果选择使用个人访问密钥进行鉴权，首先需要申请一个个人访问密钥，并为其添加指定的空间和权限。操作步骤可参考[添加个人访问令牌](/developer_guides/pat)。

建议通过环境变量来管理访问密钥，以避免在代码中硬编码，从而防止密钥泄露和潜在的安全风险。配置环境变量后，你可以在不修改代码的情况下将动态的鉴权参数传递到相应的函数中，从而实现便捷且安全的身份认证。

1. 设置环境变量。
   其中 COZE_API_TOKEN 是扣子编程中申请的个人访问密钥。
   ```Shell
   export COZE_API_TOKEN=pat_****
   ```
2. 初始化客户端。
   示例代码如下：
   ```Go
   func main() {
       // Get an access token using the personal access token or oauth.
       token := os.Getenv("COZE_API_TOKEN")
       authCli := coze.NewTokenAuth(token)
       
       /*
        * The default access is api.coze.com, but if you need to access api.coze.cn
        * please use baseUrl to configure the API endpoint to access
        */
       cozeCli := coze.NewCozeAPI(authCli, coze.WithBaseURL(coze.CozeCnBaseURL))
   }
   ```   


## 配置 OAuth 授权码流程 {#7ee98769}

如果选择使用 OAuth 授权码方式完成授权，可参考以下流程及示例代码。

1. 创建 OAuth 应用。
   具体操作步骤可参考[OAuth 授权码授权](/developer_guides/oauth_code)。成功创建 OAuth 应用后，你将获得客户端 ID、客户端密钥和重定向地址。客户端密钥需要妥善保管，以避免因泄露而导致的安全风险。
2. 在代码中通过环境变量方式设置客户端 ID、客户端密钥和重定向地址。
   ```Go
   //从环境变量获取重定向地址、客户端 ID、客户端密钥
   func main() {
       redirectURI := os.Getenv("COZE_WEB_OAUTH_REDIRECT_URI")  // 重定向地址是创建OAuth应用时配置的回调地址，用户授权后会跳转至此地址
       clientSecret := os.Getenv("COZE_WEB_OAUTH_CLIENT_SECRET")   // 客户端密钥是创建OAuth应用时扣子编程生成的密钥，用于验证应用身份，需妥善保管
       clientID := os.Getenv("COZE_WEB_OAUTH_CLIENT_ID")    // 客户端ID是创建OAuth应用时扣子编程生成的唯一标识，用于区分不同应用
       ctx := context.Background()
   
       // The sdk offers the WebOAuthClient class to establish an authorization for Web OAuth.
       // Firstly, it is required to initialize the WebOAuthApp with the client ID and client secret.
       oauth, err := coze.NewWebOAuthClient(clientID, clientSecret, coze.WithAuthBaseURL(coze.CozeCnBaseURL))
       if err != nil {
          fmt.Printf("Failed to create OAuth client: %v\n", err)
          return
       }
   }
   ```
3. 授权码流程中，会自动生成一个扣子编程授权页面，然后将其发送给需要授权的用户。扣子用户可访问此链接，并根据页面提示完成授权流程。
   ```Go
   // Generate the authorization link and direct the user to open it.
   oauthURL := oauth.GetOAuthURL(ctx, &coze.GetWebOAuthURLReq{
       RedirectURI: redirectURI,
       State:       "state",
   })
   fmt.Println(oauthURL)
   
   // To restrict access to a specific WorkSpace, you can specify the WorkSpaceID when obtaining the URL.
   // oauthURL = oauth.GetOAuthURL(&coze.GetWebOAuthURLReq{
   //  RedirectURI: redirectURI,
   //  State:       "state",
   //  WorkspaceID: &workspaceID,
   // })
   // fmt.Println(oauthURL)
   ```
4. 用户点击同意授权按钮后，扣子网页会将请求重定向到授权链接中配置的重定向地址。此时，地址中会通过查询参数（Query）携带授权码和状态参数。
   通过授权码（OAuth code）调用 GetAccessToken 接口即可获取 OAuth Access Token。示例代码如下：
   ```Go
   // After the user clicks the authorization consent button, the coze web page will redirect
   // to the redirect address configured in the authorization link and carry the authorization
   // code and state parameters in the address via the query string.
   //
   // Get from the query of the redirect interface: query.get('code')
   code := "mock code"
   
   // After obtaining the code after redirection, the interface to exchange the code for a
   // token can be invoked to generate the Coze access_token of the authorized user.
   resp, err := oauth.GetAccessToken(ctx, &coze.GetWebOAuthAccessTokenReq{
       Code:        code,
       RedirectURI: redirectURI,
   })
   if err != nil {
       fmt.Printf("Failed to get access token: %v\n", err)
       return
   }
   fmt.Println(resp)
   
   // When the token expires, you can also refresh and re-obtain the token
   resp, err = oauth.RefreshToken(ctx, resp.RefreshToken)
   if err != nil {
       fmt.Printf("Failed to refresh token: %v\n", err)
       return
   }
   
   fmt.Printf("%+v\n", resp)
   
   // you can get request log by getLogID method
   fmt.Println(resp.LogID())
   
   // use the access token to init Coze client
   cozeCli := coze.NewCozeAPI(coze.NewTokenAuth(resp.AccessToken), coze.WithBaseURL(coze.CozeCnBaseURL))
   _ = cozeCli
   ```   


## 配置 OAuth PKCE 授权流程 {#b5cf99c7}

如果选择使用 OAuth PKCE 方式完成授权，可参考以下流程及示例代码。

1. 创建 OAuth 应用。
   具体操作步骤可参考[OAuth PKCE](/developer_guides/oauth_pkce)。成功创建 OAuth 应用后，你将获得客户端 ID 和重定向地址。
2. 在代码中通过环境变量方式设置客户端 ID 和重定向地址。
   ```Go
   //从环境变量获取重定向地址、客户端 ID
   redirectURI := os.Getenv("COZE_PKCE_OAUTH_REDIRECT_URI") // 重定向地址是创建PKCE类型OAuth应用时配置的前端回调地址
   clientID := os.Getenv("COZE_PKCE_OAUTH_CLIENT_ID") // 客户端ID是创建PKCE类型OAuth应用时扣子编程生成的唯一标识
   
   //
   // The default access is api.coze.com, but if you need to access api.coze.cn,
   // please use base_url to configure the api endpoint to access
   
   oauth, err := coze.NewPKCEOAuthClient(clientID, coze.WithAuthBaseURL(coze.CozeCnBaseURL))
   if err != nil {
       fmt.Printf("Failed to create OAuth client: %v\n", err)
       return
   }
   ```
3. 在代码中实现 OAuth PKCE 授权流程。
   客户端生成一个随机值 `code_verifier`，并使用指定算法（通常为 SHA-256 算法）将其转换为 `code_challenge`。然后，基于回调地址、`code_challenge` 和 `code_challenge_method`，生成一个授权链接。
   在此过程中，`code_verifier` 由 SDK 生成，并与生成的授权链接一同返回给调用方。
   ```Go
   // In the SDK, we have wrapped up the code_challenge process of PKCE.
   // Developers only need to select the code_challenge_method.
   oauthURL, err := oauth.GenOAuthURL(&coze.GetPKCEAuthURLReq{
       RedirectURI: redirectURI,
       State:       "state",
       Method:      coze.CodeChallengeMethodS256.Ptr(),
   })
   if err != nil {
       fmt.Printf("Failed to generate OAuth URL: %v\n", err)
       return
   }
   // URL that users need to click.
   fmt.Println(oauthURL.AuthorizationURL)
   // The code verifier generated by the SDK
   fmt.Println(oauthURL.CodeVerifier)
   
   // Specify the workspaceID to limit the scope of the token
   // oauthURL, err := oauth.GenOAuthURL(&coze.GetPKCEOAuthURLReq{
   //        RedirectURI: redirectURI, State: "state",
   //        Method: coze.CodeChallengeMethodS256.Ptr(),
   //        WorkspaceID: &workspace_id,
   //     })
   // if err != nil {
   //  fmt.Printf("Failed to generate OAuth URL with workspaces: %v\n", err)
   //  return
   // }
   // fmt.Println(oauthURL.AuthorizationURL)
   //  fmt.Println(oauthURL.CodeVerifier)
   ```
4. 完成授权。
   开发者应该引导用户打开生成的授权链接。当用户同意授权时，扣子编程会将页面重定向到开发者配置的回调地址。在这个回调请求中，开发者可以获取到授权码 `code`。
   在获取 `code` 后，为了交换访问令牌，开发者需要调用 `GetAccessToken` 方法。在调用此方法时，需要将之前 SDK 生成的 `code_verifier` 一同作为参数传入。
   ```Go
   // After the user clicks the authorization consent button,
   // the coze web page will redirect to the redirect address configured in the authorization link
   // and carry the authorization code and state parameters in the address via the query string.
   // Get from the query of the redirect interface : query.get('code')
   code := "mock code"
   codeVerifier := oauthURL.CodeVerifier
   // After obtaining the code after redirection, the interface to exchange the code for a
   // token can be invoked to generate the coze access_token of the authorized user.
   // The developer should use code verifier returned by genOAuthURL() method
   resp, err := oauth.GetAccessToken(ctx, &coze.GetPKCEAccessTokenReq{
       Code: code,
       RedirectURI: redirectURI, 
       CodeVerifier: codeVerifier})
   if err != nil {
       fmt.Printf("Failed to get access token: %v\n", err)
       return
   }
   fmt.Printf("%+v\n", resp)
   
   // use the access token to init Coze client
   cozeCli := coze.NewCozeAPI(coze.NewTokenAuth(resp.AccessToken), coze.WithBaseURL(coze.CozeCnBaseURL))
   _ = cozeCli
   
   // When the token expires, you can also refresh and re-obtain the token
   resp, err = oauth.RefreshToken(ctx, resp.RefreshToken)
   if err != nil {
       fmt.Printf("Failed to refresh token: %v\n", err)
       return
   }
   fmt.Println(resp)
   ```   


## 配置 OAuth 设备码授权流程 {#c6dbb16e}

如果选择使用 OAuth 设备码方式完成授权，可参考以下流程及示例代码。

1. 创建 OAuth 应用。
   具体操作步骤可参考[OAuth 设备授权](/developer_guides/oauth_device_code)。成功创建 OAuth 应用后，你将获得客户端 ID。
2. 在代码中通过环境变量方式设置客户端 ID。
   ```Go
   func main() {
       clientID := os.Getenv("COZE_DEVICE_OAUTH_CLIENT_ID")  // 从环境变量获取客户端ID，客户端ID是创建设备码类型OAuth应用时平台生成的唯一标识
   
       // The default access is api.coze.com, but if you need to access api.coze.cn,
       // please use base_url to configure the api endpoint to access
       ctx := context.Background()
   
       oauth, err := coze.NewDeviceOAuthClient(clientID, coze.WithAuthBaseURL(coze.CozeCnBaseURL))
       if err != nil {
          fmt.Printf("Failed to create OAuth client: %v\n", err)
          return
       }
   }
   ```
3. 通过 OAuth 设备码授权流程，可以获得访问密钥。
   应用程序需要调用 扣子编程 OpenAPI 来生成设备代码，获取 `UserCode` 和 `DeviceCode`。使用 `UserCode` 生成授权链接，然后引导用户打开该链接。在页面中，用户需要输入 `UserCode` 并同意授权。用户同意授权后，应用程序再次调用扣子编程 OpenAPI，通过提供的 `DeviceCode` 来生成访问密钥。
   SDK 已经拼接了 URL，只需将 SDK 返回的 URL 交给用户进行操作即可。
   ```Go
   // First, make a call to obtain 'GetDeviceCode'
   
   codeResp, err := oauth.GetDeviceCode(ctx, nil)
   if err != nil {
       fmt.Printf("Failed to get device code: %v\n", err)
       return
   }
   fmt.Printf("%+v\n", codeResp)
   fmt.Println(codeResp.LogID())
   // The returned device_code contains an authorization link. Developers need to guide users
   // to open up this link.
   // open codeResp.getVerificationUri
   
   fmt.Printf("Please open url: %s\n", codeResp.VerificationURL)
   
   // 也可以指定 workspace，限制生效范围
   // codeResp, err = oauth.GetDeviceCode(ctx, &coze.GetDeviceOAuthCodeReq{
   //  WorkspaceID: &workspaceID,
   // })
   ```
4. 在通过设备码授权流程中，应用程序需要使用 `DeviceCode` 来轮询扣子编程 OpenAPI，以获取访问密钥。
   Coze API Go SDK 已经封装了这部分的逻辑，并处理了不同的错误返回代码。开发者只需调用 `GetAccessToken` 方法即可。
   ```Go
   resp, err := oauth.GetAccessToken(ctx, &coze.GetDeviceOAuthAccessTokenReq{
       DeviceCode: codeResp.DeviceCode,
       Poll:       true,
   })
   if err != nil {
       authErr, ok := coze.AsAuthError(err)
       if !ok {
          fmt.Printf("Failed to get access token: %v\n", err)
          return
       }
       switch authErr.Code {
       case coze.AccessDenied:
          // The user rejected the authorization.
          // Developers need to guide the user to open the authorization link again.
          fmt.Println("access denied")
       case coze.ExpiredToken:
          // The token has expired. Developers need to guide the user to open
          // the authorization link again.
          fmt.Println("expired token")
       default:
          fmt.Printf("Unexpected error: %v\n", err)
   
          return
       }
   }
   fmt.Printf("%+v\n", resp)
   ```   


## 配置 OAuth JWT 授权流程 {#619ebbd1}

如果选择使用 OAuth JWT 方式完成授权，可参考以下流程及示例代码。

1. 创建 OAuth 应用并授权。
   具体操作步骤可参考[OAuth JWT 授权（开发者）](/developer_guides/oauth_jwt)。成功创建 OAuth 应用后，你将获得客户端 ID、公钥和私钥。你需要妥善保管公钥和私钥，以免数据泄露引发安全风险。
2. 在代码中通过环境变量方式设置客户端 ID、公钥和私钥。
   ```Go
   // The default access is api.coze.com, but if you need to access api.coze.cn,
   // please use base_url to configure the api endpoint to access
   cozeAPIBase := os.Getenv("COZE_API_BASE")
   jwtOauthClientID := os.Getenv("COZE_JWT_OAUTH_CLIENT_ID") // 从环境变量获取JWT授权的客户端ID，创建JWT类型OAuth应用时平台生成的唯一标识符
   jwtOauthPrivateKey := os.Getenv("COZE_JWT_OAUTH_PRIVATE_KEY") // 从环境变量获取 OAuth 应用的私钥，用于签署JWT，可以在 OAuth 应用页面找到这个应用，在操作列单击编辑图标，进入配置页面下载私钥文件
   jwtOauthPrivateKeyFilePath := os.Getenv("COZE_JWT_OAUTH_PRIVATE_KEY_FILE_PATH")  // 从环境变量获取私钥文件路径，私钥文件在本地的存储路径，开发者自行指定
   jwtOauthPublicKeyID := os.Getenv("COZE_JWT_OAUTH_PUBLIC_KEY_ID")  //OAuth 应用的公钥指纹，可以在 OAuth 应用页面找到这个应用，在操作列单击编辑图标，进入配置页面查看公钥指纹。
   
   // Read private key from file
   privateKeyBytes, err := os.ReadFile(jwtOauthPrivateKeyFilePath)
   if err != nil {
           fmt.Printf("Error reading private key file: %v\n", err)
   }
   jwtOauthPrivateKey = string(privateKeyBytes)
   
   // The jwt oauth type requires using private to be able to issue a jwt token, and through the jwt token,
   // apply for an access_token from the coze service.The sdk encapsulates this procedure,
   // and only needs to use get_access_token to obtain the access_token under the jwt oauth process.
   // Generate the authorization token The default ttl is 900s, and developers can customize the expiration time,
   // which can be set up to 24 hours at most.
   oauth, err := coze.NewJWTOAuthClient(coze.NewJWTOAuthClientParam{
           ClientID: jwtOauthClientID, PublicKey: jwtOauthPublicKeyID, PrivateKeyPEM: jwtOauthPrivateKey,
   }, coze.WithAuthBaseURL(cozeAPIBase))
   if err != nil {
           fmt.Printf("Error creating JWT OAuth client: %v\n", err)
   }
   ```
3. 应用程序通过公钥和私钥签署 JWT，并通过扣子编程提供的 API 获取访问密钥。
   Coze API Go SDK 封装了这一过程，你只需要在OAuth JWT 流程中使用 get_access_token 来获取访问密钥即可。
   ```Go
   resp, err := oauth.GetAccessToken(ctx, nil)
   if err != nil {
           fmt.Printf("Error getting access token: %v\n", err)
           return
   }
   fmt.Printf("Access token response: %+v\n", resp)
   fmt.Println(resp.LogID())
   ```
