mirror of https://github.com/Xhofe/alist
				
				
				
			fix(pikpak_share): add captcha_token generation function (#7045)
							parent
							
								
									18176c659c
								
							
						
					
					
						commit
						489b28bdf7
					
				| 
						 | 
				
			
			@ -2,20 +2,20 @@ package pikpak_share
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/op"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/alist-org/alist/v3/drivers/base"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/driver"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/model"
 | 
			
		||||
	"github.com/alist-org/alist/v3/pkg/utils"
 | 
			
		||||
	"github.com/go-resty/resty/v2"
 | 
			
		||||
	"golang.org/x/oauth2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type PikPakShare struct {
 | 
			
		||||
	model.Storage
 | 
			
		||||
	Addition
 | 
			
		||||
	oauth2Token   oauth2.TokenSource
 | 
			
		||||
	*Common
 | 
			
		||||
	PassCodeToken string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -28,28 +28,45 @@ func (d *PikPakShare) GetAddition() driver.Additional {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (d *PikPakShare) Init(ctx context.Context) error {
 | 
			
		||||
	if d.ClientID == "" || d.ClientSecret == "" {
 | 
			
		||||
		d.ClientID = "YNxT9w7GMdWvEOKa"
 | 
			
		||||
		d.ClientSecret = "dbw2OtmVEeuUvIptb1Coyg"
 | 
			
		||||
	if d.Common == nil {
 | 
			
		||||
		d.Common = &Common{
 | 
			
		||||
			DeviceID:  utils.GetMD5EncodeStr(d.Addition.ShareId + d.Addition.SharePwd + time.Now().String()),
 | 
			
		||||
			UserAgent: "",
 | 
			
		||||
			RefreshCTokenCk: func(token string) {
 | 
			
		||||
				d.Common.CaptchaToken = token
 | 
			
		||||
				op.MustSaveDriverStorage(d)
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	oauth2Config := &oauth2.Config{
 | 
			
		||||
		ClientID:     d.ClientID,
 | 
			
		||||
		ClientSecret: d.ClientSecret,
 | 
			
		||||
		Endpoint: oauth2.Endpoint{
 | 
			
		||||
			AuthURL:   "https://user.mypikpak.com/v1/auth/signin",
 | 
			
		||||
			TokenURL:  "https://user.mypikpak.com/v1/auth/token",
 | 
			
		||||
			AuthStyle: oauth2.AuthStyleInParams,
 | 
			
		||||
		},
 | 
			
		||||
	if d.Addition.DeviceID != "" {
 | 
			
		||||
		d.SetDeviceID(d.Addition.DeviceID)
 | 
			
		||||
	} else {
 | 
			
		||||
		d.Addition.DeviceID = d.Common.DeviceID
 | 
			
		||||
		op.MustSaveDriverStorage(d)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	d.oauth2Token = oauth2.ReuseTokenSource(nil, utils.TokenSource(func() (*oauth2.Token, error) {
 | 
			
		||||
		return oauth2Config.PasswordCredentialsToken(
 | 
			
		||||
			context.WithValue(context.Background(), oauth2.HTTPClient, base.HttpClient),
 | 
			
		||||
			d.Username,
 | 
			
		||||
			d.Password,
 | 
			
		||||
		)
 | 
			
		||||
	}))
 | 
			
		||||
	if d.Platform == "android" {
 | 
			
		||||
		d.ClientID = AndroidClientID
 | 
			
		||||
		d.ClientSecret = AndroidClientSecret
 | 
			
		||||
		d.ClientVersion = AndroidClientVersion
 | 
			
		||||
		d.PackageName = AndroidPackageName
 | 
			
		||||
		d.Algorithms = AndroidAlgorithms
 | 
			
		||||
		d.UserAgent = BuildCustomUserAgent(d.GetDeviceID(), AndroidClientID, AndroidPackageName, AndroidSdkVersion, AndroidClientVersion, AndroidPackageName, "")
 | 
			
		||||
	} else if d.Platform == "web" {
 | 
			
		||||
		d.ClientID = WebClientID
 | 
			
		||||
		d.ClientSecret = WebClientSecret
 | 
			
		||||
		d.ClientVersion = WebClientVersion
 | 
			
		||||
		d.PackageName = WebPackageName
 | 
			
		||||
		d.Algorithms = WebAlgorithms
 | 
			
		||||
		d.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 获取CaptchaToken
 | 
			
		||||
	err := d.RefreshCaptchaToken(GetAction(http.MethodGet, "https://api-drive.mypikpak.com/drive/v1/share:batch_file_info"), "")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if d.SharePwd != "" {
 | 
			
		||||
		return d.getSharePassToken()
 | 
			
		||||
| 
						 | 
				
			
			@ -87,9 +104,14 @@ func (d *PikPakShare) Link(ctx context.Context, file model.Obj, args model.LinkA
 | 
			
		|||
 | 
			
		||||
	downloadUrl := resp.FileInfo.WebContentLink
 | 
			
		||||
	if downloadUrl == "" && len(resp.FileInfo.Medias) > 0 {
 | 
			
		||||
		downloadUrl = resp.FileInfo.Medias[0].Link.Url
 | 
			
		||||
	}
 | 
			
		||||
		// 使用转码后的链接
 | 
			
		||||
		if d.Addition.UseTransCodingAddress && len(resp.FileInfo.Medias) > 1 {
 | 
			
		||||
			downloadUrl = resp.FileInfo.Medias[1].Link.Url
 | 
			
		||||
		} else {
 | 
			
		||||
			downloadUrl = resp.FileInfo.Medias[0].Link.Url
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	link := model.Link{
 | 
			
		||||
		URL: downloadUrl,
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,12 +7,11 @@ import (
 | 
			
		|||
 | 
			
		||||
type Addition struct {
 | 
			
		||||
	driver.RootID
 | 
			
		||||
	Username     string `json:"username" required:"true"`
 | 
			
		||||
	Password     string `json:"password" required:"true"`
 | 
			
		||||
	ShareId      string `json:"share_id" required:"true"`
 | 
			
		||||
	SharePwd     string `json:"share_pwd"`
 | 
			
		||||
	ClientID     string `json:"client_id" required:"true" default:"YNxT9w7GMdWvEOKa"`
 | 
			
		||||
	ClientSecret string `json:"client_secret" required:"true" default:"dbw2OtmVEeuUvIptb1Coyg"`
 | 
			
		||||
	ShareId               string `json:"share_id" required:"true"`
 | 
			
		||||
	SharePwd              string `json:"share_pwd"`
 | 
			
		||||
	Platform              string `json:"platform" required:"true" type:"select" options:"android,web"`
 | 
			
		||||
	DeviceID              string `json:"device_id"  required:"false" default:""`
 | 
			
		||||
	UseTransCodingAddress bool   `json:"use_transcoding_address" required:"true" default:"false"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var config = driver.Config{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +1,16 @@
 | 
			
		|||
package pikpak_share
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type RespErr struct {
 | 
			
		||||
	ErrorCode int    `json:"error_code"`
 | 
			
		||||
	Error     string `json:"error"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ShareResp struct {
 | 
			
		||||
	ShareStatus		string `json:"share_status"`
 | 
			
		||||
	ShareStatusText	string `json:"share_status_text"`
 | 
			
		||||
	ShareStatus     string `json:"share_status"`
 | 
			
		||||
	ShareStatusText string `json:"share_status_text"`
 | 
			
		||||
	FileInfo        File   `json:"file_info"`
 | 
			
		||||
	Files           []File `json:"files"`
 | 
			
		||||
	NextPageToken   string `json:"next_page_token"`
 | 
			
		||||
| 
						 | 
				
			
			@ -78,3 +74,32 @@ type Media struct {
 | 
			
		|||
	IsVisible      bool          `json:"is_visible"`
 | 
			
		||||
	Category       string        `json:"category"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CaptchaTokenRequest struct {
 | 
			
		||||
	Action       string            `json:"action"`
 | 
			
		||||
	CaptchaToken string            `json:"captcha_token"`
 | 
			
		||||
	ClientID     string            `json:"client_id"`
 | 
			
		||||
	DeviceID     string            `json:"device_id"`
 | 
			
		||||
	Meta         map[string]string `json:"meta"`
 | 
			
		||||
	RedirectUri  string            `json:"redirect_uri"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CaptchaTokenResponse struct {
 | 
			
		||||
	CaptchaToken string `json:"captcha_token"`
 | 
			
		||||
	ExpiresIn    int64  `json:"expires_in"`
 | 
			
		||||
	Url          string `json:"url"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ErrResp struct {
 | 
			
		||||
	ErrorCode        int64  `json:"error_code"`
 | 
			
		||||
	ErrorMsg         string `json:"error"`
 | 
			
		||||
	ErrorDescription string `json:"error_description"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *ErrResp) IsError() bool {
 | 
			
		||||
	return e.ErrorCode != 0 || e.ErrorMsg != "" || e.ErrorDescription != ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *ErrResp) Error() string {
 | 
			
		||||
	return fmt.Sprintf("ErrorCode: %d ,Error: %s ,ErrorDescription: %s ", e.ErrorCode, e.ErrorMsg, e.ErrorDescription)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,21 +1,78 @@
 | 
			
		|||
package pikpak_share
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/md5"
 | 
			
		||||
	"crypto/sha1"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/alist-org/alist/v3/pkg/utils"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/alist-org/alist/v3/drivers/base"
 | 
			
		||||
	"github.com/go-resty/resty/v2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var AndroidAlgorithms = []string{
 | 
			
		||||
	"Gez0T9ijiI9WCeTsKSg3SMlx",
 | 
			
		||||
	"zQdbalsolyb1R/",
 | 
			
		||||
	"ftOjr52zt51JD68C3s",
 | 
			
		||||
	"yeOBMH0JkbQdEFNNwQ0RI9T3wU/v",
 | 
			
		||||
	"BRJrQZiTQ65WtMvwO",
 | 
			
		||||
	"je8fqxKPdQVJiy1DM6Bc9Nb1",
 | 
			
		||||
	"niV",
 | 
			
		||||
	"9hFCW2R1",
 | 
			
		||||
	"sHKHpe2i96",
 | 
			
		||||
	"p7c5E6AcXQ/IJUuAEC9W6",
 | 
			
		||||
	"",
 | 
			
		||||
	"aRv9hjc9P+Pbn+u3krN6",
 | 
			
		||||
	"BzStcgE8qVdqjEH16l4",
 | 
			
		||||
	"SqgeZvL5j9zoHP95xWHt",
 | 
			
		||||
	"zVof5yaJkPe3VFpadPof",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var WebAlgorithms = []string{
 | 
			
		||||
	"C9qPpZLN8ucRTaTiUMWYS9cQvWOE",
 | 
			
		||||
	"+r6CQVxjzJV6LCV",
 | 
			
		||||
	"F",
 | 
			
		||||
	"pFJRC",
 | 
			
		||||
	"9WXYIDGrwTCz2OiVlgZa90qpECPD6olt",
 | 
			
		||||
	"/750aCr4lm/Sly/c",
 | 
			
		||||
	"RB+DT/gZCrbV",
 | 
			
		||||
	"",
 | 
			
		||||
	"CyLsf7hdkIRxRm215hl",
 | 
			
		||||
	"7xHvLi2tOYP0Y92b",
 | 
			
		||||
	"ZGTXXxu8E/MIWaEDB+Sm/",
 | 
			
		||||
	"1UI3",
 | 
			
		||||
	"E7fP5Pfijd+7K+t6Tg/NhuLq0eEUVChpJSkrKxpO",
 | 
			
		||||
	"ihtqpG6FMt65+Xk+tWUH2",
 | 
			
		||||
	"NhXXU9rg4XXdzo7u5o",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	AndroidClientID      = "YNxT9w7GMdWvEOKa"
 | 
			
		||||
	AndroidClientSecret  = "dbw2OtmVEeuUvIptb1Coyg"
 | 
			
		||||
	AndroidClientVersion = "1.47.1"
 | 
			
		||||
	AndroidPackageName   = "com.pikcloud.pikpak"
 | 
			
		||||
	AndroidSdkVersion    = "2.0.4.204000"
 | 
			
		||||
	WebClientID          = "YUMx5nI8ZU8Ap8pm"
 | 
			
		||||
	WebClientSecret      = "dbw2OtmVEeuUvIptb1Coyg"
 | 
			
		||||
	WebClientVersion     = "2.0.0"
 | 
			
		||||
	WebPackageName       = "mypikpak.com"
 | 
			
		||||
	WebSdkVersion        = "8.0.3"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (d *PikPakShare) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
 | 
			
		||||
	req := base.RestyClient.R()
 | 
			
		||||
 | 
			
		||||
	token, err := d.oauth2Token.Token()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	req.SetAuthScheme(token.TokenType).SetAuthToken(token.AccessToken)
 | 
			
		||||
	req.SetHeaders(map[string]string{
 | 
			
		||||
		"User-Agent":      d.GetUserAgent(),
 | 
			
		||||
		"X-Client-ID":     d.GetClientID(),
 | 
			
		||||
		"X-Device-ID":     d.GetDeviceID(),
 | 
			
		||||
		"X-Captcha-Token": d.GetCaptchaToken(),
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if callback != nil {
 | 
			
		||||
		callback(req)
 | 
			
		||||
| 
						 | 
				
			
			@ -23,16 +80,25 @@ func (d *PikPakShare) request(url string, method string, callback base.ReqCallba
 | 
			
		|||
	if resp != nil {
 | 
			
		||||
		req.SetResult(resp)
 | 
			
		||||
	}
 | 
			
		||||
	var e RespErr
 | 
			
		||||
	var e ErrResp
 | 
			
		||||
	req.SetError(&e)
 | 
			
		||||
	res, err := req.Execute(method, url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if e.ErrorCode != 0 {
 | 
			
		||||
		return nil, errors.New(e.Error)
 | 
			
		||||
	switch e.ErrorCode {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return res.Body(), nil
 | 
			
		||||
	case 9: // 验证码token过期
 | 
			
		||||
		if err = d.RefreshCaptchaToken(GetAction(method, url), ""); err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		return d.request(url, method, callback, resp)
 | 
			
		||||
	case 10: // 操作频繁
 | 
			
		||||
		return nil, errors.New(e.ErrorDescription)
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, errors.New(e.Error())
 | 
			
		||||
	}
 | 
			
		||||
	return res.Body(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *PikPakShare) getSharePassToken() error {
 | 
			
		||||
| 
						 | 
				
			
			@ -92,3 +158,161 @@ func (d *PikPakShare) getFiles(id string) ([]File, error) {
 | 
			
		|||
	}
 | 
			
		||||
	return res, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetAction(method string, url string) string {
 | 
			
		||||
	urlpath := regexp.MustCompile(`://[^/]+((/[^/\s?#]+)*)`).FindStringSubmatch(url)[1]
 | 
			
		||||
	return method + ":" + urlpath
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Common struct {
 | 
			
		||||
	client       *resty.Client
 | 
			
		||||
	CaptchaToken string
 | 
			
		||||
	// 必要值,签名相关
 | 
			
		||||
	ClientID      string
 | 
			
		||||
	ClientSecret  string
 | 
			
		||||
	ClientVersion string
 | 
			
		||||
	PackageName   string
 | 
			
		||||
	Algorithms    []string
 | 
			
		||||
	DeviceID      string
 | 
			
		||||
	UserAgent     string
 | 
			
		||||
	// 验证码token刷新成功回调
 | 
			
		||||
	RefreshCTokenCk func(token string)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) SetUserAgent(userAgent string) {
 | 
			
		||||
	c.UserAgent = userAgent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) SetCaptchaToken(captchaToken string) {
 | 
			
		||||
	c.CaptchaToken = captchaToken
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) SetDeviceID(deviceID string) {
 | 
			
		||||
	c.DeviceID = deviceID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) GetCaptchaToken() string {
 | 
			
		||||
	return c.CaptchaToken
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) GetClientID() string {
 | 
			
		||||
	return c.ClientID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) GetUserAgent() string {
 | 
			
		||||
	return c.UserAgent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Common) GetDeviceID() string {
 | 
			
		||||
	return c.DeviceID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func generateDeviceSign(deviceID, packageName string) string {
 | 
			
		||||
 | 
			
		||||
	signatureBase := fmt.Sprintf("%s%s%s%s", deviceID, packageName, "1", "appkey")
 | 
			
		||||
 | 
			
		||||
	sha1Hash := sha1.New()
 | 
			
		||||
	sha1Hash.Write([]byte(signatureBase))
 | 
			
		||||
	sha1Result := sha1Hash.Sum(nil)
 | 
			
		||||
 | 
			
		||||
	sha1String := hex.EncodeToString(sha1Result)
 | 
			
		||||
 | 
			
		||||
	md5Hash := md5.New()
 | 
			
		||||
	md5Hash.Write([]byte(sha1String))
 | 
			
		||||
	md5Result := md5Hash.Sum(nil)
 | 
			
		||||
 | 
			
		||||
	md5String := hex.EncodeToString(md5Result)
 | 
			
		||||
 | 
			
		||||
	deviceSign := fmt.Sprintf("div101.%s%s", deviceID, md5String)
 | 
			
		||||
 | 
			
		||||
	return deviceSign
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BuildCustomUserAgent(deviceID, clientID, appName, sdkVersion, clientVersion, packageName, userID string) string {
 | 
			
		||||
	deviceSign := generateDeviceSign(deviceID, packageName)
 | 
			
		||||
	var sb strings.Builder
 | 
			
		||||
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("ANDROID-%s/%s ", appName, clientVersion))
 | 
			
		||||
	sb.WriteString("protocolVersion/200 ")
 | 
			
		||||
	sb.WriteString("accesstype/ ")
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("clientid/%s ", clientID))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("clientversion/%s ", clientVersion))
 | 
			
		||||
	sb.WriteString("action_type/ ")
 | 
			
		||||
	sb.WriteString("networktype/WIFI ")
 | 
			
		||||
	sb.WriteString("sessionid/ ")
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("deviceid/%s ", deviceID))
 | 
			
		||||
	sb.WriteString("providername/NONE ")
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("devicesign/%s ", deviceSign))
 | 
			
		||||
	sb.WriteString("refresh_token/ ")
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("sdkversion/%s ", sdkVersion))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("datetime/%d ", time.Now().UnixMilli()))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("usrno/%s ", userID))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("appname/android-%s ", appName))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("session_origin/ "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("grant_type/ "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("appid/ "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("clientip/ "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("devicename/Xiaomi_M2004j7ac "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("osversion/13 "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("platformversion/10 "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("accessmode/ "))
 | 
			
		||||
	sb.WriteString(fmt.Sprintf("devicemodel/M2004J7AC "))
 | 
			
		||||
 | 
			
		||||
	return sb.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RefreshCaptchaToken 刷新验证码token
 | 
			
		||||
func (d *PikPakShare) RefreshCaptchaToken(action, userID string) error {
 | 
			
		||||
	metas := map[string]string{
 | 
			
		||||
		"client_version": d.ClientVersion,
 | 
			
		||||
		"package_name":   d.PackageName,
 | 
			
		||||
		"user_id":        userID,
 | 
			
		||||
	}
 | 
			
		||||
	metas["timestamp"], metas["captcha_sign"] = d.Common.GetCaptchaSign()
 | 
			
		||||
	return d.refreshCaptchaToken(action, metas)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCaptchaSign 获取验证码签名
 | 
			
		||||
func (c *Common) GetCaptchaSign() (timestamp, sign string) {
 | 
			
		||||
	timestamp = fmt.Sprint(time.Now().UnixMilli())
 | 
			
		||||
	str := fmt.Sprint(c.ClientID, c.ClientVersion, c.PackageName, c.DeviceID, timestamp)
 | 
			
		||||
	for _, algorithm := range c.Algorithms {
 | 
			
		||||
		str = utils.GetMD5EncodeStr(str + algorithm)
 | 
			
		||||
	}
 | 
			
		||||
	sign = "1." + str
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// refreshCaptchaToken 刷新CaptchaToken
 | 
			
		||||
func (d *PikPakShare) refreshCaptchaToken(action string, metas map[string]string) error {
 | 
			
		||||
	param := CaptchaTokenRequest{
 | 
			
		||||
		Action:       action,
 | 
			
		||||
		CaptchaToken: d.GetCaptchaToken(),
 | 
			
		||||
		ClientID:     d.ClientID,
 | 
			
		||||
		DeviceID:     d.GetDeviceID(),
 | 
			
		||||
		Meta:         metas,
 | 
			
		||||
	}
 | 
			
		||||
	var e ErrResp
 | 
			
		||||
	var resp CaptchaTokenResponse
 | 
			
		||||
	_, err := d.request("https://user.mypikpak.com/v1/shield/captcha/init", http.MethodPost, func(req *resty.Request) {
 | 
			
		||||
		req.SetError(&e).SetBody(param)
 | 
			
		||||
	}, &resp)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if e.IsError() {
 | 
			
		||||
		return errors.New(e.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//if resp.Url != "" {
 | 
			
		||||
	//	return fmt.Errorf(`need verify: <a target="_blank" href="%s">Click Here</a>`, resp.Url)
 | 
			
		||||
	//}
 | 
			
		||||
 | 
			
		||||
	if d.Common.RefreshCTokenCk != nil {
 | 
			
		||||
		d.Common.RefreshCTokenCk(resp.CaptchaToken)
 | 
			
		||||
	}
 | 
			
		||||
	d.Common.SetCaptchaToken(resp.CaptchaToken)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue