possible in PHP? login, email, cookie

i'm trying to come up with a authentication solution that will allow users from .edu domains to view all content without being prompted.  for other users it needs to prompt for more information before allowing them to proceed.   this is what i think i want to do:

1. check for a cookie to see if they have already authenticated.  if so, skip to end
2. check the domain they are coming is .edu then skip to end
3. for all other domains, they need to enter their email address:  
     if their email address ends in .edu, the server will send an email to them with a link that they click.  
        when they click it, the server puts a cookie on their machine and never asks for their email address again
     if email address doesn't end in .edu, redirect to a page where they can enter more info.
       someone will manually look at the information and determine whether to send an email with a cookie link or not

i know how to do it with servlets, but i don't know if its possible in PHP.  any thoughts?  i know this is a lot, so whatever pieces you could help on would be great.  thanks!
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Yes, almost anything is possible.

Here's how to play with cookies: http://www.php.net/setcookie
Here's how to get environment variables (including user ip information): http://www.php.net/getenv
Here's how to send email: http://www.php.net/mail
Here's how to use headers to redirect to other pages: http://www.php.net/manual/en/function.header.php
if ($_COOKIE['eduExist'] == 'edu1')
         //open the page
         include_once "somepage.php";
}//end if
         //verify where you from
         //this should verify what the persons address is
         $hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
         if (preg_match("/(.*?)\.edu/is", $hostname)
                   //setting your cookie - don't forget to change your domain name,
                   //also you can change your security setting
                   //don't forget to keep the period before your domain name
                  setcookie ("eduExist", "edue1", time() + 3600, "/", ".example.com", 1);
                   include_once "somepage.php";
         }//end if
         else if (!$submit)
                   echo "You are not showing from a *.edu page. Please send us your edu email address so we can send you an email for verification";
                   echo "<form action=\"".echo $PHP_SELF."\" method=\"post\">";
                   echo "Your name <br />";
                   echo "<input type=\"text\" name=\"name\" />";
                   echo "Your Email Address <br />";
                   echo "<input type=\"text\" name=\"email\" />";
                   echo "<input type=\"submit\" name=\"submit\" value=\"submit\" />";
                   echo "</form>";
          }//end else
          else if ($submit)
                    //don't forget to change your variables (ALL CAPS)
                    $headers = "Reply-To: ".$_POST['name']."<".$_POST['email'].">\n";
                    $headers .= "MIME-Version: 1.0\n";
                    $headers .= "Content-type: text/html; charset=iso-8859-1\n";
                    $headers .= "From: YOUR NAME <EMAIL ADDRESS>\n";
                    $headers .= "X-Priority: 1\n";
                    $headers .= "X-MSMail-Priority: High\n";
                    $headers .= "X-Mailer: php\n";

                    $information = "".$_POST['name'].", would like further information";

                    //don't forget to change these as well
                    $to = "From: YOUR NAME <EMAIL ADDRESS>\n";

                    $subject = "Verification from me";

                    mail( $to, $subject, $information, $headers);
                    echo "Thank you, we shall verify and send you further information";
}//end else

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
As for the email part, when they enter their email address in the form, you should add a record to a database table with that email address and a unique numeric ID.  Send the email address a link which contains the id, and an encrypted version of the address, using a known private key as the salt.

Clicking on the link compares the id and the encrypted email address, and sets the cookie if it passes.
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

spathiphylumAuthor Commented:
oh wow.   that's a lot easier than i thought it would be.  in fact, it's easier than it would be with a java servlet, i think.  

the sending of the email and what to do when they click it is a little tricky.  i assume that there's some way to link PHP and mysql?  

shmert, i didn't understand this part: "Send the email address a link which contains the id, and an encrypted version of the address, using a known private key as the salt."   why would the link need to include the address?

it sounds like something i want to do.  i'd like to restrict people from simply forwarding the link to someone else (who doesn't have a .edu address).  so i was thinking either the link would expire or we would keep track of their IP address when they requested the link and compare that to the one they used when they clicked it.
I'd advise against relying too much on IP addresses for your authentication, mostly because they tend to change quite often.

You're not going to stop anybody who's halfway savvy from getting access to your site.  All someone has to to is look at his cookies from your site to get the "isedu1" string, then anyone can spoof the cookie.

My suggestion to send an encrypted form of the email address was so you can uniquely identify a user who clicks on the link in his email program, and relate him to a record in a database.  Then, instead of setting "isedu" in a cookie, you can set that combination of the userID and encrypted email address as a cookie value, so each time the user visits the site you can link it back to that initial authorization.

