fix: validate app tokens via user credential
This commit is contained in:
parent
f396a19298
commit
d00216ebbc
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"chatapp3-golang/internal/config"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -11,6 +12,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
@ -19,8 +21,12 @@ type Client struct {
|
||||
}
|
||||
|
||||
type UserCredential struct {
|
||||
UserID Int64Value `json:"userId"`
|
||||
SysOrigin string `json:"sysOrigin"`
|
||||
UserID Int64Value `json:"userId"`
|
||||
SysOrigin string `json:"sysOrigin"`
|
||||
ExpireTime Int64Value `json:"expireTime"`
|
||||
ReleaseTime Int64Value `json:"releaseTime"`
|
||||
Version string `json:"version"`
|
||||
Sign string `json:"sign"`
|
||||
}
|
||||
|
||||
type UserProfile struct {
|
||||
@ -113,7 +119,13 @@ func New(cfg config.Config) *Client {
|
||||
}
|
||||
|
||||
func (c *Client) AuthenticateToken(ctx context.Context, token string) (UserCredential, error) {
|
||||
endpoint := c.cfg.JavaAuthBaseURL + "/auth/client/getUserCredentialByToken?token=" + url.QueryEscape(token)
|
||||
tokenCredential, err := parseUserCredentialToken(token)
|
||||
if err != nil {
|
||||
return UserCredential{}, err
|
||||
}
|
||||
|
||||
endpoint := c.cfg.JavaAuthBaseURL + "/auth/client/getUserCredential?userId=" +
|
||||
url.QueryEscape(strconv.FormatInt(int64(tokenCredential.UserID), 10))
|
||||
var resp resultResponse[UserCredential]
|
||||
if err := c.getJSON(ctx, endpoint, nil, &resp); err != nil {
|
||||
return UserCredential{}, err
|
||||
@ -121,7 +133,73 @@ func (c *Client) AuthenticateToken(ctx context.Context, token string) (UserCrede
|
||||
if int64(resp.Body.UserID) == 0 {
|
||||
return UserCredential{}, fmt.Errorf("empty credential response")
|
||||
}
|
||||
return resp.Body, nil
|
||||
if strings.TrimSpace(resp.Body.Sign) == "" {
|
||||
return UserCredential{}, fmt.Errorf("empty credential sign")
|
||||
}
|
||||
if !strings.EqualFold(strings.TrimSpace(resp.Body.Sign), strings.TrimSpace(tokenCredential.Sign)) {
|
||||
return UserCredential{}, fmt.Errorf("credential sign mismatch")
|
||||
}
|
||||
if strings.TrimSpace(resp.Body.SysOrigin) != "" && !strings.EqualFold(resp.Body.SysOrigin, tokenCredential.SysOrigin) {
|
||||
return UserCredential{}, fmt.Errorf("credential sysOrigin mismatch")
|
||||
}
|
||||
return tokenCredential, nil
|
||||
}
|
||||
|
||||
func parseUserCredentialToken(token string) (UserCredential, error) {
|
||||
token = strings.TrimSpace(token)
|
||||
if token == "" {
|
||||
return UserCredential{}, fmt.Errorf("token is blank")
|
||||
}
|
||||
|
||||
parts := strings.SplitN(token, ".", 2)
|
||||
if len(parts) != 2 {
|
||||
return UserCredential{}, fmt.Errorf("invalid token format")
|
||||
}
|
||||
|
||||
sign := strings.TrimSpace(parts[0])
|
||||
if sign == "" {
|
||||
return UserCredential{}, fmt.Errorf("invalid token sign")
|
||||
}
|
||||
|
||||
decoded, err := base64.StdEncoding.DecodeString(parts[1])
|
||||
if err != nil {
|
||||
return UserCredential{}, fmt.Errorf("decode token payload: %w", err)
|
||||
}
|
||||
|
||||
payload, err := url.QueryUnescape(string(decoded))
|
||||
if err != nil {
|
||||
return UserCredential{}, fmt.Errorf("unescape token payload: %w", err)
|
||||
}
|
||||
|
||||
items := strings.Split(payload, ":")
|
||||
if len(items) != 5 {
|
||||
return UserCredential{}, fmt.Errorf("invalid token payload")
|
||||
}
|
||||
|
||||
userID, err := strconv.ParseInt(strings.TrimSpace(items[1]), 10, 64)
|
||||
if err != nil {
|
||||
return UserCredential{}, fmt.Errorf("invalid token userId: %w", err)
|
||||
}
|
||||
expireTime, err := strconv.ParseInt(strings.TrimSpace(items[3]), 10, 64)
|
||||
if err != nil {
|
||||
return UserCredential{}, fmt.Errorf("invalid token expireTime: %w", err)
|
||||
}
|
||||
releaseTime, err := strconv.ParseInt(strings.TrimSpace(items[4]), 10, 64)
|
||||
if err != nil {
|
||||
return UserCredential{}, fmt.Errorf("invalid token releaseTime: %w", err)
|
||||
}
|
||||
if expireTime <= time.Now().UnixMilli() {
|
||||
return UserCredential{}, fmt.Errorf("token expired")
|
||||
}
|
||||
|
||||
return UserCredential{
|
||||
UserID: Int64Value(userID),
|
||||
SysOrigin: strings.TrimSpace(items[2]),
|
||||
ExpireTime: Int64Value(expireTime),
|
||||
ReleaseTime: Int64Value(releaseTime),
|
||||
Version: strings.TrimSpace(items[0]),
|
||||
Sign: sign,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) GetDeviceFingerprint(ctx context.Context, userID int64) (string, error) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user