Archived Forum Post

Index of archived forum posts

Question:

Gmail with OAuth and Xojo

Feb 02 '16 at 10:20

Hi,

I'm trying to connect to Google Apps Gmail with OAuth. With the totally clear instructions on the Google websites I hope I have set up everything correctly.

  1. Changed the MX record for one of my domains and verified the domain.
  2. Got a p12 file.
  3. Set up a service email address for the main project.

When I run the following code (basically the example):

  Dim http As New Chilkat.Http
  Dim success As Boolean = http.UnlockComponent("Anything for 30-day trial")
  If (success <> True) Then
    System.DebugLog(http.LastErrorText)
    Return
  End If

//  Begin by loading the downloaded .p12 into a Chilkat certificate object:
  Dim cert As New Chilkat.Cert
  success = cert.LoadPfxFile("/Users/beatrixwillius/Desktop/test-550c6e932e47.p12","notasecret")
  If (success <> True) Then
    msgbox(cert.LastErrorText)
    Return
  End If

Dim iss As String = "mailarchiver@api-project-83766207457.iam.gserviceaccount.com"
  Dim scope As String = "https://mail.google.com/"
  Dim numSec As Int32 = 3600

Dim accessToken As String = http.G_SvcOauthAccessToken(iss,scope,"",numSec,cert)
  If (http.LastMethodSuccess <> True) Then
    System.DebugLog(http.LastErrorText)
    Return
  Else
    System.DebugLog("access token: " + accessToken)
  End If

I get an empty accessToken. But LastErrorText is only:

ChilkatLog:
  get_OAuthVerifier:
    ChilkatVersion: 9.5.0.56
  --get_OAuthVerifier
--ChilkatLog

If I change the iss value to something like "xxxxmailarchiver@api-project-83766207457.iam.gserviceaccount.com" I get the following as response:

31.01.16 11:24:27,670 test.debug[16145]: ChilkatLog:
  G_SvcOauthAccessToken2:
    DllDate: Jan 26 2016
    ChilkatVersion: 9.5.0.56
    UnlockPrefix: Anything for 30-day trial
    Architecture: Little Endian; 32-bit
    Language: MAC OS X C/C++
    VerboseLogging: 0
    iss: xxxxxxmailarchiver@api-project-83766207457.iam.gserviceaccount.com
    scope: https://mail.google.com/
    sub: 
    aud: https://accounts.google.com/o/oauth2/token
    jwtHeader64: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
    jwtClaimSet: {"iss":"xxxxxxmailarchiver@api-project-83766207457.iam.gserviceaccount.com","scope":"https://mail.google.com/","aud":"https://accounts.google.com/o/oauth2/token","exp":1454239462,"iat":1454235862}
    fullRequest:
      a_synchronousRequest:
        generateRequestHeader:
          httpRequestGenStartLine:
            genStartLine:
              startLine: POST /o/oauth2/token HTTP/1.1
            --genStartLine
          --httpRequestGenStartLine
          addCookies:
            Not auto-adding cookies.
            sendCookies: 1
            cookieDir: 
          --addCookies
        --generateRequestHeader
        fullHttpRequest:
          domain: accounts.google.com
          port: 443
          ssl: 1
          openHttpConnection:
            Opening connection directly to HTTP server.
            httpHostname: accounts.google.com
            httpPort: 443
            ssl: 1
            socket2Connect:
              connect2:
                connectImplicitSsl:
                  clientHandshake:
                    clientHandshake2:
                      buildClientKeyExchange:
                        buildClientKeyExchangeECDHE:
                          Verified server key exchange.
                        --buildClientKeyExchangeECDHE
                      --buildClientKeyExchange
                    --clientHandshake2
                  --clientHandshake
                --connectImplicitSsl
              --connect2
            --socket2Connect
            HTTPS secure channel established.
          --openHttpConnection
          connectTime: Elapsed time: 376 millisec
          sendRequestHeader:
            sendHeaderElapsedMs: 0
          --sendRequestHeader
          sendRequestBody:
            sendBodyElapsedMs: 1
          --sendRequestBody
          statusCode: 400
          statusText: Bad Request
          readResponseBody:
            Response is chunked.
          --readResponseBody
        --fullHttpRequest
        success: 1
      --a_synchronousRequest
      success: 1
    --fullRequest
    charsetFromContentType: utf-8
    charset: utf-8
    access_token not found.
    Failed.
  --G_SvcOauthAccessToken2
