mirror of
https://github.com/AlistGo/alist.git
synced 2025-11-25 11:29:45 +08:00
feat(driver): Add URL signing support (#9347)
Introduces the ability to sign generated URLs for enhanced security and access control. This feature is activated by configuring a `PrivateKey`, `UID`, and `ValidDuration` in the driver settings. If a private key is provided, the driver will sign the output URLs, making them time-limited based on the `ValidDuration`. The `ValidDuration` defaults to 30 minutes if not specified. The core signing logic is encapsulated in the new `sign.go` file. The `driver.go` file integrates this signing process before returning the final URL.
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Open123 struct {
|
type Open123 struct {
|
||||||
@@ -89,8 +90,24 @@ func (d *Open123) Link(ctx context.Context, file model.Obj, args model.LinkArgs)
|
|||||||
return nil, fmt.Errorf("get link failed: %s", result.Message)
|
return nil, fmt.Errorf("get link failed: %s", result.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linkURL := result.Data.URL
|
||||||
|
if d.PrivateKey != "" {
|
||||||
|
if d.UID == 0 {
|
||||||
|
return nil, fmt.Errorf("uid is required when private key is set")
|
||||||
|
}
|
||||||
|
duration := time.Duration(d.ValidDuration)
|
||||||
|
if duration <= 0 {
|
||||||
|
duration = 30
|
||||||
|
}
|
||||||
|
signedURL, err := SignURL(linkURL, d.PrivateKey, d.UID, duration*time.Minute)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
linkURL = signedURL
|
||||||
|
}
|
||||||
|
|
||||||
return &model.Link{
|
return &model.Link{
|
||||||
URL: result.Data.URL,
|
URL: linkURL,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ type Addition struct {
|
|||||||
|
|
||||||
ClientID string `json:"client_id" required:"true" label:"Client ID"`
|
ClientID string `json:"client_id" required:"true" label:"Client ID"`
|
||||||
ClientSecret string `json:"client_secret" required:"true" label:"Client Secret"`
|
ClientSecret string `json:"client_secret" required:"true" label:"Client Secret"`
|
||||||
|
PrivateKey string `json:"private_key"`
|
||||||
|
UID uint64 `json:"uid" type:"number"`
|
||||||
|
ValidDuration int64 `json:"valid_duration" type:"number" default:"30" help:"minutes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = driver.Config{
|
var config = driver.Config{
|
||||||
|
|||||||
27
drivers/123_open/sign.go
Normal file
27
drivers/123_open/sign.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package _123Open
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SignURL(originURL, privateKey string, uid uint64, validDuration time.Duration) (string, error) {
|
||||||
|
if privateKey == "" {
|
||||||
|
return originURL, nil
|
||||||
|
}
|
||||||
|
parsed, err := url.Parse(originURL)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
ts := time.Now().Add(validDuration).Unix()
|
||||||
|
randInt := rand.Int()
|
||||||
|
signature := fmt.Sprintf("%d-%d-%d-%x", ts, randInt, uid, md5.Sum([]byte(fmt.Sprintf("%s-%d-%d-%d-%s",
|
||||||
|
parsed.Path, ts, randInt, uid, privateKey))))
|
||||||
|
query := parsed.Query()
|
||||||
|
query.Add("auth_key", signature)
|
||||||
|
parsed.RawQuery = query.Encode()
|
||||||
|
return parsed.String(), nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user