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

# 添加自定义身份验证

本指南将展示如何为您的 LangSmith 应用添加自定义身份验证。本页的步骤适用于 [云端](/langsmith/cloud) 和 [自托管](/langsmith/self-hosted) 两种部署方式。它不适用于在您自己的自定义服务器中独立使用 [LangGraph 开源库](/oss/python/langgraph/overview) 的情况。

## 为您的部署添加自定义身份验证

为了在部署中利用自定义身份验证并访问用户级别的元数据，请设置自定义身份验证，通过自定义身份验证处理程序自动填充 `config["configurable"]["langgraph_auth_user"]` 对象。然后，您可以在您的图中使用 `langgraph_auth_user` 键访问此对象，以 [允许代理代表用户执行经过身份验证的操作](#enable-agent-authentication)。

1. 实现身份验证：

   <Note>
     如果没有自定义的 `@auth.authenticate` 处理程序，LangGraph 只能看到 API 密钥的所有者（通常是开发者），因此请求不会限定在单个最终用户。要传播自定义令牌，您必须实现自己的处理程序。
   </Note>

   ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
   from langgraph_sdk import Auth
   import requests

   auth = Auth()

   def is_valid_key(api_key: str) -> bool:
       is_valid = # 您的 API 密钥验证逻辑
       return is_valid

   @auth.authenticate # (1)!
   async def authenticate(headers: dict) -> Auth.types.MinimalUserDict:
       api_key = headers.get(b"x-api-key")
       if not api_key or not is_valid_key(api_key):
           raise Auth.exceptions.HTTPException(status_code=401, detail="Invalid API key")

       # 从您的密钥存储中获取用户特定的令牌
       user_tokens = await fetch_user_tokens(api_key)

       return { # (2)!
           "identity": api_key,  # 从 LangSmith 获取用户 ID
           "github_token" : user_tokens.github_token
           "jira_token" : user_tokens.jira_token
           # ... 在此处添加自定义字段/密钥
       }
   ```

* 此处理程序接收请求（请求头等），验证用户，并返回一个至少包含 `identity` 字段的字典。
* 您可以添加任何您想要的自定义字段（例如，OAuth 令牌、角色、组织 ID 等）。

2. 在您的 [`langgraph.json`](/langsmith/application-structure#configuration-file) 文件中，添加身份验证文件的路径：

   ```json highlight={7-9} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
   {
       "dependencies": ["."],
       "graphs": {
       "agent": "./agent.py:graph"
       },
       "env": ".env",
       "auth": {
           "path": "./auth.py:my_auth"
       }
   }
   ```
3. 在服务器中设置好身份验证后，请求必须根据您选择的方案包含所需的授权信息。假设您使用的是 JWT 令牌身份验证，您可以使用以下任一方法访问您的部署：

   <Tabs>
     <Tab title="Python 客户端">
       ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
       from langgraph_sdk import get_client

       my_token = "your-token" # 实际应用中，您将使用您的身份验证提供者生成一个签名令牌
       client = get_client(
           url="http://localhost:2024",
           headers={"Authorization": f"Bearer {my_token}"}
       )
       threads = await client.threads.search()
       ```
     </Tab>

     <Tab title="Python RemoteGraph">
       ```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
       from langgraph.pregel.remote import RemoteGraph

       my_token = "your-token" # 实际应用中，您将使用您的身份验证提供者生成一个签名令牌
       remote-graph = RemoteGraph(
           "agent",
           url="http://localhost:2024",
           headers={"Authorization": f"Bearer {my_token}"}
       )
       threads = await remote-graph.ainvoke(...)
       ```
     </Tab>

     <Tab title="JavaScript 客户端">
       ```javascript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
       import { Client } from "@langchain/langgraph-sdk";

       const my_token = "your-token"; // 实际应用中，您将使用您的身份验证提供者生成一个签名令牌
       const client = new Client({
       apiUrl: "http://localhost:2024",
       defaultHeaders: { Authorization: `Bearer ${my_token}` },
       });
       const threads = await client.threads.search();
       ```
     </Tab>

     <Tab title="JavaScript RemoteGraph">
       ```javascript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
       import { RemoteGraph } from "@langchain/langgraph/remote";

       const my_token = "your-token"; // 实际应用中，您将使用您的身份验证提供者生成一个签名令牌
       const remoteGraph = new RemoteGraph({
       graphId: "agent",
       url: "http://localhost:2024",
       headers: { Authorization: `Bearer ${my_token}` },
       });
       const threads = await remoteGraph.invoke(...);
       ```
     </Tab>

     <Tab title="CURL">
       ```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
       curl -H "Authorization: Bearer ${your-token}" http://localhost:2024/threads
       ```
     </Tab>
   </Tabs>

   有关 RemoteGraph 的更多详细信息，请参阅 [使用 RemoteGraph](/langsmith/use-remote-graph) 指南。

## 启用代理身份验证

在 [身份验证](#add-custom-authentication-to-your-deployment) 之后，平台会创建一个特殊的配置对象 (`config`)，该对象会传递给 LangSmith 部署。此对象包含有关当前用户的信息，包括您从 `@auth.authenticate` 处理程序返回的任何自定义字段。

要允许代理代表用户执行经过身份验证的操作，请在您的图中使用 `langgraph_auth_user` 键访问此对象：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
def my_node(state, config):
    user_config = config["configurable"].get("langgraph_auth_user")
    # 令牌在 @auth.authenticate 函数中解析
    token = user_config.get("github_token","")
    ...
```

<Note>
  请从安全的密钥存储中获取用户凭据。不建议将密钥存储在图状态中。
</Note>

### 为 Studio 用户授权

默认情况下，如果您为资源添加了自定义授权，这也将适用于从 [Studio](/langsmith/studio) 进行的交互。如果需要，您可以通过检查 [is\_studio\_user()](https://langchain-ai.github.io/langgraph/cloud/reference/sdk/python_sdk_ref/#langgraph_sdk.auth.types.StudioUser) 来区别处理已登录的 Studio 用户。

<Note>
  `is_studio_user` 是在 langgraph-sdk 的 0.1.73 版本中添加的。如果您使用的是旧版本，仍然可以通过检查 `isinstance(ctx.user, StudioUser)` 来实现。
</Note>

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langgraph_sdk.auth import is_studio_user, Auth
auth = Auth()

# ... 设置 authenticate 等。

@auth.on
async def add_owner(
    ctx: Auth.types.AuthContext,
    value: dict  # 发送到此访问方法的负载
) -> dict:  # 返回一个限制资源访问的过滤器字典
    if is_studio_user(ctx.user):
        return {}

    filters = {"owner": ctx.user.identity}
    metadata = value.setdefault("metadata", {})
    metadata.update(filters)
    return filters
```

仅当您希望允许开发者访问托管在 LangSmith SaaS 上的图时，才使用此方法。

## 了解更多

* [身份验证与访问控制](/langsmith/auth)
* [设置自定义身份验证教程](/langsmith/set-up-custom-auth)

***

<div className="source-links">
  <Callout icon="edit">
    [Edit this page on GitHub](https://github.com/langchain-ai/docs/edit/main/src/i18n\zh-CN\langsmith\custom-auth.mdx) or [file an issue](https://github.com/langchain-ai/docs/issues/new/choose).
  </Callout>

  <Callout icon="terminal-2">
    [Connect these docs](/use-these-docs) to Claude, VSCode, and more via MCP for real-time answers.
  </Callout>
</div>
