- 数据工程
- 数据湖
- 大数据
- 对象存储
- 后端
【免费下载链接】lakeFS
lakeFS - Data version control for your data lake | Git for data
本篇技术指南聚焦 lakeFS Python SDK(lakefs_sdk)中的核心认证数据模型AuthenticationToken——它是 lakeFS 服务端在登录成功后返回的 JWT(JSON Web Token)认证令牌载体。文章将完整讲解该模型的字段结构、JSON 序列化与反序列化方法、与AuthApi.login等登录接口的联动关系,并结合仓库源码揭示 JWT 令牌在服务端的生成与校验原理,帮助读者在基于 lakeFS 的 Python 应用中正确获取、解析与使用登录令牌完成 API 鉴权。
一、模型概述:什么是 AuthenticationToken
AuthenticationToken是 lakeFS HTTP API(OpenAPI 版本 1.0.0)定义的一个响应数据模型,在 Python SDK 中对应lakefs_sdk.models.authentication_token模块下的同名 Pydantic 模型类。它承载了用户通过认证后由服务端签发的一次性 JWT 登录令牌,是后续所有需要鉴权的 lakeFS API 调用的凭证来源。
从仓库中的 OpenAPI 规范定义(api/swagger.yml)可以看到,该模型的 JSON Schema 如下:
AuthenticationToken: type: object required: - token properties: token: description: a JWT token that could be used to authenticate requests type: string token_expiration: type: integer format: int64 description: Unix Epoch in seconds其中token为必填字段,token_expiration为可选的过期时间戳。该 Schema 由 OpenAPI Generator 生成到 Go 服务端与各语言客户端中,例如服务端生成的 Go 类型位于 pkg/api/apigen/lakefs.gen.go,与 Python 端定义完全对应。
字段属性详解
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
token | str | 是 | 可用于认证请求的 JWT 令牌字符串,通常以Authorization: Bearer <token>形式携带 |
token_expiration | int | 否 | 令牌过期时间,单位为 Unix Epoch 秒(即自 1970-01-01 UTC 起的秒数) |
Pydantic 模型实现
Python SDK 中的模型类定义位于 clients/python/lakefs_sdk/models/authentication_token.py,核心代码如下:
class AuthenticationToken(BaseModel): """ AuthenticationToken """ token: StrictStr = Field(..., description="a JWT token that could be used to authenticate requests") token_expiration: Optional[StrictInt] = Field(None, description="Unix Epoch in seconds") __properties = ["token", "token_expiration"] class Config: """Pydantic configuration""" allow_population_by_field_name = True validate_assignment = True从实现细节可以看出三点关键设计:
- 字段类型约束:
token使用StrictStr强制要求字符串类型,token_expiration使用Optional[StrictInt]表示可选的严格整数(Unix 时间戳),若传入非整数类型会触发 Pydantic 校验错误; allow_population_by_field_name = True:允许在构造对象时直接使用字段名(如token=...),便于与 API 响应中的 JSON 键名保持一致;validate_assignment = True:开启赋值时校验,即使对象已创建,后续对属性的赋值也会再次校验类型。
该模型类在 clients/python/lakefs_sdk/init.py 中被导出,因此可直接通过lakefs_sdk.AuthenticationToken引用。
二、JSON 序列化与反序列化:模型转换方法解析
AuthenticationToken提供了四个核心转换方法,覆盖了与 JSON 字符串、Python 字典之间的双向转换,这是使用任何 lakeFS SDK 模型的基础能力。
| 方法 | 作用 |
|---|---|
to_json() | 将模型实例序列化为 JSON 字符串(内部基于to_dict()) |
from_json(json_str) | 从 JSON 字符串创建模型实例(内部先json.loads再from_dict) |
to_dict() | 将模型实例转换为 Python 字典 |
from_dict(obj) | 从 Python 字典创建模型实例 |
to_str() | 返回模型的pprint格式化字符串表示(便于调试输出) |
以下代码演示了完整的双向转换流程(基于原文档示例修正并补齐):
from lakefs_sdk.models.authentication_token import AuthenticationToken # 1. 从 JSON 字符串创建实例 json = '{"token": "eyJhbGciOiJIUzI1NiIs...", "token_expiration": 1730000000}' authentication_token_instance = AuthenticationToken.from_json(json) # 2. 打印 JSON 字符串表示 print(authentication_token_instance.to_json()) # 3. 转换为 dict authentication_token_dict = authentication_token_instance.to_dict() # 4. 从 dict 重新创建实例 authentication_token_form_dict = AuthenticationToken.from_dict(authentication_token_dict) # 5. 直接访问字段 print(authentication_token_instance.token) print(authentication_token_instance.token_expiration)从源码实现(clients/python/lakefs_sdk/models/authentication_token.py)可以看到,from_dict内部调用parse_obj完成 Pydantic 解析与类型校验,并将 JSON 中的token、token_expiration键一一映射到模型字段。
注意:原文档示例第 21 行存在笔误(print AuthenticationToken.to_json()缺少实例化对象且未加括号),实际使用应写作print(authentication_token_instance.to_json())。
三、令牌从哪里来:login 接口与 AuthApi 联动
AuthenticationToken并非客户端自行构造的请求体,而是登录接口的响应模型。在 lakeFS API 中,以下三个登录端点都以它为 200 响应体:
| 端点 | 说明 |
|---|---|
POST /auth/login | 使用 access key 执行登录(见 api/swagger.yml) |
POST /auth/external/principal/login | 使用外部认证器执行登录(见 api/swagger.yml) |
POST /sts/login | 使用 STS 临时凭证执行登录(见 api/swagger.yml) |
其中POST /auth/login在 Python SDK 中对应AuthApi.login(),返回类型正是AuthenticationToken(见 clients/python/lakefs_sdk/api/auth_api.py),其 HTTP 调用细节为POST /auth/login,响应类型映射为'200': "AuthenticationToken"(同文件 auth_api.py)。
完整登录实战示例
import lakefs_sdk from lakefs_sdk.rest import ApiException from pprint import pprint # 配置 lakeFS 服务端地址(默认 /api/v1) configuration = lakefs_sdk.Configuration(host="https://lakefs.example.com") # 创建 API client 并调用登录接口 with lakefs_sdk.ApiClient(configuration) as api_client: api_instance = lakefs_sdk.AuthApi(api_client) # 登录信息:access key id + secret access key login_info = lakefs_sdk.LoginInformation( access_key_id="YOUR_ACCESS_KEY_ID", secret_access_key="YOUR_SECRET_ACCESS_KEY", ) try: # 执行登录,返回 AuthenticationToken 实例 auth_token: lakefs_sdk.AuthenticationToken = api_instance.login(login_info) print("JWT token:") pprint(auth_token.token) print("Token expiration (Unix Epoch seconds):") pprint(auth_token.token_expiration) except ApiException as e: print("Exception when calling AuthApi->login: %s\n" % e)请求体LoginInformation模型同样定义于仓库中(clients/python/lakefs_sdk/models/login_information.py),其两个必填字段access_key_id与secret_access_key对应 api/swagger.yml 中的定义。用户凭证可通过AuthApi.create_credentials(user_id)创建(返回CredentialsWithSecret)。
四、拿到令牌之后:三种鉴权方式的配置
获取AuthenticationToken后,最典型的用法是将其token配置到 SDK 中,使后续所有 API 调用携带该 JWT。从 clients/python/lakefs_sdk/configuration.py 的auth_settings()方法可以看到,lakeFS Python SDK 支持三种鉴权方式:
| 鉴权方式 | 配置入口 | 实际携带的请求头 |
|---|---|---|
basic_auth(HTTP Basic) | Configuration(username=..., password=...) | Authorization: Basic <base64> |
jwt_token(Bearer JWT) | Configuration(access_token=...) | Authorization: Bearer <JWT> |
cookie_auth(Cookie 会话) | configuration.api_key['cookie_auth'] = ... | Cookie:internal_auth_session=<token> |
以登录返回的 JWT 配置后续请求:
import os import lakefs_sdk # 使用登录返回的 token 作为 Bearer JWT configuration = lakefs_sdk.Configuration( access_token=auth_token.token, # 即 AuthenticationToken.token host="https://lakefs.example.com", ) with lakefs_sdk.ApiClient(configuration) as api_client: api_instance = lakefs_sdk.AuthApi(api_client) # 此时调用任意鉴权接口都会自动携带 Authorization: Bearer <token> current_user = api_instance.get_current_user() pprint(current_user)token_expiration字段在此时可用于判断令牌何时过期:将其与当前时间(int(time.time()))比较,若已过期则需重新调用login()获取新令牌,避免请求返回 401 Unauthorized。
五、服务端原理:JWT 的生成、内容与校验
要真正理解AuthenticationToken,需要了解其token字段在服务端是如何产生的。lakeFS 服务端的登录处理流程位于 pkg/api/controller.go,核心逻辑如下:
loginTime := time.Now() duration := c.Config.AuthConfig().GetBaseAuthConfig().LoginDuration expires := loginTime.Add(duration) secret := c.Auth.SecretStore().SharedSecret() tokenString, err := auth.GenerateJWTLogin(secret, user.Username, loginTime, expires) // ... response := apigen.AuthenticationToken{ Token: tokenString, TokenExpiration: swag.Int64(expires.Unix()), }即:token_expiration就是服务端计算出的expires.Unix(),直接取自 JWT 的过期时间,二者天然一致。登录令牌的默认有效期由配置项auth.login_duration控制,默认值为7 天(见 pkg/config/defaults.go)。
JWT 的生成实现位于 pkg/auth/token.go,采用HS256签名算法(jwt.SigningMethodHS256),载荷包含以下声明:
| 声明 | JSON 键 | 含义 |
|---|---|---|
Issuer | iss | 固定为"auth" |
ID | jti | UUID,用于唯一标识该令牌 |
Audience | aud | 固定为"login"(LoginAudience常量) |
Subject | sub | 登录用户的用户名 |
IssuedAt | iat | 签发时间 |
ExpiresAt | exp | 过期时间 |
服务端校验逻辑(pkg/auth/token.go)同样严格:要求必须携带过期时间(jwt.WithExpirationRequired()),仅接受 HS256/HS384/HS512 签名方法,且 audience 必须为login或为空(向后兼容)。对应的 Go 单元测试见 pkg/auth/token_test.go,覆盖了过期令牌拒绝、错误签名方法拒绝、audience 校验等场景;此外 pkg/api/controller_test.go 还验证了登录令牌的实际有效期与login_duration配置一致(误差不超过 1 分钟)。
六、SDK 集成验证:测试与文档索引
仓库为AuthenticationToken提供了对应的单元测试骨架 clients/python/test/test_authentication_token.py,其中make_instance(include_optional)展示了两种构造形态:仅必填字段(token = '')与包含可选字段(token_expiration = 56),可用于快速验证模型行为。
此外,Python SDK 的完整模型与接口文档见 clients/python/README.md,其中AuthApi的完整端点列表(login、external_principal_login、create_credentials、get_current_user等)见 clients/python/docs/AuthApi.md,所有端点的 200 响应类型均为AuthenticationToken。相关辅助模型文档包括 LoginInformation 对应文档 中所述请求体,以及服务端 OpenAPI 规范 api/swagger.yml。
七、常见问题与注意事项
- 令牌过期:
token_expiration为可选字段,若服务端配置了令牌 TTL 则会返回;客户端应在过期前重新调用login()刷新令牌,避免 401 错误。 - 令牌安全:JWT 令牌等同于用户的登录凭证,务必妥善保管,不应写入日志或公开的代码仓库;泄露后应通过服务端机制使其失效并重新生成。
- 时间单位:
token_expiration是 Unix Epoch 秒(整数),不是毫秒,与 Pythontime.time()返回的时间单位一致,可直接比较。 - 模型校验:由于
validate_assignment = True,对实例字段的错误类型赋值会立即抛出 Pydantic 校验异常,这在解析外部 JSON 时是很好的防御机制。 - 文档示例笔误:原文档示例中的
print AuthenticationToken.to_json()缺少实例对象与括号,请参照本文第二部分的修正写法。
- 数据工程
- 数据湖
- 大数据
- 对象存储
- 后端
【免费下载链接】lakeFS
lakeFS - Data version control for your data lake | Git for data
相关推荐
lakeFS Java SDK 认证令牌 AuthenticationToken 详解:JWT 字段结构、登录流程与底层实现
lakeFS Java SDK 认证令牌 AuthenticationToken 详解:JWT 字段结构、登录流程与底层实现 导读 Authentication
数据工程数据湖大数据对象存储后端urql 认证实战指南:用 @urql/exchange-auth 实现 JWT 登录、令牌刷新与登出
urql 认证实战指南:用 @urql/exchange auth 实现 JWT 登录、令牌刷新与登出 大多数 GraphQL API 都带有某种形式的认证,最
前端Redwood dbAuth 无密码认证实战:基于邮箱令牌的 Passwordless 登录改造指南
Redwood dbAuth 无密码认证实战:基于邮箱令牌的 Passwordless 登录改造指南 导读 本文基于 Redwood 官方 how to 文档,
后端前端Web框架开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考