Titanium User Authentication: Part 1

Titanium User Authentication: Part 1

Tutorial Details
  • Technology: Appcelerator's Titanium Mobile
  • Difficulty: Intermediate
  • Completion Time: 45 - 60 Minutes
This entry is part 1 of 3 in the series Titanium User Authentication

Welcome to part 1 of 3 in my little series on authenticating users with Titanium. Titanium is an open source cross compiler that allows you to write iPhone and Android (soon to be blackberry too!) applications using Javascript. No Objective-C required! We will be using PHP as the server side language in this tutorial and my database will be MySQL.

Step 1: Create the Users Table and Insert a Row

Make a new database or use an existing one, then open it. To save time on this step, I’ve included the SQL code below to create the table for you. I’ve called it simply ‘users’. After the table is created, add a new row. I’ve chosen ‘rondog’ as my username, ’1234′ as my password, my real name and my email. DO NOT FORGET to run the MD5 function on the password field when inserting. If your MySQL GUI doesn’t offer the ability to run the MD5 function, use this md5 generator and copy/paste the 32 character string in the password field. Also no need to fill the ‘id’ field out as it is an auto-incrementing field.

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL,
  `password` varchar(32) NOT NULL,
  `name` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Note: This SQL statement was exported from phpMyAdmin. If you get errors when copying/pasting this SQL statement you need to manually create the table and fields using the settings above.

Step 2: Create a New Titanium Project

Open up titanium and create a new project. The name you choose does not matter for this tutorial. Once the project is created, browse to the Resources/app.js file. Their is a lot of stuff in it already that we do not need. Go ahead and remove everything except the background color line at the top.

Now we need to create 3 things:

  • a tab group
  • a tab
  • and a window

We will then add the window to the tab and the tab to the group and then open it.

// this sets the background color of the master UIView (when there are no windows/tab groups on it)
Titanium.UI.setBackgroundColor('#fff');
var tabGroup = Titanium.UI.createTabGroup();
var login = Titanium.UI.createWindow({
	title:'User Authentication Demo',
	tabBarHidden:true,
	url:'main_windows/login.js'
});
var loginTab = Titanium.UI.createTab({
	title:"Login",
	window:login
});
tabGroup.addTab(loginTab);
tabGroup.open();

Ok, so we’ve made our window, tab and tab group.

Note: Before you compile, notice the URL property on the window. In the Resources folder, make a new folder called ‘main_windows’ and a new JS file called login.js. The URL property tells the compiler to use login.js as our window. If you skip this part, Titanium will throw an ugly red error in the emulator.

Upon a successful compile, your screen should look like this:


Step 3: Creating the Login Interface

Open up login.js after you’ve created it. We will be adding 2 text fields and a button.