--ChilkatLog

What am I doing wrong?

Using latest Chilkat plugin from yesterday. Xojo 2015r4.

PS: is it possible to get a version of LoadPfxFile that has a folderitem as parameter? Using a string instead of a folderitem is very unusual on the Mac.

Mit freundlichen Grüßen/Regards

Trixi Willius

http://www.mothsoftware.com Mail Archiver X: The email archiving solution for professionals


Answer

Hi Trixi,

I have a few quick points to begin:

1) The LastErrorText contains information for the last method called (and often for the last property accessed). The 2nd line in the LastErrorText shows the method or property. In the first "LastErrorText" you posted, it was for the access to the OAuthVerifier property. If you meant to get the LastErrorText for G_SvcOauthAccessToken2, it means that after calling G_SvcOauthAccessToken2, but before getting the value of LastErrorText, your program accessed the OAuthVerifier property and overwrote the information in LastErrorText. Always verify that the name of the method/property shown in the LastErrorText matches the name/property of what you think it should be. Otherwise, the last method called was not what you thought..

2) The arguments cannot use things that are platform specific, such as a FolderItem. Chilkat is cross-platofrm, cross-operating-system, and cross-language, and therefore arguments must be in a portable type.

I'm not sure exactly why you got the "400 Bad Request". My guess is that the 3rd argument to G_SvcOauthAccessToken is an empty string and should be an email address.


Answer

1) I've put a breakpoint in the line after

Dim accessToken As String = http.G_SvcOauthAccessToken(iss,scope,"",numSec,cert)

and still get the following as LastError:

ChilkatLog: get_OAuthVerifier: ChilkatVersion: 9.5.0.56 --get_OAuthVerifier --ChilkatLog

2) OK. Please document which type of path is used(Shell, native).

3) So sub should be the email address for the domain. This at least makes the code trying to connect to Gmail. By the way sub is a reserved work in Xojo and won't compile.

Regards

Beatrix Willius


Answer

Thanks. The problem I'm facing in try to help is that I'm not able to reproduce the problem. When I make the call to G_SvcOauthAccessToken, it works (using the values I'm passing for my particular case -- which are the same in nature but just different in content).

Try this: Set the http.SessionLogFilename property to the local path of a log file that will be created, and then send me the contents of the log file (in private email to support@chilkatsoft.com). I can then examine it to see if the format of the request is invalid somehow.

In any case, all of this might be moot anyway because from all of my (countless hours of) investigation, I've found that using OAuth2 with consumer GMail account is only possible with using 3-legged OAuth2, meaning it's a cumbersome/awkward task for the user to manually get a verifier and then copy-and-paste it into the application. See the answer to this question: http://www.chilkatforum.com/questions/9368/oauth2-gmail-authentication-fails

Regarding the points:

1) The LastErrorText contains information about the last method or property accessed. You may have called G_SvcOauthAccessToken, but in between that call and actually fetching the contents of the LastErrorText property, it must've been that the OAuthVerifier property was the last thing accessed. Remember: When you're looking at things in the debugger -- the IDE is accessing the properties of the object and thus it's setting the LastErrorText by doing that..

2) I don't understand what you mean by "shell" or "native" path. The path that's passed to any Chilkat method is passed down to the underlying system call to open the file -- where the path is a relative or absolute path in the filesystem.

3) Thanks. I'll avoid using "sub".. :-)