fix(aliyundrive_open): retry refresh token if sub not match

This commit is contained in:
Andy Hsu 2023-08-08 22:08:05 +08:00
parent 95386d777b
commit b91ed7a78a

View File

@ -2,9 +2,11 @@ package aliyundrive_open
import ( import (
"context" "context"
"encoding/base64"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"github.com/alist-org/alist/v3/drivers/base" "github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/op" "github.com/alist-org/alist/v3/internal/op"
@ -15,7 +17,7 @@ import (
// do others that not defined in Driver interface // do others that not defined in Driver interface
func (d *AliyundriveOpen) refreshToken() error { func (d *AliyundriveOpen) _refreshToken() (string, string, error) {
url := d.base + "/oauth/access_token" url := d.base + "/oauth/access_token"
if d.OauthTokenURL != "" && d.ClientID == "" { if d.OauthTokenURL != "" && d.ClientID == "" {
url = d.OauthTokenURL url = d.OauthTokenURL
@ -34,15 +36,54 @@ func (d *AliyundriveOpen) refreshToken() error {
SetError(&e). SetError(&e).
Post(url) Post(url)
if err != nil { if err != nil {
return err return "", "", err
} }
log.Debugf("[ali_open] refresh token response: %s", res.String()) log.Debugf("[ali_open] refresh token response: %s", res.String())
if e.Code != "" { if e.Code != "" {
return fmt.Errorf("failed to refresh token: %s", e.Message) return "", "", fmt.Errorf("failed to refresh token: %s", e.Message)
} }
refresh, access := utils.Json.Get(res.Body(), "refresh_token").ToString(), utils.Json.Get(res.Body(), "access_token").ToString() refresh, access := utils.Json.Get(res.Body(), "refresh_token").ToString(), utils.Json.Get(res.Body(), "access_token").ToString()
if refresh == "" { if refresh == "" {
return errors.New("failed to refresh token: refresh token is empty") return "", "", errors.New("failed to refresh token: refresh token is empty")
}
curSub, err := getSub(d.RefreshToken)
if err != nil {
return "", "", err
}
newSub, err := getSub(refresh)
if err != nil {
return "", "", err
}
if curSub != newSub {
return "", "", errors.New("failed to refresh token: sub not match")
}
return refresh, access, nil
}
func getSub(token string) (string, error) {
segments := strings.Split(token, ".")
if len(segments) != 3 {
return "", errors.New("not a jwt token because of invalid segments")
}
bs, err := base64.StdEncoding.DecodeString(segments[1])
if err != nil {
return "", errors.New("failed to decode jwt token")
}
return utils.Json.Get(bs, "sub").ToString(), nil
}
func (d *AliyundriveOpen) refreshToken() error {
refresh, access, err := d._refreshToken()
for i := 0; i < 3; i++ {
if err == nil {
break
} else {
log.Errorf("[ali_open] failed to refresh token: %s", err)
}
refresh, access, err = d._refreshToken()
}
if err != nil {
return err
} }
log.Infof("[ali_open] toekn exchange: %s -> %s", d.RefreshToken, refresh) log.Infof("[ali_open] toekn exchange: %s -> %s", d.RefreshToken, refresh)
d.RefreshToken, d.AccessToken = refresh, access d.RefreshToken, d.AccessToken = refresh, access