Sonntag, 23. Oktober 2016

Google Login with Oracle Jet - Part 2 - Combine with Oracle Jet webapplication

Introduction


This is part 2 of a series of blogs, that explain on how to use Google Sign In with Oracle Jet. For more information, please start with part 1.
  1. Google Login with Oracle Jet - Part 1 - Create Google Project
  2. Google Login with Oracle Jet - Part 2 - Combine with Oracle Jet webapplication
  3. Google Login with Oracle Jet - Part 3 - Combine with Oracle Jet hybrid application
Let's begin with the fun part. We did create a Google project and an OAuth client ID in part 1. Now we will create a basic Oracle Jet webapplication and add Sign In and Sign Out functionality to it. Besides that, we also want to read the name of the logged in user and show the picture of the logged in user.


Create Oracle Jet webapplication

We did this several times before and we will do it again. We will create really fast an Oracle Jet page, which is based on the basic template. Just enter the following commands to first create it an than build it.

$ yo oraclejet webclient --template=basic:web

$ grunt build

First steps

I did call it first steps, because I didn't find a better word and cause I didn't want to put these steps in another chapter.

1. Open Netbeans
2. Open the project which you just created
3. Create the following file
File-Location:
src/js/googlecredentials.json

File-Content:
{
    "client_id": "<LONG_UNIQUE_ID>.apps.googleusercontent.com",
    "scope": "profile email"
}

As you can see this is a JSON file, which holds the client_id. I am pretty sure, that it is not a good idea to keep your client_id here, because now everybody can read it, but I didn't find a better place to put it.

As client_id you should use the id, which has been created in Part 1 of this series of blogs. 
Go to the following URL, select your project and select Credentials (left navigation bar). Now you should be able to see your client Id again.



4. Make adjustments to the main.js file to read the googlecredentials.json file and store it in the sessionStorage as soon as the page is being loaded. The adjustments should be made in the init() function. As you can see, the credentials are being stored in an item called googlecredentials.

$.ajax({                                
url: 'js/googlecredentials.json',
dataType: 'json',
async: false,
success: function (data) {
sessionStorage.setItem('googlecredentials', JSON.stringify(data));
},
error: function (req, status, err) {
console.log('something went wrong', status, err);
}
});


Create the Javascript functionality

We do need some Javascript functions like GoogleSignIn, GoogleSignOut or IsUserLoggedIn to make this work.
Please open the appController.js file and make the following adjustments  to it.

1. First of all we have to extend the define, because the GoogleApi also has to be loaded. So please add 'https://apis.google.com/js/platform.js' to your define.

My define looks like this now. Yours can look different, but the important part is, that you add this 'https://apis.google.com/js/platform.js'

