TwitPic-Like Twitter Sign In With PHP and Zend

There are two ways to let people sign in to your app with their twitter account, the preferred(OAuth) and new way and the old easier way, which is what am about to show you.

One of the reasons for why I like Zend over other frameworks is because of the classes it has to interact with APIs like Amazon, Google, Flicker, and Twitter. If you have never used Zend don’t worry it’s easy to install and use.

The first thing you have to have of course is Zend, and I wrote a post on how to install it here, it won’t take you over 5 minutes to install it once you have downloaded it.

This tutorial will consist of three files, the login, profile and logout pages. Am going to be using a CSS framework to style the profile page, you don’t have to, but just in case you want to use it here is a link that will show you how to use this framework am using.

Login Form: index.html

I will name the login page, “index.html” and this will be its content. It’s just a form with two fields, username and password.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Twitter Login System With Zend<title>
</head>
<body>

<form action="profile.php" method="post" class="box">
 <label>Username</label><br/>
 <input type="text" name="username" class="text"/><br />
 <label>Password</label><br />
 <input type="password" name="password" class="text"/><br />
 <input type="submit" value="Login" />
</form>

</body>
</html>

Profile Page: profile.php

The profile page’s name is going to be “profile.php” with this content.

<?php
// include the zend class
require_once 'Zend/Service/Twitter.php';
// check if the cookies are already set
if(!isset($_COOKIE['username']))
{
// set the cookies
setcookie('username',$_POST['username'],0,'/','.yoursite.com');
setcookie('password',$_POST['password'],0,'/','.yoursite.com');
}
// assign cookies to variables
$username=$_COOKIE['username'];
$password=$_COOKIE['password'];

try
{
// try to connect to twitter
// assign the username and password
$twitter=new Zend_Service_Twitter($username,$password);
// verify credentials
$response=$twitter->account->verifyCredentials();
}
catch (Exception $e) {

// if there was an error  connecting show the error
    echo 'Error: ',  $e->getMessage(), "\n";
}

?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<link rel="stylesheet" href="../../css/blueprint/screen950.css" type="text/css" /> 
<!--[if IE]>
<link rel="stylesheet" href="../../css/ie.css" />
<![endif]--> 
<title>Twitter Login System With Zend<title>
</head>
<body>
	<div class="container">
<?php
if($response->id>1)
{
// we got a user id, so the response was "ok"
?>
	<div class="span-24"><!-- menu -->
		<a href="logout.php">Logout</a>
	</div>
	
	<div class="span-15"><!-- picture and username -->
		<img src="<?php echo $response->profile_image_url;?>" alt="<?php echo $response->name;?>" /><br />
		<label><?php echo $response->screen_name;?></label>
		<p>
		<small>
		<label>Latest:</label>
		<?php echo $response->status->text;?>
		</small>
		</p>
	</div>
	
	<div class="span-9 last"><!-- profile information -->
		<fieldset class="box">
			<label>Name</label> <?php echo $response->name;?><br />
			<label>Location</label> <?php echo $response->location;?><br />
			<label>Web</label> <a href="<?php echo $response->url;?>"><?php echo $response->url;?></a> <br />
			<label>Bio</label><br />
			<?php echo $response->user->description;?>
		</fieldset>
	</div>

	</div>
	<?php
}
else
{
	// invalid user name and/or password , show the login form again.
	?>
	<div class="error">
	Invalid username or password
	</div>
	<form action="profile.php" method="post">
 <label>Username</label><br/>
 <input type="text" name="username" /><br />
 <label>Password</label><br />
 <input type="password" name="password" /><br />
 <input type="submit" value="Login" />
</form>
	<?php
}
?>
</div>
</body>
</html>

profile.php Explained

That was a lot of code, I hope the comments help you out a little bit, but just in case they didn’t let me explain what we are doing. The first thing we do is include the Zend class we will need, get the variables from the form and put them in cookies, then we store those cookies into variables for later use.

