Jump to content
Larry Ullman's Book Forums
Sign in to follow this  
nam797

Prevent Login From Two Places

Recommended Posts

Hello,

 

I am in the process of rewriting my SaaS Application in Yii and your tutorial on custom authentication using Yii framework really helped me understand what had to be done for autentication. I do have a question on how to stop a user from logging in at the same time with 2 seperate computers? I also am looking forward to your Yii book.

 

 

Thanks for all the help,

Nathan

Share this post


Link to post
Share on other sites

You could possibly save some unique information like agent string, ip-adress etc. in a session. If those do not match, you unset all sessions for that computer. The more information, the better the protection.

 

One question: how important is this? How secure is secure enough? That's pretty important to know to determine the approach.

Share this post


Link to post
Share on other sites

Thanks for you comments. its important because i charge per user per month. If i don't have that in place companies would purchase less users knowing that they can have multiple people login under one account.

Share this post


Link to post
Share on other sites

I'm doing something like this myself, but it's more to guard against session hijacking.

 

This is what I do:

 

1. ) Concatenate the user agent with their email adress and md5 it. This is their secret key. Store as unique info as possible. I save this to a key in the session.

2. ) I compare this key for each request. I also just check if a session key is true.

 

Here is the code I'm using. I haven't checked if it actually works as it is a work in progress, but It'll give you something to build on. The code used is pretty much based on a tutorial to guard against session hijacking, but is baked into a class.

 


/**
 * session_validate()
 * Will check if a user has a encrypted key stored in the session array.
 * If it returns true, user is the same as before
 * If the method returns false, the session_id is regenerated
 *
 * @param {String} $email	The users email adress
 * @return {boolean} True if valid session, else false
 */

public function session_validate(  )
{

	// Encrypt information about this session
	$user_agent = $this->session_hash_string($_SERVER['HTTP_USER_AGENT'], $this->user_email);

	// Check for instance of session
	if ( session_exists() == false )
	{
		// The session does not exist, create it
		$this->session_reset($user_agent);
	}

	// Match the hashed key in session against the new hashed string
	if ( $this->session_match($user_agent) )
	{
		return true;
	}

	// The hashed string is different, reset session
	$this->session_reset($user_agent);
	return false;
}

/**
 * session_exists()
 * Will check if the needed session keys exists.
 *
 * @return {boolean} True if keys exists, else false
 */

private function session_exists()
{
	return isset($_SESSION['USER_AGENT_KEY']) && isset($_SESSION['INIT']);
}

/**
 * session_match()
 * Compares the session secret with the current generated secret.
 *
 * @param {String} $user_agent The encrypted key
 */

private function session_match( $user_agent )
{
	// Validate the agent and initiated
	return $_SESSION['USER_AGENT_KEY'] == $user_agent && $_SESSION['INIT'] == true;
}

/**
 * session_encrypt()
 * Generates a unique encrypted string
 *
 * @param {String} $user_agent		The http_user_agent constant
 * @param {String} $unique_string	 Something unique for the user (email, etc)
 */

private function session_hash_string( $user_agent, $unique_string )
{
	return md5($user_agent.$unique_string);
}

/**
 * session_reset()
 * Will regenerate the session_id (the local file) and build a new
 * secret for the user.
 *
 * @param {String} $user_agent
 */

private function session_reset( $user_agent )
{
	// Create new id
	session_regenerate_id(TRUE);
	$_SESSION = array();
	$_SESSION['INIT'] = true;

	// Set hashed http user agent
	$_SESSION['USER_AGENT_KEY'] = $user_agent;
}

/**
 * Destroys the session
 */

private function session_destroy()
{
	// Destroy session
	session_destroy();
}

 

Please note $this->user_email inside the public function session_validate. I use this inside a user class, and as the user must be logged in, this variable is always available. I guess you could just change it to something other unique.

 

If you want more security, look at the method session_hash_string(). Edit that and include more randomness and higher level of encryption if you need it. I would guess this should already work pretty good for your purposes, but you'll maybe have to do some alterations.

  • Upvote 1

Share this post


Link to post
Share on other sites

Finally i understand your code Antonio :) , HTTP_USER_AGENT can be used as a good unique identifier, but as Larry was saying user IP is NOT as it can change or there can be more than one person with the same IP on the same network.

 

PS Did you solve the Wordpress plugin/PHPBB3 problem?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×