Compare commits

..
4 Commits
Author SHA1 Message Date
wuzhiqiang 3ea8eff34d refactor: 替换密码哈希实现为原生bcrypt并更新依赖
重构CryptUtils类,替换原有的passlib密码哈希逻辑为直接使用bcrypt库;添加密码字节长度限制以符合bcrypt原生72字节上限;更新pyproject.toml配置,新增bcrypt依赖并将passlib设为可选依赖;统一代码缩进格式
2026-09-05 07:48:45 +08:00
wuzhiqiang 7e7afe3907 config: 添加lock文件 2026-09-04 22:07:42 +08:00
wuzhiqiang 4276015cf3 chore: 删除lock文件 2026-09-04 21:40:06 +08:00
wuzhiqiang 59ac17e609 config: 配置源 2026-09-04 21:37:19 +08:00
4 changed files with 4011 additions and 3022 deletions
+2 -1
View File
@@ -83,7 +83,8 @@ ai_configs = {
}, },
'bailian-embedding': { 'bailian-embedding': {
'model': 'text-embedding-v4', 'model': 'text-embedding-v4',
'url': 'https://llm-z0ugjqj2yf8a7i89.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/embeddings', # 'url': 'https://llm-z0ugjqj2yf8a7i89.cn-beijing.maas.aliyuncs.com/compatible-mode/v1/embeddings',
"url": "https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings",
'key': env.llm_key_bailian, 'key': env.llm_key_bailian,
}, },
} }
+22 -13
View File
@@ -1,44 +1,53 @@
from datetime import timedelta, datetime, timezone from datetime import timedelta, datetime, timezone
from typing import TypedDict, Literal, TypeAlias from typing import TypedDict, Literal, TypeAlias
import bcrypt
import jwt import jwt
from passlib.context import CryptContext
from app.config.env import env from app.config.env import env
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") BCRYPT_MAX_BYTES = 72
# token的类型,access用于接口认证,refresh用于刷新access token,verify用于激活用户账号
AccessTokenType: TypeAlias = Literal["access", "refresh", "verify", "api"] AccessTokenType: TypeAlias = Literal["access", "refresh", "verify", "api"]
class TokenInfo(TypedDict): class TokenInfo(TypedDict):
# 用户名信息
username: str username: str
# token过期时间
exp: datetime exp: datetime
type: AccessTokenType type: AccessTokenType
def _safe_password_bytes(password: str) -> bytes:
data = password.encode("utf-8")
if len(data) > BCRYPT_MAX_BYTES:
data = data[:BCRYPT_MAX_BYTES]
return data
class CryptUtils: class CryptUtils:
@staticmethod @staticmethod
def get_password_hash(password: str): def get_password_hash(password: str):
return pwd_context.hash(password) return bcrypt.hashpw(_safe_password_bytes(password), bcrypt.gensalt()).decode(
"utf-8"
)
@staticmethod @staticmethod
def verify_password(plain_password: str, hashed_password: str): def verify_password(plain_password: str, hashed_password: str):
return pwd_context.verify(plain_password, hashed_password) try:
return bcrypt.checkpw(
_safe_password_bytes(plain_password), hashed_password.encode("utf-8")
)
except ValueError:
return False
except Exception:
return False
@staticmethod @staticmethod
def create_token( def create_token(username: str, type: AccessTokenType, expires_delta: timedelta):
username: str,
type: AccessTokenType,
expires_delta: timedelta
):
data: TokenInfo = { data: TokenInfo = {
"username": username, "username": username,
"type": type, "type": type,
"exp": datetime.now(timezone.utc) + expires_delta "exp": datetime.now(timezone.utc) + expires_delta,
} }
return jwt.encode(data, env.jwt_secret_key, env.jwt_algorithm) return jwt.encode(data, env.jwt_secret_key, env.jwt_algorithm)
Generated
+3967 -2984
View File
File diff suppressed because it is too large Load Diff
+3 -7
View File
@@ -20,7 +20,8 @@ psutil = "^7.0.0"
asyncmy = "^0.2.10" asyncmy = "^0.2.10"
sqlmodel = "^0.0.24" sqlmodel = "^0.0.24"
greenlet = "^3.2.3" greenlet = "^3.2.3"
passlib = {extras = ["bcrypt"], version = "^1.7.4"} passlib = {extras = ["bcrypt"], version = "^1.7.4", optional = true}
bcrypt = "^4.0.0"
pyjwt = "^2.10.1" pyjwt = "^2.10.1"
python-multipart = "^0.0.20" python-multipart = "^0.0.20"
langgraph = "^0.6.3" langgraph = "^0.6.3"
@@ -40,15 +41,10 @@ psycopg = {extras = ["binary"], version = "^3.3.3"}
langchain-cli = ">=0.0.15" langchain-cli = ">=0.0.15"
# 配置国内镜像源 # 配置国内镜像源
[[tool.poetry.source]]
name = "tsinghua"
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
priority = "primary" # 最高优先级
[[tool.poetry.source]] [[tool.poetry.source]]
name = "aliyun" name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple/" url = "https://mirrors.aliyun.com/pypi/simple/"
priority = "supplemental" # 次级优先级 priority = "primary" # 最高优先级
[build-system] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]