// include the zend class
require_once 'Zend/Service/Twitter.php';
// check if the cookies are already set
if(!isset($_COOKIE['username']))
{
// set the cookies
setcookie('username',$_POST['username'],0,'/','.yoursite.com');
setcookie('password',$_POST['password'],0,'/','.yoursite.com');
}
// assign cookies to variables
$username=$_COOKIE['username'];
$password=$_COOKIE['password'];

Note:
One of the reasons for why OAuth is better is because it doesn’t require the user to give out his/her password like we do it here. Read PHP.net’s page on setcookie if you want to implement https

Now that we have the user’s name and password we can try to connect to twitter. Each time we call a twitter API method an exception might be thrown, you might not be familiar with the try-catch syntax, all this does is say “try this and if that didn’t work let me know why”

try
{
// try to connect to twitter

// assign the username and password
$twitter=new Zend_Service_Twitter($username,$password);
// verify credentials
$response=$twitter->account->verifyCredentials();
}
catch (Exception $e) {

// if there was an error  connecting show the error
    echo 'Error: ',  $e->getMessage(), "\n";
}

Am not going to explain the HTML except for the header. I included a CSS framework called Blueprint that I like to use, but you don’t have to for this tutorial.

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<link rel="stylesheet" href="../../css/blueprint/screen950.css" type="text/css" /> 
<!--[if IE]>
<link rel="stylesheet" href="../../css/ie.css" />
<![endif]--> 
<title>Twitter Login System With Zend<title>
</head>

The account verify credentials method we used returns this XML response and I use the id to check if the response was valid, that is, the username and password are correct if we get an ID. If the ID is not greater than 1,we show the login form again.

<?php
if($response->id>1)
{
// we got a user id, so the response was "ok"

}
else
{
	// invalid user name and/or password , show the login form again.
	?>
	<div class="error">
	Invalid username or password
	</div>
	<form action="profile.php" method="post">
 <label>Username</label><br/>
 <input type="text" name="username" /><br />
 <label>Password</label><br />
 <input type="password" name="password" /><br />
 <input type="submit" value="Login" />
</form>
	<?php
}
?>

The $response variable holds the user info, so I can do stuff like this to display it.

		<fieldset class="box">
			<label>Name</label> <?php echo $response->name;?><br />
			<label>Location</label> <?php echo $response->location;?><br />
			<label>Web</label> <a href="<?php echo $response->url;?>"><?php echo $response->url;?></a> <br />
			<label>Bio</label><br />
			<?php echo $response->user->description;?>
		</fieldset>

Logout Page: logout.php

To log the user out from your website expire the cookies. To log the user out from twitter end the session using Zend.

<?php
require_once 'Zend/Service/Twitter.php';

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

setcookie('username','',time()-3600,'/','.yoursite.com');
setcookie('password','',time()-3600,'/','.yoursite.com');

try{
$twitter=new Zend_Service_Twitter($username,$password);
$twitter->account->endSession();
}catch (Exception $e) {

// if there was an error  connecting show the error
    echo 'Error: ',  $e->getMessage(), "<br />";
}
?>
<html>
<head>
<title>Twitpic-Like Login System<title>

</head>
<body>
<h1>You have logged out</h1>
</body>
</html>

The Result (picture)

If it all went right you should see something similar to this for your profile page.

Profile Page Result

Profile Page Result

That is all the code that is needed to build a twitpic-like sign in with twitter, here is a piece of advice however. If you are planning to build “the next big twitter app” don’t use this method of authentication, use OAuth instead since it’s what twitter and twitter users prefer, the main purpose of this tutorial was to show you how a framework can save you tons of work and this perhaps might get you to try one whether is Zend, CakePHP, CodeIgniter or any other. But If you want to build an app for yourself I don’t see any harm in using this method of authentication, hopefully Zend updates to OAuth soon.