B4A Class [class][B4X] Google OAuth2

Status
Not open for further replies.

Erel

Administrator
Staff member
Licensed User
GoogleOAuth2 class is compatible with B4A, B4i and B4J (new).

It is no longer possible to use WebView to implement Google's OAuth2 authentication.
The solution is to open the default browser and set the redirection uri in such a way that the browser will redirect the response back to our app.

GoogleOAuth2 class takes care of several tasks:

1. Opening the browser and getting the authorization code.
2. Getting and saving the access token and refresh token from the authorization code.
3. Getting a new access token when it expires using the refresh token.

The process is documented here: https://developers.google.com/identity/protocols/OAuth2InstalledApp

Setup

1. Go to Google developer console, create a new project if needed and add a client id:



For the Android client you need to get the SHA-1 signature. It is available under Tools - Private Sign Key.
Set the package name or bundle identifier fields to your app's package name.

2. B4A:
Add to the manifest editor:
B4X:
AddActivityText(Main,
  <intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="$PACKAGE$" />
  </intent-filter>
   )
B4i:
Change b4i.example2 with your package name.
B4X:
#UrlScheme: b4i.example2
3. B4A code:
B4X:
Sub Activity_Resume
   oauth2.CallFromResume(Activity.GetStartingIntent)
End Sub
B4i code:
B4X:
Sub Application_OpenUrl (Url As String, Data As Object, SourceApplication As String) As Boolean
   oauth2.CallFromOpenUrl(Url)
   Return True
End Sub
B4J:
Create a new OAuth Client id with the type set to Other.
You need to add both the client id and the client secret to the project (client secret is not required in the the mobile solutions).
The Initialize methods expects two additional parameters: client secret and the path where the token will be stored.


3. Initialize GoogleOAuth2 with the required scopes (based on the API that you want to call).
Call GoogleOAuth2.GetAccessToken. The AccessTokenAvailable will be raised when the token is available.
Once you have the access token, you can access the relevant Google web service.
In this example we will access the People API. You need to enable it in Google console.
Example:
B4X:
Sub btnGetData_Click
   oauth2.GetAccessToken
   Wait For OAuth2_AccessTokenAvailable (Success As Boolean, Token As String)
   If Success = False Then
     ToastMessageShow("Error accessing account.", True)
     Return
   End If
   Dim j As HttpJob
   j.Initialize("", Me)
   j.Download2("https://people.googleapis.com/v1/people/me", _
       Array As String("access_token", Token, "requestMask.includeField", "person.email_addresses,person.birthdays,person.names"))
   Wait For (j) JobDone(j As HttpJob)
   If j.Success Then
     ParsePersonData(j.GetString)
   Else
     ToastMessageShow("Online data not available.", True)
   End If
   j.Release
End Sub








The latest version (v2.10) of GoogleOAuth2 class is attached separately. You should use that version instead of the one included in the zips.
 

Attachments

Last edited:

Intiwhiz

Member
Licensed User
Dear @Erel
why I am getting error with these code

Wait For OAuth2_AccessTokenAvailable (Success As Boolean, Token As String)
Wait For (j) JobDone(j As HttpJob)

Thanks
 

Erel

Administrator
Staff member
Licensed User
Quoting the first post:

"Note that the code uses the new resumable subs feature added in B4A v7.0 (beta will be released next week) and B4i v4.0. It makes it easier to manage asynchronous tasks.
It shouldn't be too difficult to open the project in an older version. You will need to rewrite the subs that call Wait For and implement the logic with standard events."
 

Erel

Administrator
Staff member
Licensed User
We cannot really answer this question. Please start a new thread in the questions forum. In that thread you should explain what you are trying to do and post the relevant code and logs.
 

keirS

Well-Known Member
Licensed User
Just like to point out that the B4J implementation is not to OAuth 2 specification. A Client Credentials grant is only supposed to be used for server to server authorization where a user interface is not possible. So it's fine for a B4J server app but it should not be used for a distributed desktop app. The theory behind this is a desktop app could be cracked and the Client ID and Client Secret found. See here for further details
 

Erel

Administrator
Staff member
Licensed User
That's not correct. The B4J implementation is the desktop apps implementation. It follows Google instructions: https://developers.google.com/identity/protocols/OAuth2InstalledApp

Maybe it was not clear, though you can see it if you run the project or go over the source code, the process is very similar to the mobile process. The default browser opens and the user needs to authorize your app to access the requested scopes. This is the most important step of OAuth2. The user explicitly grants access through a trusted third party application.
 
Last edited:

keirS

Well-Known Member
Licensed User
The difference is the mobile apps do not require the client secret. Storing both the Client ID and the Client Secret in a Jar file is a concern. If you can run Jetty from a UI app (never tried this) then I would be tempted to implement this as a Implicit Grant.
 

Erel

Administrator
Staff member
Licensed User
This is how the desktop implementation works. You can store the keys in a server and download them at runtime if you like.
 

Erel

Administrator
Staff member
Licensed User
V2.05 is released. It fixes an issue with the handling of the token expiration.
 

Erel

Administrator
Staff member
Licensed User
V2.10 is released. 5 minutes are removed from the expiration time to avoid cases where an expired token is used.
 

soyVB6

Active Member
Licensed User
I discovered that apparently only works with google chrome browser, try other browsers and got an ugly error ...

b4a
 

Erel

Administrator
Staff member
Licensed User
I guess that the browser must be a browser recognized by Google in some way. It will not work for example with WebView.
 

JohnC

Well-Known Member
Licensed User
Erel,

Great job on all the code you wrote for this functionality. Makes it very easy to use!

The only thing I added to it is a sub to do a quiet check if the token is valid or not without launching a browser, because the user could get confused why their browser is opening up (and also possibly show a browser intent selection box if they have multiple browsers) when they just want to send an email. This way, my app will be able to silently see the token is not valid and pop up a small window explaining what is going to happen next (that they need to do a one-time authorization to allow my app to access their google account in order to send gmails).

B4X:
Public Sub TokenValid
    Return ti.Valid
End Sub
 
Status
Not open for further replies.
Top