schmorrison / Zoho

Golang API for Zoho services
MIT License
35 stars 34 forks source link

Printing the GenerateTokenRequest URL shows a valid link, but still returns ErrTokenInvalidCode #29

Closed Jammizzle closed 3 years ago

Jammizzle commented 3 years ago

I've failed at the first hurdle it seems!

I'm trying to create an access and request token using the below, but I'm getting hit with the default "invalid_code" error:

func main() {
    logging.Info("Starting cron...")
    z := zoho.New()
    z.SetZohoTLD("eu")

    if err := z.GenerateTokenRequest(os.Getenv("CLIENT_ID"), os.Getenv("CLIENT_SECRET"), os.Getenv("CODE"), "ignore"); err != nil {
        log.Fatal(err)
    }
}

I had a look at the url copying the same method you do before the POST with:

func main() {
    logging.Info("Starting cron...")
    z := zoho.New()
    z.SetZohoTLD("eu")

    q := url.Values{}
    q.Set("client_id", os.Getenv("CLIENT_ID"))
    q.Set("client_secret", os.Getenv("CLIENT_SECRET"))
    q.Set("code", os.Getenv("CODE"))
    q.Set("redirect_uri", "ignore")
    q.Set("grant_type", "authorization_code")

    // tokenURL := fmt.Sprintf("%s%s?%s", z.oauth.baseURL, oauthGenerateTokenRequestSlug, q.Encode())
    // log.Println(tokenURL)
    // resp, err := z.client.Post(tokenURL, "application/x-www-form-urlencoded", nil)
    // if err != nil {
    //  return fmt.Errorf("Failed while requesting generate token: %s", err)
    // }

        // Printing Z shows the oauth.baseurl as "https://accounts.zoho.eu/oauth/v2/"
    logging.Infof("https://accounts.zoho.eu/oauth/v2/token?%s", q.Encode())

    if err := z.GenerateTokenRequest(os.Getenv("CLIENT_ID"), os.Getenv("CLIENT_SECRET"), os.Getenv("CODE"), "ignore"); err != nil {
        log.Fatal(err)
    }
}

If I take the output from the logging.Info() line and paste it into postman, I get a successful response back with the auth and refresh token, but the code fails for "invalid_code"

Am I missing a step in the setup?

Jammizzle commented 3 years ago

Of course as soon as I create the ticket, my next run works... how odd

I'll leave this here in case there is something blaringly wrong with the above implementation, if there isn't then feel free to close away :)

schmorrison commented 3 years ago

Yeah, I'm not sure what coulda happened. Sorta, kinda sounds like somehow Postman had something to do with it.

If at some point you create new id/secret on zoho, and have a similar issue, please report it. I feel like I had a similar weirdness back when I was starting this project.

There might be a stupid statement in the GenerateTokenRequest function. It checks for a saved token, and

func (z *Zoho) GenerateTokenRequest(clientID, clientSecret, code, redirectURI string) (err error) {

    z.oauth.clientID = clientID
    z.oauth.clientSecret = clientSecret
    z.oauth.redirectURI = redirectURI

    err = z.CheckForSavedTokens()
    if err == ErrTokenExpired {
        return z.RefreshTokenRequest()
    }

I'm forgetting how this should work. It checks for a saved tokens file, if the token is expired (what does a 0 value Expiry or empty file return in CheckExpiry()??) we try to refresh the token instead of generating a new one, and simply return the result of the refresh call. The refresh call uses q.Set("grant_type", "refresh_token") and returns an error.

if tokenResponse.Error == "invalid_code" {
    return ErrTokenInvalidCode
}

If you experience this issue again, this is the first place I'd look.