Sample code for 30+ languages & platforms
PureBasic

Automatically Refresh Token for 401 Unauthorized

See more Google Calendar Examples

Demonstrates how to automatically refresh an access token (without user interaction) when the token expires and a 401 Unauthorized response is received.

Chilkat PureBasic Downloads

PureBasic
IncludeFile "CkHttp.pb"
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkJsonObject.pb"
IncludeFile "CkOAuth2.pb"

Procedure ChilkatExample()

    success.i = 0

    ; This example requires the Chilkat API to have been previously unlocked.
    ; See Global Unlock Sample for sample code.

    tokenFilePath.s = "qa_data/tokens/googleCalendar.json"

    ; Get our current access token.
    jsonToken.i = CkJsonObject::ckCreate()
    If jsonToken.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    success = CkJsonObject::ckLoadFile(jsonToken,tokenFilePath)
    If CkJsonObject::ckHasMember(jsonToken,"access_token") = 0
        Debug "No access token found."
        CkJsonObject::ckDispose(jsonToken)
        ProcedureReturn
    EndIf

    http.i = CkHttp::ckCreate()
    If http.i = 0
        Debug "Failed to create object."
        ProcedureReturn
    EndIf

    CkHttp::setCkAuthToken(http, CkJsonObject::ckStringOf(jsonToken,"access_token"))

    jsonResponse.s = CkHttp::ckQuickGetStr(http,"https://www.googleapis.com/calendar/v3/users/me/calendarList")
    If CkHttp::ckLastMethodSuccess(http) <> 1

        If CkHttp::ckLastStatus(http) <> 401
            Debug CkHttp::ckLastErrorText(http)
            Debug "----"
            Debug CkHttp::ckLastResponseBody(http)
            CkJsonObject::ckDispose(jsonToken)
            CkHttp::ckDispose(http)
            ProcedureReturn
        EndIf

        ; The access token must've expired. 
        ; Refresh the access token and then retry the request.
        oauth2.i = CkOAuth2::ckCreate()
        If oauth2.i = 0
            Debug "Failed to create object."
            ProcedureReturn
        EndIf

        CkOAuth2::setCkTokenEndpoint(oauth2, "https://www.googleapis.com/oauth2/v4/token")

        ; Replace these with actual values.
        CkOAuth2::setCkClientId(oauth2, "GOOGLE-CLIENT-ID")
        CkOAuth2::setCkClientSecret(oauth2, "GOOGLE-CLIENT-SECRET")

        ; Get the "refresh_token"
        CkOAuth2::setCkRefreshToken(oauth2, CkJsonObject::ckStringOf(jsonToken,"refresh_token"))

        ; Send the HTTP POST to refresh the access token..
        success = CkOAuth2::ckRefreshAccessToken(oauth2)
        If success <> 1
            Debug CkOAuth2::ckLastErrorText(oauth2)
            CkJsonObject::ckDispose(jsonToken)
            CkHttp::ckDispose(http)
            CkOAuth2::ckDispose(oauth2)
            ProcedureReturn
        EndIf

        ; The response contains a new access token, but we must keep
        ; our existing refresh token for when we need to refresh again in the future.
        CkJsonObject::ckUpdateString(jsonToken,"access_token",CkOAuth2::ckAccessToken(oauth2))

        ; Save the new JSON access token response to a file.
        sbJson.i = CkStringBuilder::ckCreate()
        If sbJson.i = 0
            Debug "Failed to create object."
            ProcedureReturn
        EndIf

        CkJsonObject::setCkEmitCompact(jsonToken, 0)
        CkJsonObject::ckEmitSb(jsonToken,sbJson)
        CkStringBuilder::ckWriteFile(sbJson,tokenFilePath,"utf-8",0)

        Debug "OAuth2 authorization granted!"
        Debug "New Access Token = " + CkOAuth2::ckAccessToken(oauth2)

        ; re-try the original request.
        CkHttp::setCkAuthToken(http, CkOAuth2::ckAccessToken(oauth2))
        jsonResponse = CkHttp::ckQuickGetStr(http,"https://www.googleapis.com/calendar/v3/users/me/calendarList")
        If CkHttp::ckLastMethodSuccess(http) <> 1
            Debug CkHttp::ckLastErrorText(http)
            CkJsonObject::ckDispose(jsonToken)
            CkHttp::ckDispose(http)
            CkOAuth2::ckDispose(oauth2)
            CkStringBuilder::ckDispose(sbJson)
            ProcedureReturn
        EndIf

    EndIf

    Debug jsonResponse
    Debug "-----------------------------"


    CkJsonObject::ckDispose(jsonToken)
    CkHttp::ckDispose(http)
    CkOAuth2::ckDispose(oauth2)
    CkStringBuilder::ckDispose(sbJson)


    ProcedureReturn
EndProcedure