rainycode 1.6.0__tar.gz → 1.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rainycode-1.6.0 → rainycode-1.6.2}/PKG-INFO +1 -1
- {rainycode-1.6.0 → rainycode-1.6.2}/common_depends/auth_depend.py +2 -2
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/api/auth_api.py +1 -1
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/api/wechat_api.py +4 -2
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/service/auth_svc.py +13 -4
- {rainycode-1.6.0 → rainycode-1.6.2}/core/base_config.py +13 -3
- {rainycode-1.6.0 → rainycode-1.6.2}/core/start.py +1 -1
- {rainycode-1.6.0 → rainycode-1.6.2}/pyproject.toml +1 -1
- {rainycode-1.6.0 → rainycode-1.6.2}/rainycode.egg-info/PKG-INFO +1 -1
- {rainycode-1.6.0 → rainycode-1.6.2}/common_base/aiorequests.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_base/consts.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_base/exception.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_base/logging.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_base/response.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_models/__init__.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_models/base_model.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_models/file_model.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_models/user_model.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_models/wechat_model.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/router.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/schemas/auth_schema.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/service/file_svc.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_servers/service/wechat_svc.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/bcrypt_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/captcha_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/datetime_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/ip_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/jwt_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/snowflake_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/common_utils/wechat_util.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/core/databases/aiodb.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/core/databases/aioredis.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/core/middleware/http_middleware.py +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/rainycode.egg-info/SOURCES.txt +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/rainycode.egg-info/dependency_links.txt +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/rainycode.egg-info/requires.txt +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/rainycode.egg-info/top_level.txt +0 -0
- {rainycode-1.6.0 → rainycode-1.6.2}/setup.cfg +0 -0
|
@@ -21,7 +21,7 @@ async def get_current_user(request: Request, token: str, security_scopes: Securi
|
|
|
21
21
|
"""
|
|
22
22
|
payload = JwtUtil.decode_token(token)
|
|
23
23
|
if not payload:
|
|
24
|
-
raise CustomException(msg="无效的令牌", status_code=401)
|
|
24
|
+
raise CustomException(msg=f"无效的令牌 {token}", status_code=401)
|
|
25
25
|
|
|
26
26
|
# 检查是否在黑名单中
|
|
27
27
|
if await AioRedis.get(f"{REDIS_PREFIX_BLOCKLIST}{token}"):
|
|
@@ -29,7 +29,7 @@ async def get_current_user(request: Request, token: str, security_scopes: Securi
|
|
|
29
29
|
|
|
30
30
|
user_id = payload.get("sub")
|
|
31
31
|
if not user_id:
|
|
32
|
-
raise CustomException(msg="无效的令牌", status_code=401)
|
|
32
|
+
raise CustomException(msg=f"无效的令牌 {token}", status_code=401)
|
|
33
33
|
|
|
34
34
|
# 1. 尝试从缓存获取
|
|
35
35
|
user = None
|
|
@@ -55,7 +55,7 @@ async def logout(
|
|
|
55
55
|
|
|
56
56
|
@router.get("/me", response_model=UserInfo, summary="获取当前用户信息")
|
|
57
57
|
async def get_me(user: User = Security(login_require)):
|
|
58
|
-
return SuccessReturn(data=user)
|
|
58
|
+
return SuccessReturn(data=await User.model2dict(user), msg="查询成功")
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
@router.post("/wechat/mini", response_model=TokenResponse, summary="微信小程序登录")
|
|
@@ -89,8 +89,10 @@ async def wechat_oauth_callback(
|
|
|
89
89
|
"error": error,
|
|
90
90
|
"error_description": error_description or "用户拒绝授权",
|
|
91
91
|
}
|
|
92
|
-
# redirect_uri
|
|
93
|
-
#
|
|
92
|
+
# 拼接符按 redirect_uri 现状选:前端现在把目标页路由挂在 query 上
|
|
93
|
+
# (?dw_route=%2Fpages%2Fxxx,原因见 AuthService._build_redirect_response),
|
|
94
|
+
# 此时用 & 续接;存量授权链接仍是 #/pages/xxx 形态,用 ? 续接。
|
|
95
|
+
# 两种形态下错误信息都会落在该页自己的参数区,页面能取到并提示。
|
|
94
96
|
sep = "&" if "?" in redirect_uri else "?"
|
|
95
97
|
error_url = f"{redirect_uri}{sep}{urlencode(params)}"
|
|
96
98
|
return RedirectResponse(url=error_url, status_code=302)
|
|
@@ -521,7 +521,7 @@ class AuthService:
|
|
|
521
521
|
async def _build_redirect_response(
|
|
522
522
|
cls, redirect_uri: str, token_data: dict, state: str | None = None
|
|
523
523
|
) -> RedirectResponse:
|
|
524
|
-
"""构建带 token
|
|
524
|
+
"""构建带 token 的重定向响应(凭证拼在 redirect_uri 的 query 上)"""
|
|
525
525
|
params = {
|
|
526
526
|
"access_token": token_data["access_token"],
|
|
527
527
|
"refresh_token": token_data["refresh_token"],
|
|
@@ -531,9 +531,18 @@ class AuthService:
|
|
|
531
531
|
if state:
|
|
532
532
|
params["state"] = state
|
|
533
533
|
|
|
534
|
-
#
|
|
535
|
-
#
|
|
536
|
-
#
|
|
534
|
+
# 凭证一律拼在 query 上,绝不落到 `#` 之后。
|
|
535
|
+
#
|
|
536
|
+
# 为什么:PC 微信跟随 302 时会丢掉 `#` 之后整段(微信官方社区原话:fragment
|
|
537
|
+
#「仅用作浏览器端的处理,不会参与到服务端请求中,故回跳不会带上这部分信息」)。
|
|
538
|
+
# 凭证若落在 fragment,就等于在电脑端凭空消失,用户表现为「点了登录回到首页
|
|
539
|
+
# 且没登录」,后端日志里连 /user/profile 都不会出现。
|
|
540
|
+
# 因此前端 guard.js 连目标页路由也一并挪到 query 上(?dw_route=%2Fpages%2Fxxx),
|
|
541
|
+
# 由 index.html 在 app 启动前还原成 hash 路由。这里只按 redirect_uri 是否已带
|
|
542
|
+
# 参数来选拼接符:
|
|
543
|
+
# ?dw_route=..(当前形态,路由挂在 query)→ 用 & 续接
|
|
544
|
+
# #/pages/xxx(存量授权链接,路由挂在 hash)→ 用 ? 续接
|
|
545
|
+
# 注:变量名 fragment 是历史沿用,实际拼在 query 上。
|
|
537
546
|
fragment = urlencode(params)
|
|
538
547
|
sep = "&" if "?" in redirect_uri else "?"
|
|
539
548
|
redirect_url = f"{redirect_uri}{sep}{fragment}"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
1
3
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
2
4
|
|
|
5
|
+
# 包内 static 目录(core/ 的上一级),默认的 /static 挂载点
|
|
6
|
+
_STATIC_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../static"))
|
|
7
|
+
|
|
3
8
|
|
|
4
9
|
class BaseConfig(BaseSettings):
|
|
5
10
|
app_debug: bool = False
|
|
@@ -13,10 +18,15 @@ class BaseConfig(BaseSettings):
|
|
|
13
18
|
# 基础 URL
|
|
14
19
|
base_url: str = ""
|
|
15
20
|
|
|
21
|
+
# 静态文件:/static 的挂载根目录,默认包内 static;
|
|
22
|
+
# 想让静态资源落到项目目录,子类里覆盖这一项即可。
|
|
23
|
+
static_root: str = _STATIC_DIR
|
|
24
|
+
|
|
16
25
|
# 文件上传:本地存储根目录 + 访问 URL 前缀。
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
# upload_root 必须在 static_root 之下,否则会出现「写得进、读不到」。
|
|
27
|
+
# upload_url_prefix 可为相对路径(/static/uploads)或完整 URL(https://cdn.xxx.com/uploads),
|
|
28
|
+
upload_root: str = os.path.join(_STATIC_DIR, 'uploads')
|
|
29
|
+
upload_url_prefix: str = '/static/uploads'
|
|
20
30
|
|
|
21
31
|
# 跨域
|
|
22
32
|
cors_origins: list[str] = ['*']
|
|
@@ -97,7 +97,7 @@ def register_files(app: FastAPI) -> None:
|
|
|
97
97
|
"""
|
|
98
98
|
注册文件相关配置
|
|
99
99
|
"""
|
|
100
|
-
static_dir =
|
|
100
|
+
static_dir = base_config.static_root
|
|
101
101
|
if not os.path.exists(static_dir):
|
|
102
102
|
os.mkdir(static_dir)
|
|
103
103
|
app.mount('/static', StaticFiles(directory=static_dir))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|