Spaces:
Paused
Paused
package middleware | |
import ( | |
"encoding/base64" | |
"encoding/json" | |
"fmt" | |
"net/http" | |
"os" | |
"strings" | |
"time" | |
"github.com/gin-gonic/gin" | |
"github.com/linweiyuan/go-chatgpt-api/api" | |
) | |
const ( | |
emptyAccessTokenErrorMessage = "please provide a valid access token or api key in 'Authorization' header" | |
accessTokenHasExpiredErrorMessage = "the accessToken for account %s has expired" | |
) | |
type AccessToken struct { | |
HTTPSAPIOpenaiComProfile struct { | |
Email string `json:"email"` | |
EmailVerified bool `json:"email_verified"` | |
} `json:"https://api.openai.com/profile"` | |
HTTPSAPIOpenaiComAuth struct { | |
UserID string `json:"user_id"` | |
} `json:"https://api.openai.com/auth"` | |
Iss string `json:"iss"` | |
Sub string `json:"sub"` | |
Aud []string `json:"aud"` | |
Iat int `json:"iat"` | |
Exp int `json:"exp"` | |
Azp string `json:"azp"` | |
Scope string `json:"scope"` | |
} | |
func Authorization() gin.HandlerFunc { | |
return func(c *gin.Context) { | |
authorization := c.GetHeader(api.AuthorizationHeader) | |
if authorization == "" { | |
authorization = c.GetHeader(api.XAuthorizationHeader) | |
} | |
if authorization == "" { | |
if c.Request.URL.Path == "/" { | |
c.Header("Content-Type", "text/plain") | |
} else if strings.HasSuffix(c.Request.URL.Path, "/login") || | |
strings.HasPrefix(c.Request.URL.Path, "/chatgpt/public-api") || | |
(strings.HasPrefix(c.Request.URL.Path, "/imitate") && os.Getenv("IMITATE_ACCESS_TOKEN") != "") { | |
c.Header("Content-Type", "application/json") | |
} else if c.Request.URL.Path == "/favicon.ico" { | |
c.Abort() | |
return | |
} else { | |
c.AbortWithStatusJSON(http.StatusUnauthorized, api.ReturnMessage(emptyAccessTokenErrorMessage)) | |
return | |
} | |
c.Next() | |
} else { | |
if expired := isExpired(c); expired { | |
c.AbortWithStatusJSON(http.StatusUnauthorized, api.ReturnMessage(fmt.Sprintf(accessTokenHasExpiredErrorMessage, c.GetString(api.EmailKey)))) | |
return | |
} | |
c.Set(api.AuthorizationHeader, authorization) | |
} | |
} | |
} | |
func isExpired(c *gin.Context) bool { | |
accessToken := c.GetHeader(api.AuthorizationHeader) | |
split := strings.Split(accessToken, ".") | |
if len(split) == 3 { | |
rawDecodedText, _ := base64.RawStdEncoding.DecodeString(split[1]) | |
var accessToken AccessToken | |
json.Unmarshal(rawDecodedText, &accessToken) | |
c.Set(api.EmailKey, accessToken.HTTPSAPIOpenaiComProfile.Email) | |
exp := int64(accessToken.Exp) | |
expTime := time.Unix(exp, 0) | |
now := time.Now() | |
return now.After(expTime) | |
} | |
// apiKey | |
return false | |
} | |