I got a comment about a few things on this blog post and thought I'd do a quick edit. First, when I wrote this, I just assumed anyone doing a login request would be hitting a https server. My code shows hitting a http server because at the time, that's how my blog was hosted, but I assumed people running this code in production wouldn't do that. That was wrong. So to be clear, you should be logging in to something on https only. I'm changing the code to reflect that, even though the demo itself isn't online. Secondly - I mentioned in the article how I was unsure that storing credentials in LocalStorage was a good idea. I definitely do not think it is now. I'd look at the Secure Storage wrapper I blogged about last year: Working with Ionic Native - Using Secure Storage
Yesterday I worked on a simple PhoneGap that would demonstrate how to perform a login before using the application. (Ok, technically, you are using the application when you login, but you get my drift.) I worked up a simple demo of this and then extended it to allow for automatic login after you've first successfully authenticated. This could probably be done better, but here's my first draft demo application that will hopefully be useful to others.
I began by creating a new PhoneGap application in Eclipse and included jQuery Mobile. My home page will include my login form and upon successful login I'll simply push the user to the "real" home page. Here's the login screen.
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=320; user-scalable=no" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auth Demo</title>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.0rc2.css" type="text/css" charset="utf-8" />
<script type="text/javascript" src="js/jquery-1.7.min.js"></script>
<script type="text/javascript" charset="utf-8" src="js/phonegap-1.2.0.js"></script>
<script src="jquery.mobile/jquery.mobile-1.0rc2.js"></script>
<script type="text/javascript" charset="utf-8" src="js/main.js"></script>
</head>
<body onload="init()">
<div id="loginPage" data-role="page">
<div data-role="header">
<h1>Auth Demo</h1>
</div>
<div data-role="content">
<form id="loginForm">
<div data-role="fieldcontain" class="ui-hide-label">
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" placeholder="Username" />
</div>
<div data-role="fieldcontain" class="ui-hide-label">
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="" placeholder="Password" />
</div>
<input type="submit" value="Login" id="submitButton">
</form>
</div>
<div data-role="footer">
<h4>© Camden Enterprises</h4>
</div>
</div>
</body>
</html>
I assume most of my readers are familiar with jQuery Mobile now so I won't discuss the mechanics of it above. That being said, here's a quick screen shot of how this looks.
Ok, now let's switch over to the code.
function init() {
document.addEventListener("deviceready", deviceReady, true);
delete init;
}
function deviceReady() {
$("#loginForm").on("submit",function(e) {
//disable the button so we can't resubmit while we wait
$("#submitButton",this).attr("disabled","disabled");
var u = $("#username", this).val();
var p = $("#password", this).val();
if(u != '' && p!= '') {
$.post("https://www.coldfusionjedi.com/demos/2011/nov/10/service.cfc?method=login&returnformat=json", {username:u,password:p}, function(res) {
if(res == true) {
$.mobile.changePage("some.html");
} else {
navigator.notification.alert("Your login failed", function() {});
}
$("#submitButton").removeAttr("disabled");
},"json");
}
return false;
});
}
I begin with a deviceready listenener. Technically I'm not actually using any of the phone features for this demo, but in general I think this is a good way to start up your application specific code. The code we care about is in the submit handler for my form. All we need to do when run is do an Ajax request to the server. Remember: The restriction on non-same-domain Ajax requests does not exist in a PhoneGap app. If my authentication returns true, I then use jQuery Mobile's changePage feature to shift them over to the page. (Note - my remote service is just returning a boolean. It would probably be more useful to return some data about the user. Their username for example. You get the idea I think.)
So this works - but let's ramp it up a bit. What I'd like to do is ensure that once you login with the application, you don't have to do it again. This could be optional, but for now I've made it just happen by default. I'm going to modify my code to...
- Store my username and password in local storage upon successful login
- When the application starts, check for these values, and if they exist, prepopulate the form and submit it automatically
So, my first change was just to store the values. HTML5 local storage to the rescue...
function handleLogin() {
var form = $("#loginForm");
//disable the button so we can't resubmit while we wait
$("#submitButton",form).attr("disabled","disabled");
var u = $("#username", form).val();
var p = $("#password", form).val();
console.log("click");
if(u != '' && p!= '') {
$.post("https://www.coldfusionjedi.com/demos/2011/nov/10/service.cfc?method=login&returnformat=json", {username:u,password:p}, function(res) {
if(res == true) {
//store
window.localStorage["username"] = u;
window.localStorage["password"] = p;
$.mobile.changePage("some.html");
} else {
navigator.notification.alert("Your login failed", function() {});
}
$("#submitButton").removeAttr("disabled");
},"json");
}
return false;
}
Handling the check on startup was a bit more difficult. I'm still trying to wrap my best way to handle events when working with PhoneGap and jQuery Mobile together. For my case, I wanted to populate the form fields. Therefore it made sense to do this both after the page is loaded and the page is "decorated" by jQuery Mobile. For that I needed the pageinit function. However, it is tricky to get the listener in for this. If I add it to my init function, the one called by body/onload, it's too late. A bit of Googling seems to suggest the best place is in the DOM itself. Here's how my home page looks now.
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=320; user-scalable=no" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auth Demo</title>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile-1.0rc2.css" type="text/css" charset="utf-8" />
<script type="text/javascript" src="js/jquery-1.7.min.js"></script>
<script type="text/javascript" charset="utf-8" src="js/phonegap-1.2.0.js"></script>
<script src="jquery.mobile/jquery.mobile-1.0rc2.js"></script>
<script type="text/javascript" charset="utf-8" src="js/main.js"></script>
</head>
<body onload="init()">
<div id="loginPage" data-role="page">
<div data-role="header">
<h1>Auth Demo</h1>
</div>
<div data-role="content">
<form id="loginForm">
<div data-role="fieldcontain" class="ui-hide-label">
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" placeholder="Username" />
</div>
<div data-role="fieldcontain" class="ui-hide-label">
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="" placeholder="Password" />
</div>
<input type="submit" value="Login" id="submitButton">
</form>
</div>
<div data-role="footer">
<h4>© Camden Enterprises</h4>
</div>
</div>
<script>
$("#loginPage").live("pageinit", function(e) {
checkPreAuth();
});
</script>
</body>
</html>
And here is my re-engineered main.js file:
function init() {
document.addEventListener("deviceready", deviceReady, true);
delete init;
}
function checkPreAuth() {
var form = $("#loginForm");
if(window.localStorage["username"] != undefined && window.localStorage["password"] != undefined) {
$("#username", form).val(window.localStorage["username"]);
$("#password", form).val(window.localStorage["password"]);
handleLogin();
}
}
function handleLogin() {
var form = $("#loginForm");
//disable the button so we can't resubmit while we wait
$("#submitButton",form).attr("disabled","disabled");
var u = $("#username", form).val();
var p = $("#password", form).val();
console.log("click");
if(u != '' && p!= '') {
$.post("https://www.coldfusionjedi.com/demos/2011/nov/10/service.cfc?method=login&returnformat=json", {username:u,password:p}, function(res) {
if(res == true) {
//store
window.localStorage["username"] = u;
window.localStorage["password"] = p;
$.mobile.changePage("some.html");
} else {
navigator.notification.alert("Your login failed", function() {});
}
$("#submitButton").removeAttr("disabled");
},"json");
} else {
//Thanks Igor!
navigator.notification.alert("You must enter a username and password", function() {});
$("#submitButton").removeAttr("disabled");
}
return false;
}
function deviceReady() {
$("#loginForm").on("submit",handleLogin);
}
The code you care about here is checkPreAuth. It basically looks for the existing values, and if there, sets them up in the form and automatically runs the submission. In my tests, this works well. You would probably want to configure the login failed message to handle a case where an auto-login failed. Another issue - and one I do not have a good feel for - is how secure the local storage data will be on the device. Use with caution!
Archived Comments
Ray what's up with the "var form" variable you've defined and sprinkle into the jQuery selectors? I'm not following what that is accomplishing.
I'm just caching the selector. When I use it for u, p I'm saying, "Find me this, but search WITHIN this earlier selection." Just helps keep it a bit safer I think.
OK I get what you're doing but I dont think you need two IDs in your selector. Just var u = $("#username") would suffice rather than creating the unnecessary form variable which amounts to var u = $("#loginForm #username"). It's supposedly faster to use just the one ID and it gives the added bonus of ridding those form variables you declare in each function.
My original confusion was that I hadn't used that syntax before - $("#username", form) - which looks like it would have its advantages if you were using class names rather than IDs to target your username and password elements, which you may very well do in some situations.
In jQuery Mobile, new pages are added to the DOM. If I - mistakenly - added another form with the same IDs, then there would be a conflict. So by saying, "Match a, inside b", it feels more secure.
And to conclude, I think you're right it is safer potentially if you had multiple elements with the ID "#username". So I'll grant you that. Consider using find() to do what you're attempting as in:
var form = $("#loginForm");
var u = form.find("#username");
Wouldn't it be better to move your script tag to just below the body and then cache the selectors like so? Seems more readable than sprinkling the same cached selectors in multiple function calls and could easily be added to a closure w/ module pattern to reduce the use of globals.
var $form = $("#loginForm"),
$username = $("#username"),
$password = $("#password"),
$submitButton = $("#submitButton");
Also, csslint would complain about multiple id's in selectors. Ex. #loginForm #username.
@Raymond:
You can use my Field Plug-in to make it easier to get form field values. There's a formHash() method which will return all the fields in a form as a hash/struct. By default it also hashes multiple values as a comma separated values--essentially emulating the way CF would see the data if the form was submitted to the server.
So, instead of having to grab the value for each field, you can just grab all the fields in a form.
http://www.pengoworks.com/w...
There's also a ton of other stuff you can do--including passing in a hash/struct to formHash() to fill in a form. There's many other helpers as well.
@blackjk: I could see that too. jQuery provides way too many ways to do things. ;)
@Dan: I've not had trouble w/ forms like that before... except in terms of checkboxes/radio fields, where I've had to do my own logic. Next time I need something like that I'll try to remember it. But you have to agree that would be a bit overkill for just grabbing 2 fields. :)
...
if(u != '' && p!= '') {
...
$("#submitButton").removeAttr("disabled");
}else{
navigator.notification.alert("You must enter a username and password", function() {});
$("#submitButton").removeAttr("disabled");
}
return false;
Um.... were you trying to say something Igor?
The code of the article are not taken into account when the option the user enters a username and password - the button does not stay active (it is disabled until the conditions)
Ah, great point Igor. I'm going to edit now. Your mod also adds a message to make it clear they need to enter stuff. I like that.
@Raymond:
But how many projects do you work on where you'll only ever need to grab the value for 2 form fields? :)
Seriously though, I mentioned it more because most forms become more complex and working in logic for non-text fields can become much more complex, so there's a huge advantage in using code that will automate everything for you.
I'd argue (not because it is helpful, but because I want to argue*) that a complex form may not make sense on a mobile device.
* Being honest. ;)
@Raymond:
Thanks for the demo! I've been retooling it a little and have 1 quick question. After the user has been authenticated and you come back to the application, is there anyway to supress the android prompt of Confirm: " Do you want the browser to remember the password" - Not Now, OK, Never"
@steve: I haven't tried this, but check out the recommendation here:
http://stackoverflow.com/qu...
Hi,
thanks for sharing this.
can you upload a sample of this?
or a sample how the json should look like?
V.
I'm confused - I did share the code. As for the JSON, it is just a boolean value, so it isn't that complex.
So Ray, what's enforcing the security? is it just that in the compiled native app there is no way to get to some.html? Or is my coldfusion session-based security still usable with phonegap?
CF handles the authentication. If you decrypt the PhoneGap app, you see a ajax call to some CFC, noething more.
can i use php on the server side, could you give some sample ??
.........
if(u != '' && p!= '') {
$.post("http://www.sample.com/login...", {username:u,password:p}, function(res) {
if(res == true) {
//store
...........
You can use _any_ server side language. But I can't write the PHP for you - I don't know the language.
can you show your server side source ?
http://www.coldfusionjedi.c...
Sure:
component {
remote boolean function login(string username, string password) {
if(arguments.username == "admin" && arguments.password == "password") {
session.loggedin = true;
return true;
} else return false;
}
remote numeric function randomNumber() {
return randRange(1,10000);
}
}
In case it isn't obvious, this code isn't meant to be used as is. It's a simple static username/password. Normally this would be a database query.
Hi. Is it working with phonegap 1.3.0 ?
I tried but could not be succeed :(.
There is no notification nothing. Only page changes and goes to same page.
Nothing here should stop working in the latest PhoneGap. Have you done any debugging? For example, you say the page changes. I assume you mean that it goes right away to the logged in page. That only happens if you have logged in before. Looking at line 9 in the final code above, add, right after, a simple alert:
alert("I'm auto logging in.");
If that runs, it means you logged in once and it remembered it.
Thanks for your reply. But i tested it. Yes in the page first loading, checkPreAuth() function is fired.
But handleLogin () is not fired.
? 've changed the code and test with Firefox, Chrome before build for Phone but alert is not shown :( :
function handleLogin() {
alert("Tested HANDLE Login");
var form = $("#loginForm");
//disable the button so we can't resubmit while we wait
$("#submitButton",form).attr("disabled","disabled");
var u = $("#username", form).val();
You tested with Firefox and Chrome? You do know that that desktop browsers cannot make AJAX requests to other domains, right? Did you check your console for error messages? You would have seen one.
Hi again. I made a mistake while importing js files.
Now it works fine :) Good job Raymond. Also which modification can we do to see Loading animation while waiting json response ?
Assume we have a new div, called status.
Before the post, do
$("#status").html("Stand back, doing stuff...");
In the post result handler, clear it:
$("#status").html("");
Obviously you can change the message to your liking.
thanks Raymond,
also some friends have asked your service file.
Here is my .PHP service file that turns boolean value with JSON header
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
$u = strip_tags($_POST['username']);
$p = strip_tags($_POST['password']);
$con = mysql_connect("localhost","db_user","db_pass");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db ("your_database_name");
$sorgu="SELECT * from db_users WHERE username ='$u' AND password ='$p' ";
$ssql_select = mysql_query($sorgu)or die(mysql_error());
if(mysql_num_rows($ssql_select)>0)
{
echo 'true';
}else{
echo 'false';
}
mysql_close($con);
Hi Raymond again,
Now i have another question. We are making a post with the code and check the response data.
if(res == true) {
//store
window.localStorage["username"] = u;
window.localStorage["password"] = p;
Also i want to store USER_ID value from the users table. But how can we read it from JSON. Our response code is just true or false. Can we change it like true:12311?
12311 is USERID return value from service
Eric - JSON can be used to represent many forms of data. In my case, I returned just a boolean value. You could also JSON encode a structure as well. So you could have a structure that looks like this:
(Note - the code below isn't exactly real JSON, it's just a representation. You would be responsible to encode it in PHP.)
On failure:
{ result="false" }
On success:
{ result="true", userid=4} (4 being the userid and dynamic)
Hi Raymond Thanks for your reply now i change my service file now the json response is like that
{"result":"true","memberId":null}
How should i change this part of code:
$.post("http://adasdas.com/loginser...", {username:u,password:p}, function(res) {
if(res == true) {
//store
window.localStorage["username"] = u;
window.localStorage["password"] = p;
Thanks
Hi again. I've made this
if(res.result == 'true') {
//store
window.localStorage["username"] = u;
window.localStorage["password"] = p;
;)
Cool, glad you got it.
Hi Raymond,
I like your blog ! Just found it when I was searching for a server side based android login (and wauw this was acactly what I was searching for!) in a few minutes, with some tweaks I got it working on my android device. The part I changed was the local storage:
function checkPreAuth() {
var form = $("#loginForm");
if(typeof(window.localStorage) != 'undefined'){ //HERE IS THE CRASH!
if(window.localStorage["username"] != undefined && window.localStorage["password"] != undefined) {
$("#username", form).val(window.localStorage["username"]);
$("#password", form).val(window.localStorage["password"]);
handleLogin();
}
else{
//alert("ERROR!");
}
}
}
It checks if any then exites then it will create and and go to the handLogin, if succeded. els it trows an error (wich is commented out now)
So after this (GREAT!) script was working in android I tought lets " copy past " it to my IOS device (I'm developing it for the both of them)
But this isn't going for smooth.... it crashes on that part.... I changed it back what you had but this also didn't work. I can't seem to find the issue, meby you can? (its commented where it crashes, without an error....)
Hope you can help me and I'm looking forward to the other blog posts and your help!
I'm still learning the iOS side of PhoneGap myself, but XCode has a debug type view where you _should_ see an error message. Can you try looking there?
This is great info. Niels V please do report on what error you received if you were able to see the message in the debug type view!
Thanks
IT was quite simple. Just used the ios phonegap js file ! And this works great .
Ohhhh lord - I shoulda known that. Yeah, I believe the PG guys are working on having _one_ JS file for all.
Next time I blog on this and share the code, I'll remind folks to replace the phonegap.js file.
Yea that would be nice, also add that jquery 1.7.x is the minimum that you'll need to get this working, first I tried 1.6.4 (I just like that version, stable and clean) but post and other functions wheren't in that one, took me some time to figure that out lol
neither the less, great post and thanks for every thing!
post is _definitely_ in 1.6 - shoot, it's been around for a long time. I can say that jQuery Mobile doesn't support 1.7 now- they plan to in the future. You may want to watch out for that.
Are you sure? Couse after upgrading to 1.7.1 it worked for me?
Well anyhow, it's working like a charm now so, so far 1.7.x isn't giving me any problems ;)
I think it's more an issue of support. I'm thinking maybe they found a few edge cases where it didn't work right, so they just stuck with saying 1.6.4 was what they support.
Hello, great work-up here. Does anyone have a complete working sample with the .php db file? I've been trying to keep up with the comments here and thank everyone for the input as this is relatively new to me. Thanks Ray!
Well, to be clear, the front end stuff may be new to you, but the server side stuff should be simple, right? Or are you new to PHP too?
If anyone on this thread knows PHP, I'd gladly accept a comment pointing to a pastebin demo. I'll even edit the post to put a note at the end.
I noticed that you set a session on the server side of your script. Are you able to access those server side session variables from the app? if yes, How? Does working with server session with a phonegap app on a device act the same way as if you were on a regular website?
Technically the answer is no. You can't read server variables from your client side code. You can - of course - expose those values via services.
And yes - it works the same. So AJAX calls can pick up, and reuse cookies, so cookie-based sessions "just work".
Raymond,
Thanks for your reply. If I store values in local storage and close the app, will those local storage values go away? Or do I have to manually remove them? if so, how?
localStorage values stick. If you want to remove them, use the removeItem function:
localStorage.removeItem("somekey");
Thanks again Raymond,
In the last part of your article you mention about the security of local storage. Here is a link to clear it up.
http://stackoverflow.com/qu...
This would suggest putting the variables in local storage not a good idea if they are sensitive, like a password. This also assumes that the person has access to the computer. Now since this is meant to be on a device like a phone or tablet then this may not be a concern.
Yeah, I'd probably avoid passwords in localStorage, but on a mobile device I'd say it's more secure than a desktop.
Hi,
I can't make this work on iOs, despite the comment from Niels. Any idea ? What does he mean by "Just used the ios phonegap js file" ?
Thanks,
Quentin
Currently, the phonegap.js file is platform specific. So in iOS, you have to ensure you copy the iOS version of the phonegap.js file. Does that make sense now?
One of the things that PG team is working on is moving to ONE file for all the platforms (one JS file).
Hi,
Thanks for the swift answer! Well that's ok then, I have a phonegap-1.2.0.js file in my project, so that's not it.
I can't find what's going wrong, no errors when running it in the simulator but the button doesn't do anything.
Here's my code, if you -or someone- has some time to waste to quickly check on it : http://pastie.org/3735130
What I recommend is a butt load of console.log messages. So for example, add one in init. Add one in deviceRead(),add one in handleLogin. Etc. See where it is failing. Add one before $.post.
Hey,
Thanks for the advice. I had a whitelist rejection from the URL which I fixed by adding a * in the array, but now I have this :
2012-04-05 23:17:22.741 LCDemo[5819:13403] Device initialization: DeviceInfo = {"name":"iPhone Simulator","uuid":"8BA3CEC6-27B2-5573-8C42-7A2DB234EF32","platform":"iPhone Simulator","gap":"1.2.0","version":"5.0","connection":{"type":"wifi"}};
2012-04-05 23:17:22.759 LCDemo[5819:13403] *** WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: <NSRangeException> *** -[JKArray objectAtIndex:]: index (1) beyond bounds (1)
Any idea ?
Thanks,
Quentin
Does it throw that error anywhere in particular? Did you use the console messages like I suggested to see if it throws that in a certain place? Can you click the submit button?
Yes I did but no errors except that! I can click the submit button but nothing happens... I'll keep looking and i'll let you know, unless you have another idea of course :)
Is your event handler running? Like I said - using console.log can at least tell you "I got this far..." It's a cheap way to debug, but quick.
Thanks for this guide. Manage to set it up with my phonegap app. Now, thinking of security because local storage is in clear text. Maybe use SALT or instead of storing password just store a session code(with expiry) from the return value but not sure the direction yet.
You could skip storing the u/p completely if you want - or just store the username, just to make things a bit quicker. If I get access to your phone though this would be the least of my worries though.
Hey I was wondering if you could post your server file? Im trying to learn how to do this and having quite some trouble with it, I believe that would really help. Thanks.
The server logic was incredibly trivial though. The CFC had a method, login, that took two arguments, username and password, and just did a hard coded check. It didn't hit a database or anything. Are you asking because you are a CF developer and don't know how to build CFCs? Or another reason? I'm not opposed to sharing the code, it's just that it is so simple I'm not sure how it would help you.
I apologize, im a student attempting to create an app for a project, I know nothing about coldfusion and Im attempting to do this with php. I just thought maybe a look at the code could help me figure out a php solution.
It probably won't help as it's different. Actually, I posted it already in a comment above:
http://www.raymondcamden.co...
Is is possible to locally store username and password in android mobile using phonegap
PhoneGap apps have multiple ways to store data:
LocalStorage
WebSQL (Database)
Files
So yes.
great guide. thanks. one question: i got it work in the android phone. but it doesn't work in chrome on the computer. do you know the reason?
The deviceready event won't fire. That only works on a real device. When I test PG stuff in the browser, I fake it. Ie I call it in my code.
Note though that CHrome cannot make remote Ajax calls by default. You can either make use of CORS, or the command line arg that lets you do it. (I can't remember it offhand.)
so the web version will be so different from the phone version then. i thought they can share the same code, just different cordova.js
Err, well, I mean it depends. Why build a native app if you aren't going to make use of native capabilities? If you aren't - then I'd just build a mobile friendly site. If you want an app and don't want to do native stuff, you can still make a PG app out of it, but you aren't gaining much.
And it's not like they can't share any code at all of course. If your desktop web site is using an MVC architecture, then your mobile app can make use of the same model.
Hi there!
I tried to modify this a bit in order to retrieve some informations from a database during the login. The web service is built in PHP and is returning an array in JSON but the login is not working anymore. Would you -or anyone- have an idea why ?
$.post("http://app.we3r.net/login2.php", {username:u,password:p}, function(data) {
if(data.success == true)
{
window.localStorage["username"] = usernameToSave;
window.localStorage["userId"] = useridToSave;
$.mobile.hidePageLoadingMsg();
$.mobile.changePage("dashboard.html");
}
else
{
$.mobile.hidePageLoadingMsg();
navigator.notification.alert("Your login failed", function() {});
}
}, "json");
When you test outside of phonegap, what do you see? Simply hit your web service in the browser, pass in the values for username and password, and see what comes out.
Hello Raymond,
one question: why do you use deviceready?
May I do something like:
$(document).on('pageinit', '#loginPage', function(event) {
handleLogin();
});
will they be the same?
thanks
The deviceready event is fired when you are allowed to do device-specific things in your code. Things like use the camera for example. My app isn't doing anything like that, but a "real" app would. Listening for that event is considered the normal best practice.
Now - as for pageinit - that's another matter. That's jQuery Mobile specific.
For server-side PHP an database support, check out this article:
http://samcroft.co.uk/2011/...
hi raymond,
i am new to phonegap.
is your tutorial applicable for blackberry OS 5.0 and higher? where can i find "phonegap-1.2.0.js" for blackberry ?
thanks
I'm not sure what PG 1.2 supported since that was a while ago, but PG 1.8, the current release, definitely supports Blackberry OS5+. I'd just download the bits from there. My code should work fine with it. Although my code loads a specific version of phonegap's JS file. You would change it the latest cordova.js file. My code also uses an older version of jQuery Mobile. You should use the latest.
Hi Raymond,
Thank you for your help. So, i just go with
o> jquery.mobile-1.1.0.js
o> cordova.js
o> jquery-1.7.2.min.js
i load it to blackberry simulator 9930. When i open the application, it went loading and then crash. It happened whenever i load the "jquery-1.7.min.js". Do you have any idea regarding to this ? and where can i get the error message for debugging ?
Sorry for bothering you. I really appreciate your help. thanks
Hmm. I'd say start from scratch. Ensure a html page with just <h1>Hello World</h1> can load.
Hi Raymond,
I found something in web that if Phonegap want to communicate with external data, we have to use ajax to connect to server for cross domain.
But I read here that you don't need to handle it.
Is it true??
You need to set the whitelist property in XCode. In Android I never needed to. Since that is OS specific and not in the code per se, and since I was primarily only using Android, it's not something I covered in my blog entries very often. But if you go to the PhoneGap docs, it _is_ covered with examples.
hy raymond, i read every comment in this post, and i learned so much! so thank you! and everybody that helps with their comments, but i need help with the .php server part, i could make it work with the bolean result, but when i have to make it with json arrays i didn't work, so i anyone can help me plase
After validating the username and password, is it possible to redirect to a real website address?
For instance http://www.google.com
You could load a new URL into the main view. Haven't tried that myself, but it should be possible.
I was able to get the external URL to load using the code below and I wanted to share.
window.location.href="http://website.com?username="+u+"&password="+p;
I have another question. In your example your program saves the username and password to the local storage. What if someone changes their password on the server side? I have tried an example and it just sits at the login form. When I push the button to login, I don't get a message saying login failed. If I go ahead and type in the new password, it will redirect correctly. Is there anyway to pop up an alert saying that login failed or check password? Thank you!
Odd - if you look at handleLogin, you clearly see it has a handler for the auth failing. You don't see "Your login failed" running? Remember that is using the PhoneGap API so if you test on your desktop you won't see it.
If it is the first time running the program without saved info on the phone, I can get the alert "your login failed" if I type in the wrong info. If I save correct info and validate it will then redirect me. Now if I change the password on the server side and go back to the phone that is where I have the problem. I don't receive a "your login failed" message when clicking on the Login button.
Ok, so I recommend adding some logging. See if checkPreAuth is running and see if handleLogin runs. Log the response. Etc.
I have added logging (console.log("message")) to each one, checkPreAuth, init, and handleLogin. Each one says it fires.
My error is this:
Uncaught TypeError: Cannot call method 'alert' of undefined at file://android_asset/www/index.html
That is the line of code that should pop up the notification alert that shows "Your login has failed".
You are running this as a PhoneGap app, on a device, or a simulator, right? Cuz that's using the device API to do a device specific notification. If you are testing on your desktop, you want to use a 'normal' alert.
Testing on a Motorola Razor, android 2.3.6 I believe. The notification will work fine on the device on the first run, but I'm only having this problem once I have changed the password on the server and try to run the app again.
Wait a tic - are you changing the password on the device, ie, after the window.location.href?
No, I haven't changed the password on the device yet at this point.
The idea is that someone might change their password on the server but forget to change on the device. They will be stuck at the form that won't go anywhere and not have any indicator saying hey your login failed. I'm trying to make it user friendly :).
BTW thank you for your assistance.
Omg- so stupid. So - the API I used, navigator.notification.alert, requires you to load the PhoneGap JS file. I never loaded it in my demo. I'm so, so, sorry. Simply load that file (which is now cordova.js) in your HEAD block and you should be good to go. I'll edit the code sample to include it.
Oh crap - I read too quick. It IS being included. Um....
I think I know what may be going on now. I've got loginpage.live("pageinit") running checkPreAuth, which is a jQuery Mobile event. But my use of navigator.notification.alert will only run AFTER deviceReady has fired.
It is possible that we have a case here where checkPreAuth fires BEFORE deviceReady does which means... bad news.
If you want a quick fix, change it to just an alert(). Will be a bit ugly, but will work.
The longer fix is me doing an update to the entry that handles the 2 events correctly so one doesn't fire before the other. (Err, well, that one fires whenever but it correctly waits.)
I'm totally sure that your code is not at fault. I wouldn't have gotten this far without your help. I'm just missing something. Can you try changing the password in your service.cfc to mimic what I'm doing?
The alert() fix works great!! I really do appreciate your work. Thank you again.
For folks curious about how I fixed it, see the update here:
http://www.raymondcamden.co...
Hi Raymond,
I tried the example which you have posted, but I am facing a problem. The control is not going into the " $.post("http://www.coldfusionjedi.c...", {username:u,password:p}, function(res) { .... } " function.
What can be the problem?
I'd ensure this line is running:
$("#loginForm").on("submit",handleLogin);
You can add a console.log before it. You can add a console.log as the first line in handleLogin as well.
Hi there,Fanstastic Post.Just a question how can i do a log off account? because the username passsword combination is stuck and its driving me crazy.
Thanks
hii
thats great work
can u mail complete source code to my mail pls
@Miguel: Logoff would need to:
a) Remove the values from localStorage (easy enough)
b) Call the remote CFC to clear the session on the server side (again, easy enough in ColdFusion, should be easy in any language).
@Ashok: What complete source do you want? It is all there except the login routine on the server which really wasn't critical to the blog post.
Hi, just wondering, the data submitted from this forms to the server, are they encrypted? if not, then it will be sending "naked" passwords to the server through the net?
Sorry about my previous comment. After further looking into your code. i found that you did not send password over the internet, instead you pull password from server and check against the form value. However, the password pulled from the server is in MD5 form. how to check it against the form values?
$.post("http://www.coldfusionjedi.c...", {username:u,password:p}, function(res) {
Actually, we do send the password, otherwise, how would the server have anything to compare too? You should use https for the call, not http as I did for my simple example. THat will make it marginally safer. You could also do a hash client side before sending it, or look for a JS encryption routine.
Hello Ray , I also followined a style like yours for posting values to server using $.post but my app doesn't send any data to server ,when run in Blackberry Emulator and Device .
I build the code using Phonegap BUILD and used a valid Signing key also. But the post doesn't get executed , my code can be seen at http://stackoverflow.com/qu...
What is the URL you are trying to hit? On Android if you hit localhost, it means the _device_ localhost, not the machine you are on.
Hi Raymond,
I tried the example which you have posted, can you give me cfc code ? thnxx before..
You can find it in this comment:
http://www.raymondcamden.co...
Hi MR.Raymond.
I'm behzad from Iran.
your site really great.
how can i replace PHP instead service.cfc?
(i don't know what is the --> .cfc file !)
i want to get stuff from MYSQL Database by PHP
and past it to the phone.
thank you sir.
All the ColdFusion code is doing is:
Running a query.
Turning the result into an array.
Converting the array into JSON.
That should be very possibly in PHP. I don't know PHP though so I can't help you with that.
Hey Raymond, can this code work on a website like this?
https://sso.sp.edu.sg/login...
I won't be able to edit and they did not do anything on the code related to JSON. Although i tried to login but i failed instead probably because it needed json.
Please help! thanks
I have no idea what that site is and what it does - so I don't think I can properly respond.
Thanks for the demo! but where do I store the below code..i have been trying this but getting errors. so could please help me with this..
function init() {
document.addEventListener("deviceready", deviceReady, true);
delete init;
}
function deviceReady() {
$("#loginForm").on("submit",function(e) {
//disable the button so we can't resubmit while we wait
$("#submitButton",this).attr("disabled","disabled");
var u = $("#username", this).val();
var p = $("#password", this).val();
if(u != '' && p!= '') {
$.post("http://www.coldfusionjedi.c...", {username:u,password:p}, function(res) {
if(res == true) {
$.mobile.changePage("some.html");
} else {
navigator.notification.alert("Your login failed", function() {});
}
$("#submitButton").removeAttr("disabled");
},"json");
}
return false;
});
}
Where do you "store" the code? I don't think I understand your question. Are you asking how to use JavaScript?
Hey Ray! Awesome write-up. I'm wondering, though, what would be the best method to keep the user from coming back to this page when "some.html" is loaded. I'm noticing that when I deploy this to my Android phone and hit the hardware back button, it goes back to the login page. That doesn't seem like the behavior a user would expect!
Few ways:
1) Listen for the back button. Example from docs: http://docs.phonegap.com/en...
2) Depending on your UI framework, you can listen for a pageshow type event (that's jQuery Mobile specific) and say (in pseudo-code), "If I'm loading the login page and the dude is logged in, push them to the home page."
Ok, thanks. I was looking into the back button event listener already but wasn't sure if that was the best mehtod or not. I've literally copied/pasted your code to test so I'm using jQuery Mobile as well (although, I can't tell why jQuery Mobile is necessary in this example).
One thing I've had a continual issue with is page transitioning in jQuery Mobile. It's so confusing and I can't quite wrap my mind around the concept. Does it actually visit the new page? Do you need all of the script and css inclusions on each page? Do you just use multiple divs in ONE page rather than loading a whole new page? It's just very confusing!
"I've literally copied/pasted your code to test so I'm using jQuery Mobile as well (although, I can't tell why jQuery Mobile is necessary in this example)."
It is absolutely NOT required. In general, I try to make my examples as simple as possible and not mix stuff in. In this case, JQM just made some things easier. As a tech blogger, it is a hard balance. :)
"Does it actually visit the new page?" Define visit. JQM loads in pages via Ajax and puts them in the DOM. Is that a visit? Probably not.
"Do you need all of the script and css inclusions on each page?" See the above. You can get away with doing it just once as the other pages are loaded in via Ajax and only the 'page' content is displayed.
" Do you just use multiple divs in ONE page rather than loading a whole new page?" Normally you have one div per HTML file just to make things simpler.
" It's just very confusing!" I apologize. I'd suggest the jQuery Mobile web site for more info, or, just think of the basic concepts of this article at a higher level. Don't get hung up on the UI aspects of it.
Hi, I am following your code on phonegap app using Window phone emulater and Visual Studio 2010.
Issue is, I am not able to call $.post call to http://localhost:55209/Account/Login which is dev server.
Is it due to cross domain issue?
I was thing about whitelist but according to phoneGap APi "Domain whitelisting is unsupported on Windows Phone. By default, all domains are accessible."
What could be the issue? Please help!
On the phone emulator, if you open IE and enter that URL, does it work?
Thanks Raymond,
I was able to fix the issue. I just added $.support.cors = true; in my .js file and after that code works like a charm on the phone emulator.
Thanks for helping me by this post. :)
Nice. I'm getting a Windows phone pretty soon actually.
Hi, I liked the example of the login and I want to ask if you can give me some advice on how to get some data for this user from my server. I have a website and I want a mobile app. I am using ASP.NET MVC 4. I had the idea of just creating new api that can give me user specific data without authentication but that will mean open door for anyone to all the data. Or can I somehow when I login do it like I am logging in from the browser so I can check from the server if I the user is logged or not.
I do not know Asp.Net so I can't really comment. In ColdFusion, you can use Sessions to mark a user as authenticated. This works fine with XHR (Ajax) calls so you could use this to secure your calls for data.
Hi Ray,
Am I reading the above comments correctly in that to deploy this to an iOS device all you would need to do would be change the js file included? The PhoneGap docs imply you need to develop on a Mac, but I'm assuming that's for native development rather than using JQMobile and PhoneGap?
Thanks in advance.
"Am I reading the above comments correctly in that to deploy this to an iOS device all you would need to do would be change the js file included?" Each platform has a unique JS file. When you use the command line to create your projects, this is handled for you. When you use PG Build, ditto.
"The PhoneGap docs imply you need to develop on a Mac, but I'm assuming that's for native development rather than using JQMobile and PhoneGap?"
It depends. You can use PG Build to generate iOS apps based on HTML you write on a PC. If you don't want to use PG Build, you have to use a Mac.
Thanks Ray. At the moment I'm using Eclipse to do my dev, but will defo look at PG Build, which seems to be the way to go for cross platform apps.
Actually a safer aproach would be not to store the password and username, but instead store the url-location and IP from wich the url-location was called (i.e Your mobile phone).. And just check this against a php-script.
"php-script" - or any other language. :)
hello .. i want to create an App Android using phoneGap.. the user musst login befor using the App.. the question is how can i add the HttpRequest Plugin phoneGap/cordova to my project to communicate with the server.
You don't need a HttpRequest plugin. Just use AJAX.
Thanks Raymond..
so like this !!
$.ajax({
2 url: 'http://yourdomain.com/your-...,
3 dataType: 'jsonp',
4 jsonp: 'jsoncallback',
5 timeout: 5000,
6 success: function(data, status){
7 //data loaded
8 },
9 error: function(){
10 //error loading data
11 }
12 });
Sure, but keep in mind that folks use JSONP because browsers are restricted from making an XHR to another domain. PhoneGap removes that limitation.
hi Raymond
I dont understand this line..
$.post("http://www.coldfusionjedi.c...", {username:u,password:p}, function(res)
so method = login, login is a method or a variable?
if it is a method where it is defined?
thanks in advance..
The URL you see there is specific for ColdFusion servers. If you aren't a ColdFusion dev, then it doesn't matter. It basically says to run a particular method in a particular CFC (think class).
ok ..
can I use a php file instead of cfc ??
like this : $.post("http://www.earthfaves.bis/dev/ajax/ phonegap/ login.php?
method = login&returnformat=json", {username:u,password:p}, function(res) {
if(res == true) {
do something
Absolutely. PhoneGap, hell, even JS code, doesn't really care what your back end is written in. It cares about the response.
Firstly, i must thank you for that awesome efforts you made on that script.
i have a learning problem with JSONP and up till now i'd spent about a month and a half trying to get this done
and the last try i made is i packed up your script here as an APK and sent it to my android but the result is one white blank screen with no data in it.
i don't know where the problem is !! i'm so desperate.
thanks in advance
You should consider using the Android tools/monitor script to see if you can see the error. It gives you a view of your device and the running applications.
is it to much for me to ask you for the server side code in PHP or what ever ??
i realy had had so much hard time finding it and making it to work and nothing is workin with me.
Thanks in advance
Unfortunately it is for many reasons.
A) I don't know PHP
b) If you are working on a server-side project and don't know how to do authentication, then you shouldn't be just copying someone else's code. This is really basic level stuff for a language. You take in two inputs (username and password) and compare them to a database.
can someone test the program in the emulator (Android Galaxy)?
I try to test, but that does not work
someone has an idea
"does not work" isn't enough. You need to provide more detail.
Firsty I try to communicate with the server
the code looks like this
login.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auth Demo</title>
<script type="text/javascript" charset="utf-8" src="js/cordova.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.mobile.js"></script>
<script type="text/javascript" charset="utf-8" src="js/functions.js"></script>
</head>
<body onload="init()">
<div id="loginPage" data-role="page">
<div data-role="header">
</div>
<div data-role="content">
<form id="loginForm">
<div data-role="fieldcontain" class="ui-hide-label">
<label for="username">Username:</label>
<input type="text" name="username" id="username" value="" placeholder="Username" />
</div>
<div data-role="fieldcontain" class="ui-hide-label">
<label for="password">Password:</label>
<input type="password" name="password" id="password" value="" placeholder="Password" />
</div>
<input type="submit" value="Login" id="submitButton">
</form>
</div>
<div data-role="footer">
</div>
</div>
</body>
</html>
and the file functions.js looks like this
function init() {
document.addEventListener("deviceready", deviceReady, true);
delete init;
}
function deviceReady() {
$("#loginForm").on("submit",function(e) {
//disable the button so we can't resubmit while we wait
$("#submitButton",this).attr("disabled","disabled");
var u = $("#username", this).val();
var p = $("#password", this).val();
if(u != '' && p!= '') {
$.post("http://www.kdgkasdg.com/dev...", {username:u,password:p}, function(data) {
if(res == true) {
alert(res);
} else {
nalert("Your login failed", function() {});
}
$("#submitButton").removeAttr("disabled");
},"json");
}
return false;
});
}
and the file login.php is like this
<?php
header('Content-type: application/json');
echo 'hello from server';
?>
but i dont now if it is possible to test that in Emulator android or Chrom
thanks for your help ..
Of course you can test PhoneGap apps in the emulator. But that's not really relevant to this blog post. Have you read the core PG docs to know how to run the emulator? If not - please do so.
ok ..
thank you for the answer
Hi
hi
I am using Phonegap to develop a app (login) and I get a 404 error about cordova_plugin.json when I test/view the app I am developing in chrome(ripple).
Could someone please let me know what this is and how I can fix this error.
Thanks very much
mouradovitch
That error is ignorable w/ Ripple, but I should point out that Ripple and PhoneGap 3 is currently incompatible.
i use cordova 2.9.0.
but how can I ignore that ?
The 404 error can be ignored is what I meant. I don't believe it matters. As it stands - Ripple has been broken for me since PG 2.6.
What Emulator would you recommend?
I now mostly use the 'real' emulators, ie the one you get with Android or iOS.
the people who use PHP, can someone send me the code for Ajax or write here. I have tried for two weeks to write the correct code but without result.
this is my email: mouradovitch@live.de
Thanks very much
I don't use PHP, but honestly, this is taking form input, running a database query, and outputting true or false. Are you saying you can't do that in PHP? That's pretty basic stuff as far as I know.
Start simple.
Can you write PHP code that outputs the value of form fields?
now it works .. thank you Raymond for your help
the problem was missing cordova_plugins.json error
i just create an empty cordova-plugin.json file with just {} inside.
and this is my Test_code if someone needs it
login.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/...">
<html>
<head>
<title>First App</title>
<script src="cordova.js"></script>
<script src="jquery.mobile-1.3.1.js"></script>
<script src="jquery-2.0.0.min.js"></script>
<script>
function onLoad(){
document.addEventListener("deviceready",onDeviceReady, true);
}
function onDeviceReady(){
navigator.notification.alert(" PhoneGap is working!!");
}
function LoginTest(){
var myName = document.getElementById("name").value;
alert("Hello " + myName );
//connect to the server
$.ajax({
url: 'http://www.domain.com/ajax/...,
dataType: 'json',
// jsonp: 'jsoncallback',
timeout: 5000,
success: function(data, status){
//data loaded
alert(data);
},
error: function(){
//error loading data
alert('no data');
}
});
}
</script>
</head>
<body onload="onLoad();">
<h1>Welcome to PhoneGap</h1>
<form>
<p> login: <br/>
<input type="text" id="name" ></p>
<p> Password: <br/>
<input type="password" id="pw" ></p>
<input type="button" value="Login" onclick="LoginTest()" />
</form>
<div id=’result’></div>
</body>
</html>
and this is login.php file
<?
header('Content-type: application/json');
echo json_encode('hello from server ');
?>
Nobody gave a complete serverside code to test the above code using php.
Can somebody please provide the entire login working example with php ?
I would also like to have a nice zip file with all the working files as well if someone could be so kind to post it. I have been trying get a simple phonegap server based log-in to work for several days, and I can get it to work in Android 2.3 but anything in Android 4.x doesn't work.
hi saurabh..
my serverside code login.php looks like this
<?
header('Content-type: application/json');
$email = strip_tags($_POST["username"]);
$p = strip_tags($_POST["password"]);
define ("USER", "database_username");
define ("PWD", "database_password");
define ("DBNAME", "databasename");
// connect to the server
function connect_server(){
$_db_host = "localhost";
$_db_username = USER;
$_db_passwort = PWD;
// Serververbindung herstellen
$link = mysql_connect($_db_host, $_db_username, $_db_passwort) or die("Keine Serververbindung möglich: " . mysql_error());
return $link;
}
//connect to the Database
function connect_db($link){
$_db_name = DBNAME;
// Verbindung zur richtigen Datenbank herstellen
$datenbank = mysql_select_db($_db_name, $link) or die("Failed to connect to DB " . mysql_error());
if (!$datenbank){
mysql_close($link); # Datenbank schliessen
echo 'Failed to connect to DB <br/>';
exit; # Programm beenden !
}
return $datenbank;
}
$con = connect_server();
connect_db($con);
//Email and Pass testen
$result1=mysql_query("SELECT username, password FROM users
WHERE username = '$email'
AND password = '$p' ")or die(mysql_error());
if(mysql_num_rows($result1)>0)
{
//do something
}else{
// email or password is incorrect
}
mysql_close($con);
?>
Steve, if you can provide more details on how it fails in Android 4.X, I can try to help.
The problem was with my config.xml file... I had the
<access uri="http://mydomain.com"/> Tag (Blackberry), but I was missing <access origin="http://mydomain.com"/> (Android)
Ah cool - thanks for sharing the solution.
Hi
I tried creating the android app using phonegap with php-mysql. But encountered the issue. The app is not atall communicating with the php file.
What I did is:
Created a html file (jndex.html)
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=320; user-scalable=no" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Auth Demo</title>
<link rel="stylesheet" href="jquery.mobile/jquery.mobile..." type="text/css" charset="utf-8" />
<link href="jquery-mobile/jquery.mobile.theme-1.0.min.css" rel="stylesheet" type="text/css"/>
<link href="jquery-mobile/jquery.mobile.structure-1.0.min.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" charset="utf-8" src="js/cordova.js"></script>
<script src="jquery-mobile/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="jquery-mobile/jquery.mobile-1.0.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8" src="js/main.js"></script>
</head>
<body onload="onLoad();">
<div id="loginPage" data-role="page">
<div data-role="header">
<h1>Auth Demo</h1>
</div>
<div data-role="content">
<form>
<p> login: <br/>
<input type="text" id="name" ></p>
<p> Password: <br/>
<input type="password" id="pw" ></p>
<input type="button" value="Login" onclick="LoginTest()" />
</form>
<div id=’result’></div>
</div>
<div data-role="footer">
<h4>© Camden Enterprises</h4>
</div>
</div>
</body>
</html>
Otherthan this index.html file, I have the js directory that contains the js files.
one config.xml file -
<?xml version="1.0" encoding="UTF-8" ?>
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "com.gita.example"
version = "1.0.0">
<name>Gandhi Institute of Technological Advancement</name>
<description>
Gandhi Institute of Technological Advancement
</description>
<author href="https://themingpress.com" email="admin@themingpress.com">
Themingpress
</author>
<access origin="http://pixelmarketing.com" subdomains="true" />
<preference name="splash-screen-duration" value="5000" />
<gap:splash src="splash.png" />
</widget>
In the server side at my staging server, I have created a file login.php that includes:
<?php
header('Content-type: application/json');
$email = strip_tags($_POST["username"]);
$p = strip_tags($_POST["password"]);
define ("USER", "username");
define ("PWD", "password");
define ("DBNAME", "dbname");
// connect to the server
function connect_server(){
$_db_host = "localhost";
$_db_username = USER;
$_db_passwort = PWD;
// Serververbindung herstellen
$link = mysql_connect($_db_host, $_db_username, $_db_passwort) or die("Keine Serververbindung möglich: " . mysql_error());
return $link;
}
//connect to the Database
function connect_db($link){
$_db_name = DBNAME;
// Verbindung zur richtigen Datenbank herstellen
$datenbank = mysql_select_db($_db_name, $link) or die("Failed to connect to DB " . mysql_error());
if (!$datenbank){
mysql_close($link); # Datenbank schliessen
echo 'Failed to connect to DB <br/>';
exit; # Programm beenden !
}
return $datenbank;
}
$con = connect_server();
connect_db($con);
//Email and Pass testen
$result1=mysql_query("SELECT email, password FROM users WHERE email = '$email' AND password = '$p' ")or die(mysql_error());
if(mysql_num_rows($result1)>0)
{
return true;
}else{
echo "email or password is incorrect";
}
mysql_close($con);
?>
=======================
Using Postman restclient in google chrome i have checked that the php file returns the perfect result, but not the android app after developing and installing in on my android phone
Being a newbie, i am unable to understand the issue. Can you (Raymond) or anyone else here help me in getting what is the issue where i am lacking in.
Thanks
Tusar
Can you confirm the AJAX call is being made? Perhaps with a simple alert?
Also, in the future, please do not post blocks of code. Please use a Gist or Pastebin.
Hi Raymond,
is there any way to hide the login Screen when preAuth? When I start the app the Login Screens appears for about half a second and after successful login it redirects to my first page. I want to get rid of that half a second login screen.
Thank you in advance.
Btw: Great Blog, helped a lot in the past!
Oh yeah, you definitely could. I don't have the code for that, but I'd use some logic to simply load a different page if preAuth can be tried, and if not, load the normal login screen.
Hi Raymond,
I can't make the handleLogin() fired..
I've put an alert in it but it doesn't appear.
all my code is the same as the code above.
when I clicked the button Login, the alert won't come.
function handleLogin() {
var form = $("#loginForm");
alert("I'm submit");
//disable the button so we can't resubmit while we wait
$("#submitButton",form).attr("disabled","disabled");
..................................
..................................
thanks for your help, Regards.
Is deviceready firing?
I have used this login concept and works fine. Now I am trying to add an auto check which would run for every change of page, every button click by the user. In my app, the requirement is that once the user is logged in, the login is valid for only that day. So, after a successful login, the login date is stored in localStorage. The next day, the first action by the user should take him to the login screen. For this to happen, I need to keep checking if the login is current at every point.
Wondering if there is a clean way to do this, other than adding the check in every function and every page init code. Some event I can tap into using jQuery to do this and where to place that code.
Thanks in advance.
I can't think of any simple way to say, "before any action, run X", in vanilla JS. I'm sure Angular or Backbone has an easy way to do this but I assume you aren't using this or you would have mentioned it.
I dont understand. I need attached file :/
I've provided all the client side code and explained in multiple comments how the back end would work. If that isn't sufficient, then I'm not sure what else to give you.
Hi,
how would you organize the logout? through $pagechange?
martin
If we assume a logout button, like in the footer, then on click I'd call the server and run logout there and redirect the user to the home page on the PG app.
I'm curious about the security of the login form. It's posting over ajax (obviously because it's an app that communicates with the remote server) But couldn't that be sniffed and the u/p revealed? What other options do we have though??
You would - I assume - be hitting a https server for the login.
Hi i want to use a "window.location.href="some.html" instead of "$.mobile.changePage("some.html")" this but when i used this way its not redirect "some.html" page
If you do that then you will need to wait for the deviceready event to fire again before you can use anything from PhoneGap. Just FYI.
Hi i am having difficultly gettin this working with php. I know raymond is familiar with php but can someone else provide the php code that works with a mysql database
Um, Google "php database"? Isn't working with a database one of the core things PHP does?
Thanks ..
Its very helpful to me...
Hnin Yee Maung Maung
i'm trying to run this code in http://jsfiddle.net/ and i'm getting such kind of error {"error": "Please use POST request"}
So where is the jSFiddle link so I can run it?
that is the link with the same code you implement http://jsfiddle.net/WLmaz/
Oh wait, you tried to run it at JSFiddle? You can't do cross domain XHR requests in a desktop browser unless you use CORS or JSON/P. You can also use the Ripple emulator.
Thx Ray, it's working very fine... I'm a new on this phonegap platform i'm building my software project in jsp and phonegap.... and i'm using my jsp in another computer when i'm connecting that project on the browser to this address "http://192.168.0.103:8080/Myproject/api/books " i can be in its apache server and see my json file but if i'm trying to that web server on my phonegap application i'm able to connected with that, i have tried with the android ip which is 10.0.2.1 or x.x.x.2 or .3... can u plz help me out
I'm not sure I understand your English. It sounds like you are saying that you are testing on a mobile device trying to hit your dev server. If the IP is not working, I'd recommend looking at the <access> config docs at PhoneGap's site to ensure your app has access to the remote site. Another test - open your web browser on the device and type in the address. Ensure that works as well.
when i'm using my web browser it works fine but when i'm testing on a mobile device or the emulator it's still loading and nothing is changed
So check the <access> docs: http://cordova.apache.org/d...
Ensure you've added it.
thanks so much, i have handled that problem
Hi,
I have tried to get this working with php connecting to a mysql database loads of times but still wont work. Could someone please upload an example to github using php and Raymonds code. Please
Hello!,
I am a student and trying to build my first html5 jquery mobile page. I am using dreamweaver. Can I get the files to the login page so that I can open it with chrome to view and dreamweaver cc to design?
All the files are available in the blog post. The server side code is in one of the comments above.
I need to access the mssql database even when I am offline. Is it somehow possible to create a database in html5 local storage and periodically update it when net is available? Or is there some other way? Please guide.
Well, technically yes, it isn't really related to login though, but yes. You can use localStorage or Web SQL.
i tried this example with my webservice.. which checks with thedatabase and returens true when sucess login.. but nothing works..
please help me out
<!DOCTYPE HTML>
<html>
<head>
<title>PhoneGap Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="errorfile.css"/>
<link rel="stylesheet" type="text/css" href="jquery/css/jquery.mobile-1.4.0.min.css"/>
<script type="text/javascript" charset="utf-8" src="jquery/jquery-1.8.2.min.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery/jquery.mobile-1.4.0.min.js"></script>
<script type="text/javascript" charset="utf-8" src="jquery/jQuery.Validate.min.js"></script>
<script type="text/javascript" charset="utf-8" src="cordova-2.7.0.js"></script>
<script type='text/javascript'>
function init() {
document.addEventListener("deviceready", deviceReady, true);
delete init;
}
function deviceReady() {
navigator.notification.alert("login ");
$("#frmLogin").on("submit",function(e) {
//disable the button so we can't resubmit while we wait
$("#submit",this).attr("disabled","disabled");
var u = $("#username", this).val();
var p = $("#password", this).val();
if(u != '' && p!= '') {
$.post("http://10.0.11.103/amismobileapps/amismobileservices.asmx?", {UserName:u,pwd:p}, function(res) {
if(res == true) {
$.mobile.changePage("list.html");
} else {
navigator.notification.alert("Your login failed", function() {});
}
$("#submit").removeAttr("disabled");
},"json");
}
return false;
});
}
</script>
</head>
<body onload="init()">
<div data-role="page" data-theme="a" id="login" >
<div data-role="header" data-theme="b">
<h1>PhoneGap Demo</h1>
</div>
<div data-role="content">
<form id="frmLogin" data-ajax=false method="get" >
<div data-role="fieldcontain">
<label for="username">
<em>* </em> UserName: </label>
<input type="text" id="username"
name="username" class="required" />
</div>
<div data-role="fieldcontain">
<label for="password">
<em>* </em>Password: </label>
<input type="password" id="password"
name="password" class="required" />
</div>
<div class="ui-body ui-body-b">
<button class="button" type="submit" id="submit"
data-theme="a" minlength="5">Login</button>
</div>
</form>
</div>
</div>
</body>
</html>
nothing happens when i click on login button.. no errors too..
have written the webservice to access the database of our service and returns boolean value on login..
First, please do not post large code blocks in comments. Please use a Pastebin or Gist instead.
I'd start by seeing if the submit handler is working. Add an alert inside there and see if it fires.
<script type='text/javascript' >
$(document).ready(function()
{
$("#submit").click(function (e) {
e.preventDefault();
var u = $("#username").val();
var p = $("#password").val();
authenticate(u, p);
});
});
// data: {UserName: userName, pwd: password},
function authenticate(u, p) {
var serviceurl= "http://www.raymondcamden.co...";
$.ajax({
url:serviceurl,
type: 'GET',
contentType: "application/javascript",
data: {username:u,password:p },
dataType: 'JSONP',
async : true,
crossDomain: true,
jsonp: 'callback',
jsonpCallback: 'jsonpCallback',
success: function(res)
{
alert("Web service call succeeded." );
},
error: function (error)
{
alert('ERROR has occurred!');
alert(JSON.stringify(error))
}
})
}
</script>
this is my script.. even though tour webservice is returning true or false why is it not going to sucess function it is going to error function.. this is the warning which i see in chrome
Resource interpreted as Script but transferred with MIME type text/html: "http://www.raymondcamden.co...". jquery-1.8.2.min.js:2
*Please* do not post large blocks of code!
Tell me the URL of your instance of this and I'll give it a run to see.
am using your webservice in my script code... just to check whether its working for me or not.. guess its because your webservice just returns true or false not in exact json format..
Um, is that a question, a comment?
thank you so much for this app. i want to pass the session storage to a page eg. (welcome .html). so that when the user login, she will see something like "welcome mutago" where mutago is the name from session or localstorage.
thanks
Not quite sure I get your question here. Once a session is defined on the server, further AJAX calls will pass along the cookies required to associate the connection with the session. So if you hit a service on your server that returns the username, then it will work. That's how ColdFusion works w/ sessions and I'm sure other app servers are similar.
Hi Raymond Sir,
I am a new developer. I have designed a login page which has to fetch data from remote server but its not working. Can u please suggest me
You need to figure out *how* it isn't working. Just saying "its not working" is not nearly helpful enough. Look into remote debugging (see my About Me page for links to articles I've done on this) and dig deeper.
I am using jsop for the interaction with server and using post method but somehow post is converted into get.what to do to correct this.
You can't post with JSON/P, you can only get. Why use JSON/P? Cordova apps can make XHR requests to other domains w/o using JSON/P.
yeah I have to authenticate the user.....Earlier I had used json but it was not working
It should work. Check to ensure your access value in config.xml is set to * or to the host you are trying to hit.
Hey Raymond,
First of, thanks for the great writeup. I see that in the above tutorial, we are trying to log the user in everytime the application is launched, does that mean the user is automatically logged-out when the application is closed ? Is there a way to keep the user logged-in (like sessions) as I require to send some push notifications to the device ?
Hmm, well, technically I'd have to guess no. The ajax calls from your application to the server pass on cookies that the server gave it originally. So if you close the app and restart it, the cookies should (afaik!) still exist and if you are within the session "window" of your remote server, it may not be required.
So you could write code to do a ping to the box to return a boolean for the current login status.
Hi Raymond,
thanks for your code, when I press login the application stuck and I from my logcat I get only this text "Ignore this event" of tag SoftKeyboard Detect, do you know why?
I'd recommend using Chrome Remote Debugging instead. It should provide more detail.
Hello. I tried the following code but whenever i click the login button the app is stuck. wht should i do next?
hello..Its mentioning an error " has no method "live" ". how should i sort it out?
HI..I have an error while i run this code.. it shows "changePage of undefined" and its not able to load the some.html file. any help would be appreciated. thanks
@raunak: You may be using a version of jQuery that no longer supports live, and requires on instead. You would need to update the core, or use the version of jQuery I did for the demo.
@thomas: If changePage is undefined, it sounds like the JS file didn't load right. Check your dev tools and see.
what if I want to create a login system which username and passwords are base on the active directory user lists? Any suggestion?
Thanks before :)
That would depend on your server. If you use PHP, then I'd Google for active directory and PHP.
okay thanks sir :)
Hi,
i used the code it shows up but does not 'pushes' tothe other page. I added main.js and main page with loggin in, how to go to the next page after clicking 'submit' button?
Can you confirm that changePage is being run after login? Simply add a console message before and after. Also check your console in general for any errors.
Hi,
I am new to build phonegap apllication.
can anyone help me out to do it in a best way
@shabber: Your question is so overly broad I cannot really help you. I recommend you start with the documentation.
Why storing the password into localStorage? that's very insecure in my opinion. From then on it's accessible also from other parts of the mobile phone, that's dangerous.
Why not doing that with a session having an ID that could be created on the server-side, saved to database and the sessionID is saved to authenticate again, later. Or something like that.
However, there are much better solutions!
Fair point. If I did this now I'd only store the username.
Hello sir,
I am new to learn the Phonegap.Basically am a .NET developer .But now i need to convert my php coding to phonegap sir.Please explain me from the top to bottom of this converting concept sir.
I believe I may have mentioned this before, but I do not know PHP.
I want to store following json file on server .
var employees = [
{
"firstName":"John",
"lastName":"Doe"
},
{
"firstName":"Anna",
"lastName":"Smith"
},
{
"firstName":"Peter",
"lastName":"Jones"
},
];
when we store data on server side any code require on server side??
Not quite sure I get you. If you want to store something on the server, then yes, you need a server.
Ray, this is great info! I have a question, do you think it is a good idea to store the user & password values and use them on every call that you do to the server, to extract or post info into the database? I mean, like an alternative to create cookies... Thanks in advance!
I'd use session cookies instead - most app servers should support this and your Ajax requests will use them automatically.
Thanks Ray! Keep up this good work! :)
HI Raymond. Thanks for this article. Forgive me if this sound stupid. But sending the username and password in the url, will it not expose to security threat.
I'd use a https url to help prevent it from being sniffed, and it isn't in the URL, but the form data.
Hi Richard,
First of all thanks for your source code, I'm new to phonegap and I tried the code above as follows but i used cordova.js instead of phonegap.js and i'm trying to check the login in mozilla browser i can't see any response in the mozilla console and when i ran the php api url with parameters, the api ulr is showing the values it is working fine.
I'm trying to alert the res value , but it is not alerting and in Android virtual device when i click the login button nothing happens
$.post("http://localhost/android_api/api.php?method=login&returnformat=json", {username:u,password:p}, function(res) {
please help me to solve this problem.
localhost means your phone, not your local machine. You need to use the IP address of your computer.
Thanks for your reply Raymond, I will check and get you back..
Hi Raymond. I tried with the IP address but it is not working, please check the attached screen shot once. Please help me to solve this issue ASAP.
mapp.post("http://192.168.0.102/android_api/api.php?method=login&returnformat=json", {username:u,password:p}, function(res) {
Oh you are testing in the browser? You said this, "i'm trying to check the login in mozilla browser", but I missed it. You need to enable CORS in your PHP code. It should be simple, but as I don't do PHP, I can't tell you how to do it.
Hi Raymond,
Thanks for your response and tried with that and it is working fine.
Hi Raymond,
Thanks in advance, I want to logout from the app, can you please help me how can i logout from the app and redirect to home page. I tried with different things on click on logout button with jquery like
window.location="index.html";
navigator.app.loadUrl('index.html');
window.history.go(-(history.length - 1));
but these are not working, and i'm checking in browser , once the user clicks the logout button it has to redirect the home page but it is staying on the same page and the logout jQuery code is as follows
$( "#logoutButton" ).click(function() {
window.localStorage.removeItem("username");
window.localStorage.clear();
//window.location="index.html";
//navigator.app.loadUrl('index.html');
window.history.go(-(history.length - 1));
//alert('cleaned');
});
Please help me to solve this issue ASAP.
Well, first off, jQuery Mobile provides an API to change views. See: http://api.jquerymobile.com...
Login System using PHP & MySQL http://bit.ly/1GN5aEt
Build using @Ionicframework @phonegap @apachecordova
Hey Ray, would this code also work for a login in a web environment for desktop?
Sure.
Hey saw you have a youtube channel do you have a video for this tutorial? Thanks though it looks great
Sorry, no.
Probably a stuipid question but I am new to javascript and for some reason this isn't loading my main.js when I click submit in the browser! is there anything I need to add?
You should use Chrome Remote Debug or Safari Remote Debug to see if you can find an error. See my "About Me" page where I link to articles I've written on the topic.
It's saying$
$("#loginPage").live("pageinit", function(e) {
checkPreAuth();
});
Reference can't be found
Looks like jQuery is not loading. Did you include it? Do you see, earlier in console, an error for it loading?
how does Facebook remember your password? through your browser ;)
if you wanted to assign an ID for everyone who joined so you could track the user submissions. For example if I built another page that could take photos and collect a parigraph of text and they submit it to the data base then on another page I call the data to see the image, text and there ID. How can this be done??
Well this demo has login, not registration, but that could be done. User registration would depend on your back end system, but there are many examples of that.
"Another issue - and one I do not have a good feel for - is how secure
the local storage data will be on the device. Use with caution!"
Don not use this code!!! This guy does not even understand the basic of security!!!
Also, since he has no clues, you will send the password in CLEAR TEXT!! LMAO, what a noob.
Hey Tom. thanks for the comments. Let me address them.
* send in clear text: My assumption was that no one would use this on a http server. My blog (at the time) was using http, but that was just for the demo. However, I should have made that clear. I'm going to add some text on that now.
* Since I wrote this six years ago, there is now a plugin to handle secure local storage. I'd recommend that as well. I'll add a note on that too. (I wrote a blog post much more recent that covers that.)
Again, thanks for the feedback!
hello sir, can i have a project, please!
All of the code is available in the blog post.
Are you passing the password to "Online" Web service without any encryption? if there was a way, may you give suggestions?
I want to pass login username and password from Phonegap to my web service in other server. If i pass it un-encrypted, i think it will be unsecured.
No - you should POST to a https URL only.
hi raymond, i tried your code, but the style cannot appear, it is just like basic form.
i use jquery.mobile-1.4.5 so I change several times your code but there is no change.
Here it is one of example change.
<link rel="stylesheet" href="jquery.mobile-1.4.5/jquery.mobile-1.4.5.css" type="text/css" charset="utf-8"/>
Best I can suggest is using remote debug to see if something failed to load.
Hi. I am new to the ajax request to the server. Can you explain this line.https://www.coldfusionjedi.com/demo..."
And lease provide the code specified in the service.cfc
service.cfc simply checked the values to see if they were valid for login - which in my demo was hard coded. As to your first request, it got garbled - can you ask again?
https://uploads.disquscdn.c...
Hi, I get this error. I dont know what it is and how to fix it.
I hope some one can help me with this.
You're trying to hit a file:// URL? That's not going to work - you need to hit a proper server using https. (http is allowed, but I'd avoid it.)
I'm trying to get this working on localhost. My connection with the DB is fine. But when I'm trying to register some one or something I get this error and nothing will write to the DB.
Well remember localhost on the phone is the phone, not your desktop.
I first wanna build it on desktop. With my localhost. When it works I wanna build it to mobile.
Or is it impossible to get this working on desktop with localhost?
You'll need to set up a proper application server to handle your login though, not something you'd hit via file://.
How can I do it the right way? Can u show me how? How to write/code it? U would help me allot!
I can't help you to write a back end service. If you have -no- experience with back end stuff I'd suggest picking up Node. Also, if you just want authentication in a simple way, see Auth0.com.
I can write thing to database and get data from database. Thanks for helping with that problem. Now I have a new problem.
When I try to login it gets stuck at Authenticatin.... and it will not redirect to the welcome.html page
Do you see any errors in the console?
No errors in the console
Sorry not sure what else to tell you. You would need to look at the code handling the result. See why it isn't doing the redirect. Add some simple logging if you have to.
Thanks tot the support. I just fixed it.
Thank you very much for your tutorial ! It helped me a lot to build my own first login app !