var win = Titanium.UI.currentWindow;
var username = Titanium.UI.createTextField({
	color:'#336699',
	top:10,
	left:10,
	width:300,
	height:40,
	hintText:'Username',
	keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
	returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
	borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(username);
var password = Titanium.UI.createTextField({
	color:'#336699',
	top:60,
	left:10,
	width:300,
	height:40,
	hintText:'Password',
	passwordMask:true,
	keyboardType:Titanium.UI.KEYBOARD_DEFAULT,
	returnKeyType:Titanium.UI.RETURNKEY_DEFAULT,
	borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(password);
var loginBtn = Titanium.UI.createButton({
	title:'Login',
	top:110,
	width:90,
	height:35,
	borderRadius:1,
	font:{fontFamily:'Arial',fontWeight:'bold',fontSize:14}
});
win.add(loginBtn);

Go ahead and compile and your interface should look like this. Their will be no functionality yet, but you will be able to type.


Step 4: Make the Login Button Do Something

We need to create a click event listener, but before we go and check if the user exists in the database, we want to do some error checking on the fields. We will also create an HTTP client via the createHTTPClient() function.

var loginReq = Titanium.Network.createHTTPClient();
loginBtn.addEventListener('click',function(e)
{
	if (username.value != '' && password.value != '')
	{
		loginReq.open("POST","http://localhost:8888/post_auth.php");
		var params = {
			username: username.value,
			password: Ti.Utils.md5HexDigest(password.value)
		};
		loginReq.send(params);
	}
	else
	{
		alert("Username/Password are required");
	}
});

To explain the above, we first check if any of the fields are empty. If they are, then we present an alert saying they are required. If they both have values, we want to open our PHP file (we will create this next) and send some values to it. Notice I am running MD5 encryption on the password value.


Step 5: Creating our Authentication PHP File

This file will be the PHP file our app talks to when hitting the login button. The name must reflect the name in our loginReq.open() method in the previous step. I’ve named mine post_auth.php. Replace my mysql_connect and mysql_select_db settings with your connection settings.

<?php
// Connect to the database(host, username, password)
$con = mysql_connect('localhost','root','root');
if (!$con)
{
	echo "Failed to make connection.";
	exit;
}
// Select the database. Enter the name of your database (not the same as the table name)
$db = mysql_select_db('dbName');
if (!$db)
{
	echo "Failed to select db.";
	exit;
}
// $_POST['username'] and $_POST['password'] are the param names we sent in our click event in login.js
$username = $_POST['username'];
$password = $_POST['password'];
// Select eveything from the users table where username field == the username we posted and password field == the password we posted
$sql = "SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . $password . "'";
$query = mysql_query($sql);
// If we find a match, create an array of data, json_encode it and echo it out
if (mysql_num_rows($query) > 0)
{
	$row = mysql_fetch_array($query);
	$response = array(
		'logged' => true,
		'name' => $row['name'],
		'email' => $row['email']
	);
	echo json_encode($response);
}
else
{
	// Else the username and/or password was invalid! Create an array, json_encode it and echo it out
	$response = array(
		'logged' => false,
		'message' => 'Invalid Username and/or Password'
	);
	echo json_encode($response);
}
?>

Step 6: Receiving Data in Login.js

Okay back to login.js. Let’s do some data handling for when our PHP returns something. Place this code under var loginReq and above our click event.

loginReq.onload = function()
{
	var json = this.responseText;
	var response = JSON.parse(json);
	if (response.logged == true)
	{
		alert("Welcome " + response.name + ". Your email is: " + response.email);
	}
	else
	{
		alert(response.message);
	}
};

JSON.parse() is part of the Titanium API. It parses the json_encode() string we created in our PHP file. Let’s launch it now. Enter your username or password. Depending if you enter it correctly or not, you will either see the welcome message or you will see the invalid username/password message. Try both!

If you’re getting an error in the Titanium console about being unable to parse the JSON string, that means you are failing to connect to the database or select the database. Try browsing directly to your post_auth.php file in your browser and see what the error is. I would browse to mine via this URL http://localhost:8888/post_auth.php

Conclusion

In part 1 of this series, we created the database and added a user. We then made our login interface by creating a tab group, a tab and a window. We then gave our login button some actions. Our PHP file queried our database and upon successful login it returned our name and email. If login failed, we returned a string simply stating invalid username and/or password. I hope you enjoyed this tutorial and that it wasn’t too hard to follow considering we used 3 different technologies: PHP, MySQL and Titanium (Javascript)! Stay tuned for part 2 of this series where we will make a new tab that allows your users to create an account.

Series NavigationTitanium User Authentication: Part 2»

Ronnie Swietek is rondog on Activeden
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.hipervinculo.net Raul Riera

    Please, more like this!

    • Rajaa Samaha

      hello it’s so beautiful but i’m runing this exemple i’m obtein “Network ERROR”.can help me plz??thx

  • Brunodev

    OMG! This is really the tutorial i was looking for! Really awesome job on this one, will begin building something based on this really soon.

    P.S Can’t wait for next part :D

    • Ronnie Swietek
      Author

      I’m glad this helped you, I like hearing that!

  • aaran

    Thank you. that just saved me alot of time trying to find out how to do that…

  • http://yourwebteam.ca Hasitha

    Rather than echoing and exiting for database related problems, isn’t it better to set the message in $response with ‘logged’ set to false and return it that way? That’ll eliminate the “Unable to parse JSON string” error messages.

    • Ronnie Swietek
      Author

      Yes, you are right that would have made more sense to do it that way.

  • http://www.jarnesjo.net Nicklas Jarnesjö

    Nice tutorial. I use some of the code but more one time registration form view.
    I found it a little bit odd why you don’t push for mysqli with prepared statements instead of old mysql?

    Keep up the good work!

    • Ronnie Swietek
      Author

      Thank you. I used mysql because that is what I am familiar with. This can be changes to mysqli easily I am sure.

  • http://nanofied.com Jonathan OBrien

    If you wanted to return multiple rows from the database instead of one result, how would this be accomplished?

    I played with it for a few hours today, but I couldn’t figure it out. I figured you would use an array inside of an array, but couldnt actually make it work.

    Much thanks to anyone that can help :)

    • Ronnie Swietek
      Author

      Multiple rows or multiple results? This tutorial is already showing multiple results. Not really sure why you would want to return multiple rows, unless it’s from a different table.

      • http://nanofied.com Jonathan OBrien

        Well I was trying to use this concept, and apply it to fetching a tables of data. In my application for example say I wanted to fetch all “categories” for the app, that were stored in a mysql database.

      • http://nanofied.com Jonathan OBrien

        For example, this is the JSON I am dealing with…

        [{"category_id":"1","category_name":"Academic Interests"},{"category_id":"2","category_name":"Affinity Groups"},{"category_id":"3","category_name":"The Arts"},{"category_id":"4","category_name":"Campus Communities"},{"category_id":"5","category_name":"Communications"}]

      • http://nanofied.com Jonathan OBrien

        Nevermind I figured it out :)

        Needed the JSON to be something like this…

        {
        “categories”: [
        {
        "category_id": "1",
        "category_name": "Academic Interests"
        },
        {
        "category_id": "2",
        "category_name": "Affinity Groups"
        },
        {
        "category_id": "3",
        "category_name": "The Arts"
        }
        ]
        }

        Then I was able to call specific items by using response.categories[0].category_id

  • Andreas

    When I install this on my N1, the window looks like this:
    [IMG]http://i56.tinypic.com/2zdqik3.png[/IMG]

    So your layout will only work if you are a iPhone user?

    I’m new to all of this so if someone would help with modifying
    the code to look properly on a Android device.

  • Andreas

    For Android devices it looks like this now:
    http://i56.tinypic.com/2zdqik3.png

    How can I modify this to look similar to a iPhone UI.

    I was thinking; a single window with a label at the top (with a backgroundGradient), text fields under and last the login button.

    • Ronnie Swietek
      Author

      Depending on the phone you have, the UI is going to change. You can get android phones to mimic the iPhone UI by using the image fields on all the objects, but I would not recommend that.

  • Maxwell Barvian

    I rarely leave comments, but I must say that this tutorial was incredibly helpful. Kudos to you sir.

    I wish there were more like this.

    • http://www.ronnieswietek.com Ronnie Swietek
      Author

      Hey, I really appreciate that, thank you!

  • moosc

    Hi,
    Can anybody put the php/mysql code in a server to trying to connect?
    I don’t know how install/configure server to do in local

    Thanks

  • http://www.sydcon.com Dave

    Great tutorial Ronnie! I’m having an issue though. When I use the post variables I always get a “Invalid username or password” error message. If I hardcode the values that I put in the form everything works fine. Any ideas?

    $username = $_POST['username'];
    $password = $_POST['password'];

    $username = “Dave”;
    $password = “Dave”;

  • Han

    Hi … Thanks for your awesome tuts.:) now i am addicted already to Titanium Framework because I am web developer so that your coding style is easy to catch up at short period. When I test your sample, I face this problem. After I submit username and password, i cannot see anything. Error is “Unable to parse JSON string” .. May I know how to fix that one. Thanks much!

    • http://ronnieswietek.com Ronnie Swietek
      Author

      Hey Han, it is most likely a connection error. In your browser, go to your post_auth.php file

      Browse to it by going to http://localhost/post_auth.php if you are using WAMP and if you’re using MAMP use http://localhost:8888/post_auth.php.

      See what errors come up. You can email me directly at ronnieswietek[at]gmail[d0t]com

      • http://ronnieswietek.com Ronnie Swietek
        Author

        sorry, connection error mean connecting to your database.

  • foroctfralion

    I love this tutorial and got it to work as you wrote it however I need to do something slightly different. I have a site written in cakephp and my user passwords are hashed using md5 and a security salt. Is there a way I can add that salt to the app or should i remove md5 hashing and send the password unencrypted to the post_auth page and allow cakephp to do the encrypting?

    Thanks in advance.

    • http://ronnieswietek.com Ronnie Swietek
      Author

      You know I’ve heard of salt but i’ve never used it before. I don’t think I can accurately answer that question.

  • http://12bubbles.com Pritam

    My localhost is up and running properly and I’ve set up everything (database, authentication php file) but I get an error message saying “Network Error” which definitely is the loginReq.onerror function call.

    Is there anything I can prevent this error??

    • http://ronnieswietek.com Ronnie Swietek
      Author

      in login.js replace the onerror method with this one and see what it says:

      loginReq.onerror = function(event)
      {
      alert(event.toSource());
      };

    • Fabian

      I think you are using the Androi emulator, so…… my solution for this was replacing this string in the files account.js and login.js :

      createReq.open(“POST”,”http://localhost/post_register.php”);

      to this:

      createReq.open(“POST”,”http://10.0.0.25/post_register.php”);

      Where 10.0.0.25 is my local server IP, replace it with yours

      Hope this can be helpful.

  • Arturo

    Amazing tutorial, will there be more like these?

  • http://russildi.com Alessio

    Hi Ronnie! Thanks for the great tutorial, it’s a great guide for beginners to start doing great things!

    I had a problem with the code, when I launch the app I get this error:

    “TypeError: Cannot call method “createHTTPClient” of undefined (app://main_windows/login.js#42)”

    I used the login.js directly from your sourcecode, maybe there’s been a change in the API or something like that that doesn’t accept that code anymore?

    I would really appreciate your help! Thanks in advance! :)

  • Serge

    You have a SQL injection vulnerability in your code.

    • http://www.cranklin.com Eddie

      I have 3 recommendations for a more secure system:
      1) don’t use md5. Use bcrypt. Md5 is easily crackable
      2) sanction your data before querying the MySQL db. A simple SQL injection attack is all that’s needed to crack this system.
      3) use https post. Your data is being sent in plaintext to the php authentication file and can be easily read through various packet sniffing methods.

  • natwar

    nice tutorial man.
    I hav a question.I want to add an image on a button.what to do.I hav put the the image in resources folder but its not working

  • http://www.allpctips.com Eskalin

    Great Job. You saved my day. Thanks for your valuable time in writing this.

  • Jim

    Thank you for a great tutorial.

    I am new to this but I was wondering how I could secure the part in the PHP file where username and password for connecting to mysql database are provided in cleartext. The PHP file seems to be quite accessible from the outside world. Is it possible to retrieve the php file or read inside it from the outside?

    Maybe I’m not getting this 100% please do advise.

    Thanks,

    Jim

  • Mosselman

    Thanks for (all 3) the tutorial! Great stuff.

    How do you go about keeping sessions on the server side? Does titanium automatically support cookies?

  • Dave

    Just like Mosselman, I would also like to know how sessions would be handled. — I don’t want to have my user log in every time they launch the app, and would like to show/hide certain buttons depending on their login status etc.

  • Dinesh B

    Hi,

    Same project i am trying in JSP. May i know what i need to return fro jsp page whether it’s JSON Object or JSON Array. I am not able to understand what they return in php code.

    Thanks in advance

  • Wayne

    Great tutorial! I was wondering if you have this working on Android. When I click the button to login nothing ever happens. When I look at the console output it says ignoring focus gain on window that already has focus.

  • Vivek

    Hi Ronnie,

    Awesome tutorial :) .
    I am a newbie for Titanium thus have some confusions. Above whatever u had performed, u used mySQL and our database and emulator etc. were on our local machine so everything went fine. But if talk about a real app (or app not running on emulator but on real device) then there should we use mySQL or SQLite ?
    Since i had installed XAMPP, so i saved post_auth.php to htdocs folder. But in case of real app (not running on emulator) do i have to save it inside my project folder (as created by Titanium) and refer to it like http://10.0.0.25/post_auth.php (as in one of the above posts) in my code ?

  • Jerry

    Great tutorial. Very practical.

    Can you point me to a tutorial in which the database is local to the app, like a sqlite that is part of the app? Would love to know/see how a user login/authentication is processed against a local db.

    Thanks.

  • mexico

    El mejor ejemplo para comenzar…. gracias

  • Atif

    hi there awesome work its really a great tutorial but am having one issue I did some modifications to make sure my mysql and DB is connection but it keep showing me null values please help I get this result from the auth php.

    Mysql Connected.
    Found the Database.
    {“logged”:true,”email”:null,”displayname”:null}

    Thanks

  • http://www.studio5eleven.com Nick P

    Having a minor issue when calling localhost from the Android emulator (using MAMP). I’m receiving the following error:

    Connection to http://localhost:8888 refused

    What’s odd about this is that iOS allows me to make the call without a problem. My guess is that this error has something to do with the Android system trying to call it’s true localhost, meaning that of the device / emulator… Could this be possible?

    Anyone have a workaround?

  • http://sandermangel.nl Sander Mangel

    You’re PHP is sensetive to SQL injection. Use mysql_real_escape_string() cause this way I can make the username: “bob’ OR 1=1″ and ill be able to login no mather what i send to the password variable.

  • Kigen

    ….awesome…!!!!

  • Some dude

    Thanks for posting this tutorial. It was very helpful. I was getting an error on WS 2008 R2 with XAMPP where my Android emulator was unable to connect to the localhost. I was getting this error…

    Access forbidden!

    New XAMPP security concept:

    Access to the requested directory is only available from the local network.

    This setting can be configured in the file “httpd-xampp.conf”.

    If you think this is a server error, please contact the webmaster.
    Error 403

    I fixed it by modifying the httpd-xampp.conf file. Here is how the bottom section of my file looks like…

    #
    # New XAMPP security concept
    #

    # Close XAMPP security section here

    Order deny,allow
    #Deny from all
    #Allow from ::1 127.0.0.0/8
    Allow from all
    ErrorDocument 403 /error/HTTP_XAMPP_FORBIDDEN.html.var

    # Close XAMPP sites here

    Order deny,allow
    Deny from all
    #Allow from ::1 127.0.0.0/8
    Allow from all
    ErrorDocument 403 /error/HTTP_XAMPP_FORBIDDEN.html.var

  • stexx

    Can happen that a domain host doesn’t accept remote POST?

    My code don’t work with POSTed data, work with a defined query.

  • danilo

    i know this question may be out of the current topic but after a lot of research i didn’t find anything helpful,
    i’m coding an app that takes existing data on the internet, it works fine until i use a connection with a proxy,
    the question is: is there a way to set the proxy credentials on the app?

    Thanks in advance

  • http://www.blueicestudios.com/ Rob

    Any reason why the name and email would return NULL in the alert?

  • Hampus

    Great tutorial, but just wanted to point something out from a security perspective. This is actually more an advice to all developers creating user login systems.

    To just hash the password with MD5 algorithm and think you’re safe and secure is a common problem amongst developers today. As Wikipedia states, MD5 should be considered cryptographically broken and unsuitable for further use.

    If an intruder somehow obtains a dump of the user table, they can easily decode the MD5 passwords using decryption techniques such as dictionary attacks, brute force or rainbow tables. This actually happend here in Sweden jut months ago when a large website got hacked and 200.000 emails and their passwords ended up on different forums.

    A more secure hashing algorithm should be used (preferably SHA-256 or SHA-512), together with a different salt for each password. This would make it very hard for any vicious intruders. To just decrypt one password with the above methods would take a long time, all of them… forever… Since even if two users have the same password, they would have different encrypted password due to the salt.

  • Karim

    Hi everybody,

    I have a problem with this tutorial.
    I followed all the steps and the chrome shows me this exception:
    message: “NETWORK_ERR: XMLHttpRequest Exception 101″
    it seems like the service is not consumed or the app.js can’t reach the service
    can anyone hepls me?

  • Mike

    Okay, so I am not sure if anyone is commenting on this thread anymore but I need some help before I take pull an Office Space move.

    I have seen that a lot of people have had similar issues and have fixed them pretty easily. Well not me!

    I am using Android Em and when I click “log-in” or “create account” I get

    (TiHttpClient-1) [68,380880] Sending error Connection to http://blah blah blah] refused”.

    In [blah blah blah] I tried my IP address and I tried the Android IP workaround 10.0.2.2. Nothing works!!

    WTF?!

    • Mike

      P.S. I disabled my firewall settings too.

  • Richard

    Couldnt get it to work…

  • Venkat

    Hi,

    This tutorial was really helpful for new titanium mobile app developers and I am facing a problem from so many days i.e. as you said I am removing all code from app.js file and I am able to a screen with Username & Password text fields with Login button. But when ever I clicked on text field on try to enter some thing then my simulator was immediately closed and I got the following message in Titanium console ” [INFO] Application has exited from Simulator ” . Please help me in this issue.

  • http://marcogomesweb.com Marco

    Nices tutorial!!

  • http://marcogomesweb.com Marco

    how can I do mysql PDO in titanium??? mysql_connect is discouraged in php official site!!!