define(['ojs/ojcore', 'knockout', 'ojs/ojknockout', 'https://apis.google.com/js/platform.js'],
        function (oj, ko) {


2. Create some knockout observable parameters, that will be defined later
// Define if the user is logged in
self.isUserLoggedIn = ko.observable(false);
// Username
self.userLogin = ko.observable("");
// User Profile Picture
self.imagePath = ko.observable("");


3. Send the Client_ID to the GoogleApi and in return you get information about the logged in user, if the user is logged in. 
  • As you can see, here we send the googlecredentials.json that has been stored in the sessionStorage during the init() function of main.js.
  • We also redefine the isUserLoggedIn();
  • Since this function is placed directly inside the ControllerViewModel it will be called whenever the index.html is being loaded.

function ControllerViewModel() {
...
window.gapi.load('client:auth2', function () {                    
window.gapi.auth2.init(JSON.parse(sessionStorage.getItem('googlecredentials'))).then(function (googleAuth) {
self.googleAuth = googleAuth;
self.isUserLoggedIn(googleAuth.isSignedIn.get());
});
});
...
}



4. We write a function, which will be triggered, when the user is clicking the sign in button. 
  • This is a promise, which is entering the first function, if everything worked fine and the second function, if there was an error.
  • In case of a success I decided to set isUserLoggedIn to true and get some user profile information like picture and name.
  • In the second function, which means, that the login was not correct, we set the isUserLoggedIn to false again. Later we will see in the html, that different parts of the page will be shown, depending on this variable.

function ControllerViewModel() {
...
self.googleSignIn = function (data, event) {
window.gapi.auth2.getAuthInstance().signIn().then(
function () {
self.isUserLoggedIn(true);
self.userLogin(self.googleAuth.currentUser.get().getBasicProfile().getName());
self.imagePath(self.googleAuth.currentUser.get().getBasicProfile().getImageUrl());
self.id_token = self.googleAuth.currentUser.get().getAuthResponse().id_token;
},
function (e) {
self.isUserLoggedIn(false);
console.log(e);
});
}
...
}



5. We write a function, which will be triggered, when the user is clicking the sign out button. 
  • This is a promise, which is entering the first function, if everything worked fine and the second function, if there was an error.
  • In case of a sign out success We do reset all the user profile informatoin.
  • In the second function, which means, that the sign out was not correct, we just log the exception.

function ControllerViewModel() {
...
self.googleSignOut = function (data, event) {
window.gapi.auth2.getAuthInstance().signOut().then(
function () {
self.userLogin('Unknown');
self.imagePath('');
self.isUserLoggedIn(false);
},
function (e) {
console.log(e);
});
}
...
}




6. We write a function, which will be triggered, when the user is clicking the Disconnect button. The difference between disconnect and sign out is the following. A sign out is just signing out the user from your webapplication. A disconnect is also removing all the rights, that the user gave you. Disconnect is hardly used in this world, but quite interesting for development.
  • This is a promise, which is entering the first function, if everything worked fine and the second function, if there was an error.
  • In case of a disconnect success We do reset all the user profile informatoin.
  • In the second function, which means, that the disconnect was not correct, we just log the exception.

function ControllerViewModel() {
...
self.googleDisconnect = function (data, event) {
window.gapi.auth2.getAuthInstance().disconnect().then(
function () {
self.userLogin('Unknown');
self.imagePath('');
self.isUserLoggedIn(false);
},
function (e) {
console.log(e);
});
}
...
}


Trigger the Javascript functions from HTML

Open the index.html file and make the following adjustments.

1. Add Sign In button and make it only visible, if the user is not logged in

<div data-bind="ifnot: isUserLoggedIn">
<h1>Google Login --- Not LoggedIn</h1>
<button id="google-signin-button"
data-bind="click: googleSignIn, ojComponent: { 
component:'ojButton', label: 'Sign In',
icons: {start:'oj-fwk-icon oj-fwk-icon-signin'},
chroming: 'full'
}">
</button>
</div>





2. Add a Sign out and Disconnect button and make it only visible, if the user is logged in. Also add an image of the logged in user.

<div data-bind="if: isUserLoggedIn">
<h1>Google Login --- LoggedIn</h1>
<button id="google-signout-button"
data-bind="click: googleSignOut, ojComponent: {
component:'ojButton', label: 'Sign Out',
icons: {start:'oj-fwk-icon oj-fwk-icon-signin'},
chroming: 'full'
 }">
</button>
<button id="google-signout-button"
data-bind="click: googleDisconnect, ojComponent: {
component:'ojButton', label: 'Disconnect',
icons: {start:'oj-fwk-icon oj-fwk-icon-signin'},
chroming: 'full'
 }">
</button>
<img data-bind="attr:{src: imagePath}" /> 
</div>




3. Add the username to the page

This is the easiest part. Thanks to the nice basic template of the Oracle Jet webapplication, all we had to do was make updates to the self.userLogin observable, after the sing in has been successfull. Inside the HTML, we didn't have to do any adjustments.




4. Also make the Sign Out link in the upper right corner of the Oracle Jet basic template work.

Add a data-bind to the existing link.

<li id="out"><a data-bind="click: googleDisconnect" href="#">Sign Out</a></li>




Conclusion

As already mentioned in the introduction, it is way more fun to do this, than taking care of all the administrative stuff. 

In the end it is a solution, that makes your user happy, because, they don't have to remember a new username/password combination and it makes you happy, because you don't have to take care of usermanagement.

You also get the id_token of the user, which opens you a whole new world to the Google world (YouTube, Maps, ...). This is basically just the beginning. And it is working like a charme with Oracle Jet, because both Google and Oracle support OAuth2.0.

In the following blog, we will take a look on how to make this work with a hybrid application. We will need a cordova plugin for that.

Keine Kommentare:

Kommentar veröffentlichen