PhoneGap is a tool that can help you make hybrid applications for different devices such as Android and iOS using HTML, CSS and JavaScript. However, there are a few differences when compared to normal websites and native apps. You would have to use plugins to do tasks that traditional websites do with ease – for example, to upload a file you would have to use the File Transfer plugin and use a different API than adding inputs with a type attribute set to file.
The concept is that you would use HTML,CSS and JavaScript to create your application but you would have to approach things a bit differently to get more complicated apps up and running. To create a log in system with different social networks is one example.
In this brief tutorial, we are going to show you how to login the user with Google, Facebook and LinkedIn within a PhoneGap application.
In traditional web apps, you would just redirect the user to the social network’s authentication page, and then the users would be returned to one of your pages. However, with PhoneGap you do not have any URL to return them to. That is why one approach to handle this is to use the PhoneGap’s InAppBrowser plugin which is a browser with some added hooks. Using this plugin, you can redirect them to any page and set up listeners for when a new page loads in the browser. When the new page loads, you can check if the URL matches the URL of the success page that you set in the request for authentication with the social network – and if it matches – you can then search for an access token within the URL which you can afterwards use to get user data when needed.
A drawback of this approach is that your client secret key with the social network may be hardcoded within the PhoneGap application. If a user examines your code, he/she can find it and present himself/herself as your application, which is a situation you would have to reflect upon.
The code below relies on jQuery and the PhoneGap InAppBrowser plugin.
To login with Facebook, there is a method that takes the Facebook’s app id and app secret which you can get by creating a new app at: https://developers.facebook.com/apps/ and a success callback which will be called with the access token if the user has been successfully logged in. The function itself opens the Facebook authentication page with the InAppBrowser and sets up listeners for when a page loads. When a page loads, it checks if the URL matches the redirect_uri parameter and if there is an access token. If that is the case – we know that the user has been successfully authenticated, so we parse the access token and call the callback. We also save the token in localStorage for later usage.
var facebookLogin = function(appId, appSecret, successCb,errCb) {
var ref = window.open("https://www.facebook.com/dialog/oauth?display=popup&response_type=token&client_id="+appId+"&redirect_uri="+"http://anyurlhere.com", "_blank", "location=no");
ref.addEventListener("loadstop", function(evt) {
if (evt.url.indexOf("anyurlhere.com") !== -1) {
if (evt.url.indexOf("#access_token") !== -1) {
localStorage.fbToken = evt.url.split("#access_token=")[1];
ref.close();
ref.addEventListener("exit", function() {
successCb(localStorage.fbToken);
})
}
}
})
}
The situation is very similar with LinkedIn. We do basically the same things but change the URLs.The situation is very similar with LinkedIn. We do basically the same things but change the URLs.
var linkedinLogin = function(appId,appSecret,successCb,errCb) {
var ref = window.open("https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id="+appId+"&redirect_uri="+(encodeURI("http://anyurlhere.com"))+"&state=987654321&scope=r_basicprofile", "_blank", "location=no");
ref.addEventListener("loadstop", function(evt) {
if (evt.url.indexOf("anyurlhere.com") !== -1) {
if (evt.url.indexOf("code=") !== -1) {
var code = evt.url.split("code=")[1];
code = code.split("&")[0];
//TODO: get actual token to access user profile
$.post("https://www.linkedin.com/oauth/v2/accessToken", {"grant_type": "authorization_code", "code": code, "redirect_uri":encodeURI("http://anyurlhere.com"), "client_id":appId,"client_secret":appSecret}, function(data) {
for (key in data) {
if (key == 'access_token') {
localStorage.linkedinToken = data[key];
ref.close();
ref.addEventListener("exit", function() {
successCb(localStorage.linkedinToken);
})
}
}
})
}
}
})
}
With Google, nothing substantial changes:With Google, nothing substantial changes:
var googleLogin = function(appId, appSecret, successCb, errCb) {
var ref = window.open("https://accounts.google.com/o/oauth2/v2/auth?response_type=token&client_id=" + appId + "&redirect_uri="+encodeURI("http://anyurlhere.com")+"&scope="+encodeURIComponent("email profile")+"&state=profile", "_blank", "location=no");
ref.addEventListener("loadstop", function(evt) {
if (evt.url.indexOf("anyurlhere.com") !== -1) {
if (evt.url.indexOf("access_token=") !== -1) {
var accessToken = evt.url.split("access_token=")[1];
accessToken = accessToken.split("&")[0];
localStorage.gToken = accessToken;
ref.close();
ref.addEventListener("exit", function() {
successCb(localStorage.gToken);
})
}
}
})
}
Now, if you want to get the user’s profile information, you can use the token that we have saved to localStorage. For example, to get the user’s profile information with Google, we just need to make a request to the URL shown below and pass it the saved access token.
var getGoogleInfo = function(successCb, errCb) {
//get basic user profile
$.get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=" + localStorage.gToken, function(userInfo) {
successCb(userInfo);
})
}
To get the user’s Facebook details, the approach is the same; there is no more need of InAppBrowser. We can make a request to their API endpoint, get the JSON data, and extract the information from their response that we need.
var getFacebookInfo = function(successCb, errCb) {
//get basic user profile-name
$.get("https://graph.facebook.com/me?fields=email,name,picture&access_token=" + localStorage.fbToken, function(userInfo) {
var myInfo = {};
if (userInfo.name) {
myInfo.name = userInfo.name;
}
if (userInfo.email) {
myInfo.email = userinfo.email;
}
if (userInfo.picture) {
myInfo.picture = userInfo.picture.data.url;
}
localStorage.myInfo = JSON.stringify(myInfo);
successCb(myInfo);
// localStorage.myInfo = myInfo;
})
}