go-chatgpt-api-new / middleware /authorization.go
dvc890's picture
Upload 30 files
f16d50c
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
}