Also, if you want to prevent people from sharing accounts, you might track the IP address of the user/email combo, and not allow the same email address to access it from a different IP address for some reasonably small amount of time.  Again, not a perfect solution, but not bad.
That doesn't work if they have dynamic IPs. What you could do however is keep the cookie for about 2 weeks, and then expire it, asking them to prompt you again for another one. Each time they ask for it, they would get another one. You can keep the link available for a one time usage only which outputs the cookie to the users Harddrive. Once they access that page, that link in your database table need not exist.

Example: someone sends you that email address. You send an email back with a random string.

You have a table in your database that has "ID", "email address", and "random string" and "permission"
Default for permission can be "0". As soon as that link is opened, the value for permission becomes "1" and then that link does not exist.

call in the url by using mysql_num_rows().

If num_rows < 1, return false. and you can't show the page.

Something like that, I could show a complete example of that if you really want it.
spathiphylumAuthor Commented:
shmert: i see what you're saying ... hmmm ... but what if the cookie was only put on their machine if they had a .edu address -- i.e. for all other users, we just don't put any cookie.  wouldn't that be pretty secure?   it seems like it would pretty difficult to spoof the whole cookie.   and to make it more secure i guess i could put some encrypted string value in there.   also, if the link contained the id number of the user in the database, would we still need to put the email address in?

the reason i wasn't too worried about the dynamic ips was that i figure that i only need the IP to be the same from the time they enter their email and the time they click on the link.  clicking on the link would put the cookie on their machine.  subsequent visits to the site would just see that the cookie exists and move on without even looking at the IP.   it's true that someone might enter their email address, log off and then back on again -- getting a new IP, and then check their email, but this probably wouldn't happen much.

duniyadnd:  so you're saying that the user would have to enter his/her email address again every 2 weeks?  that wouldn't be good.   but the example sounds exactly like what i wanted to do with the expiring links.   but it's not as important as just getting the fundamental stuff, so i put it in a separate question:  


what i really need is help with is generating the actual link they click and the code that processes it once they click it.   that, combined with what duniyadnd provided, should take care of it.  and then if i can get the expiring link question answered, i think it's pretty secure.  what do you guys think?
"duniyadnd:  so you're saying that the user would have to enter his/her email address again every 2 weeks?  that wouldn't be good."

Well no, you can easily update the cookie every time the person comes. But if the person does not come for over two weeks straight, then you can presume that he isn't going to come back anytime soon, and then that cookie is expired.

something like:

 if ($_COOKIE['eduExist'] == 'edu1')
         setcookie ("eduExist", "edu1", time() + 3600, "/", ".example.com", 1);

         //open the page
         include_once "somepage.php";
}//end if

That way, the cookie has a life of two weeks every time the person accesses your site.
OK, thanks for explaining the IP address thing.  Here's some meta-code.  Some of the functions aren't implemented.  But you can use code from dun's first post to flush it out.

if (!isset($_SESSION['user']) {
    // unknown user
    // check for cookie first (easiest to do)
    if (isset($_COOKIE['userID'])) {
        $userID = $_COOKIE['userID'];
    } else if (remote_addr_is_edu()) {
        // first-time .edu visitor
        $userID = create_new_userid(); // create a new user record and return the newly created ID
    } else if (isset($_REQUEST['email_cookie_id'])) {
        // user clicked on an email link to get here
        $userID = addslashes($_REQUEST['email_cookie_id']);
    } else if (isset($_REQUEST['verification_email'])) {
        // user filled out the email form
        send_email_to_non_edu_user(); // creates a new user record, and sends email to the user with the ID in the clickable link
        die("An email has been sent to your address, please reply to it...");
    } else {
        // non-edu user needs to supply his email address to continue
    $result = mysql_query("SELECT * FROM user WHERE _id=$userID");
    if (mysql_num_rows($result) == 0) {
        // unset the userID cookie if it's set
        die ("Unknown userID $userID");
    $_SESSION['user'] = mysql_fetch_assoc($result);
Oh, just to let you know about my code up top, it isn't tested, and I found one error with it already. That's just a sort of gist of what you wanted initially. If you copying and pasting it, you'll have to ensure that the cookie name stays consistent (I have edu1 and edue1 there by mistake, which are different names). Just FYI.
spathiphylumAuthor Commented:
thanks guys.   some things just came up, but hopefully i'll have a chance to look at this stuff this week.
It's been a while since the last post.  Is the problem solved?
spathiphylumAuthor Commented:
i haven't forgotten about these.   we've been looking them over, fixing the bugs.  if we're not done by next week this time, i'll just award the points anyway.   thanks for your patience
spathiphylumAuthor Commented:
we fixed the bugs and it seems to work!  thanks.    unless there are any complaints, i'm planning on splitting the points like this:

225: duniyadnd
225: shmert
50: snoyes_jw
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.