Repository: AlistGo/alist (language: go)

Issue:
Crypt 驱动中的缩略图功能，缺失sign参数
### Please make sure of the following things

- [X] I have read the [documentation](https://alist.nn.ci).
我已经阅读了[文档](https://alist.nn.ci)。

- [X] I'm sure there are no duplicate issues or discussions.
我确定没有重复的issue或讨论。

- [X] I'm sure it's due to `AList` and not something else(such as [Network](https://alist.nn.ci/faq/howto.html#tls-handshake-timeout-read-connection-reset-by-peer-dns-lookup-failed-connect-connection-refused-client-timeout-exceeded-while-awaiting-headers-no-such-host) ,`Dependencies` or `Operational`).
我确定是`AList`的问题，而不是其他原因（例如[网络](https://alist.nn.ci/zh/faq/howto.html#tls-handshake-timeout-read-connection-reset-by-peer-dns-lookup-failed-connect-connection-refused-client-timeout-exceeded-while-awaiting-headers-no-such-host)，`依赖`或`操作`）。

- [X] I'm sure this issue is not fixed in the latest version.
我确定这个问题在最新版本中没有被修复。


### AList Version / AList 版本

v3.35.0

### Driver used / 使用的存储驱动

Crypt

### Describe the bug / 问题描述

在 Crypt 驱动上，开启缩略图功能 #5284 的同时开启签名功能，那么缩略图将无法正常加载。

浏览器F12分析，访问 **本地存储** 时，看到的缩略图加载行为，有如下参数。
`https://alist.********/d/********/A.mp4?type=thumb&sign=********`
而访问 **Crypt存储** 时，缩略图加载不含sign参数。
`https://alist.********/d/crypt/.thumbnails/A.mp4.webp`

推测：[缩略图URL没有携带sign参数被拒绝](https://github.com/alist-org/alist/blob/639b7817bf6a3d6ac937a281495c36522e9601e3/drivers/crypt/driver.go#L163)

### Reproduction / 复现链接

**无可供访问链接。**

预先准备好视频文件和缩略图，按照 Crypt 驱动缩略图代码，如下存放。
```
/crypt/A.mp4
/crypt/.thumbnails/A.mp4.webp
```
开启签名功能状态下，网格视图不显示缩略图。
浏览器F12 分析相关加载行为的连接：`状态200；类型json；大小51B`。
访问疑似缩略图加载行为URL `
https://alist.********/d/crypt/.thumbnails/A.mp4.webp` 得到以下内容
```json
{
    "code": 401,
    "message": "expire missing",
    "data": null
}
```
在关闭签名功能后即刻恢复正常。

### Config / 配置

    {
      "id": 1,
      "mount_path": "/crypt",
      "order": 1,
      "driver": "Crypt",
      "cache_expiration": 0,
      "status": "work",
      "addition": "{\"filename_encryption\":\"standard\",\"directory_name_encryption\":\"true\",\"remote_path\":\"/********\",\"password\":\"********\",\"salt\":\"********\",\"encrypted_suffix\":\".bin\",\"filename_encoding\":\"base64\",\"thumbnail\":true,\"show_hidden\":false}",
      "remark": "",
      "modified": "********",
      "disabled": false,
      "enable_sign": true,
      "order_by": "",
      "order_direction": "",
      "extract_folder": "",
      "web_proxy": false,
      "webdav_policy": "native_proxy",
      "proxy_range": false,
      "down_proxy_url": ""
    }

### Logs / 日志

_No response_


Discussion / hints:
Thanks for opening your first issue here! Be sure to follow the issue template!

这个功能到底该怎么使用啊大佬
> 这个功能到底该怎么使用啊大佬

功能只会去尝试加载图片。要你自己主动处理缩略图，webp格式，按路径放文件。下面是路径例子。
```
~/6607.mp4
~/.thumbnails/6607.mp4.webp
```
> > 这个功能到底该怎么使用啊大佬
> 
> 功能只会去尝试加载图片。要你自己主动处理缩略图，webp格式，按路径放文件。下面是路径例子。
> 
> ```
> ~/6607.mp4
> ~/.thumbnails/6607.mp4.webp
> ```

如何用 ffmpeg 生成每个文件夹文件在对应位置呢？网盘文件是不是必须要下载到本地生成啊🤔谢谢大佬🙏
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Hello @, this issue was closed due to inactive more than 52 days. You can reopen or recreate it if you think it should continue. Thank you for your contributions again.

Fix patch:
diff --git a/drivers/crypt/driver.go b/drivers/crypt/driver.go
index b0325db4956..b6115896b98 100644
--- a/drivers/crypt/driver.go
+++ b/drivers/crypt/driver.go
@@ -13,6 +13,7 @@ import (
 	"github.com/alist-org/alist/v3/internal/fs"
 	"github.com/alist-org/alist/v3/internal/model"
 	"github.com/alist-org/alist/v3/internal/op"
+	"github.com/alist-org/alist/v3/internal/sign"
 	"github.com/alist-org/alist/v3/internal/stream"
 	"github.com/alist-org/alist/v3/pkg/http_range"
 	"github.com/alist-org/alist/v3/pkg/utils"
@@ -160,7 +161,11 @@ func (d *Crypt) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
 				// discarding hash as it's encrypted
 			}
 			if d.Thumbnail && thumb == "" {
-				thumb = utils.EncodePath(common.GetApiUrl(nil)+stdpath.Join("/d", args.ReqPath, ".thumbnails", name+".webp"), true)
+				thumbPath := stdpath.Join(args.ReqPath, ".thumbnails", name+".webp")
+				thumb = fmt.Sprintf("%s/d%s?sign=%s",
+					common.GetApiUrl(common.GetHttpReq(ctx)),
+					utils.EncodePath(thumbPath, true),
+					sign.Sign(thumbPath))
 			}
 			if !ok && !d.Thumbnail {
 				result = append(result, &objRes)
diff --git a/drivers/local/driver.go b/drivers/local/driver.go
index 229c86925fb..2519232e7d6 100644
--- a/drivers/local/driver.go
+++ b/drivers/local/driver.go
@@ -101,17 +101,17 @@ func (d *Local) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
 		if !d.ShowHidden && strings.HasPrefix(f.Name(), ".") {
 			continue
 		}
-		file := d.FileInfoToObj(f, args.ReqPath, fullPath)
+		file := d.FileInfoToObj(ctx, f, args.ReqPath, fullPath)
 		files = append(files, file)
 	}
 	return files, nil
 }
-func (d *Local) FileInfoToObj(f fs.FileInfo, reqPath string, fullPath string) model.Obj {
+func (d *Local) FileInfoToObj(ctx context.Context, f fs.FileInfo, reqPath string, fullPath string) model.Obj {
 	thumb := ""
 	if d.Thumbnail {
 		typeName := utils.GetFileType(f.Name())
 		if typeName == conf.IMAGE || typeName == conf.VIDEO {
-			thumb = common.GetApiUrl(nil) + stdpath.Join("/d", reqPath, f.Name())
+			thumb = common.GetApiUrl(common.GetHttpReq(ctx)) + stdpath.Join("/d", reqPath, f.Name())
 			thumb = utils.EncodePath(thumb, true)
 			thumb += "?type=thumb&sign=" + sign.Sign(stdpath.Join(reqPath, f.Name()))
 		}
@@ -149,7 +149,7 @@ func (d *Local) GetMeta(ctx context.Context, path string) (model.Obj, error) {
 	if err != nil {
 		return nil, err
 	}
-	file := d.FileInfoToObj(f, path, path)
+	file := d.FileInfoToObj(ctx, f, path, path)
 	//h := "123123"
 	//if s, ok := f.(model.SetHash); ok && file.GetHash() == ("","")  {
 	//	s.SetHash(h,"SHA1")
diff --git a/server/common/common.go b/server/common/common.go
index 28d2da4443d..e231ffe6e88 100644
--- a/server/common/common.go
+++ b/server/common/common.go
@@ -1,6 +1,8 @@
 package common
 
 import (
+	"context"
+	"net/http"
 	"strings"
 
 	"github.com/alist-org/alist/v3/cmd/flags"
@@ -80,3 +82,10 @@ func SuccessResp(c *gin.Context, data ...interface{}) {
 		Data:    data[0],
 	})
 }
+
+func GetHttpReq(ctx context.Context) *http.Request {
+	if c, ok := ctx.(*gin.Context); ok {
+		return c.Request
+	}
+	return nil
+}


Test patch: