refactor: 迁移本地 Supabase 到云端,使用 JWKS 进行 JWT 验证
- 新增 JwtVerifier 支持 RS256 + JWKS 验证 - 简化 docker-compose,删除本地 Supabase 服务(kong/auth/storage等) - 删除冗余的 Supabase 配置文件(volumes目录) - 适配测试用例以支持新配置方式 - 更新运行时文档和迁移计划
This commit is contained in:
@@ -4,7 +4,14 @@ from pathlib import Path
|
||||
from typing import ClassVar, Literal
|
||||
from urllib.parse import quote
|
||||
|
||||
from pydantic import BaseModel, Field, computed_field, field_validator, model_validator
|
||||
from pydantic import (
|
||||
AnyHttpUrl,
|
||||
BaseModel,
|
||||
Field,
|
||||
computed_field,
|
||||
field_validator,
|
||||
model_validator,
|
||||
)
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
@@ -116,14 +123,14 @@ class RedisSettings(BaseModel):
|
||||
|
||||
|
||||
class SupabaseSettings(BaseModel):
|
||||
public_scheme: str = "http"
|
||||
public_host: str = "localhost"
|
||||
kong_http_port: int = 8000
|
||||
site_url: str = "http://localhost:3000"
|
||||
additional_redirect_urls: list[str] = Field(default_factory=list)
|
||||
public_url: AnyHttpUrl
|
||||
anon_key: str = "CHANGE_ME"
|
||||
service_role_key: str = "CHANGE_ME"
|
||||
jwt_secret: str | None = None
|
||||
jwt_audience: str = "authenticated"
|
||||
jwt_issuer: str | None = None
|
||||
jwks_url: str | None = None
|
||||
site_url: str | None = None
|
||||
additional_redirect_urls: list[str] = Field(default_factory=list)
|
||||
|
||||
@field_validator("additional_redirect_urls", mode="before")
|
||||
@classmethod
|
||||
@@ -136,15 +143,24 @@ class SupabaseSettings(BaseModel):
|
||||
return [str(item).strip() for item in value if str(item).strip()]
|
||||
return []
|
||||
|
||||
@computed_field
|
||||
@property
|
||||
def public_url(self) -> str:
|
||||
return f"{self.public_scheme}://{self.public_host}:{self.kong_http_port}"
|
||||
@model_validator(mode="after")
|
||||
def compute_defaults(self) -> "SupabaseSettings":
|
||||
base = str(self.public_url).rstrip("/")
|
||||
if self.jwt_issuer is None:
|
||||
self.jwt_issuer = f"{base}/auth/v1"
|
||||
|
||||
if self.jwks_url is None:
|
||||
self.jwks_url = f"{self.jwt_issuer}/.well-known/jwks.json"
|
||||
|
||||
if self.site_url is None:
|
||||
self.site_url = "http://localhost:3000"
|
||||
|
||||
return self
|
||||
|
||||
@computed_field
|
||||
@property
|
||||
def url(self) -> str:
|
||||
return self.public_url
|
||||
return str(self.public_url)
|
||||
|
||||
|
||||
class StorageSettings(BaseModel):
|
||||
@@ -205,7 +221,7 @@ class Settings(BaseSettings):
|
||||
runtime: RuntimeSettings = RuntimeSettings()
|
||||
cors: CorsSettings = CorsSettings()
|
||||
redis: RedisSettings = RedisSettings()
|
||||
supabase: SupabaseSettings = SupabaseSettings()
|
||||
supabase: SupabaseSettings = Field()
|
||||
storage: StorageSettings = StorageSettings()
|
||||
llm: LlmSettings = LlmSettings()
|
||||
agent_runtime: AgentRuntimeSettings = AgentRuntimeSettings()
|
||||
@@ -236,4 +252,4 @@ class Settings(BaseSettings):
|
||||
)
|
||||
|
||||
|
||||
config = Settings()
|
||||
config = Settings() # type: ignore[reportCallIssue]
|
||||
|
||||
Reference in New Issue
Block a user