Since HTTP is a stateless protocol, the mechanisms for adding "state" (such as "logged in") have to use one or more of the following methods:
Mangled URLs (including a session key somewhere in the URL)
Basic Authentication (login box, usually managed in the .htaccess file)
Hidden fields (if your application goes from one form to another)
Cookies (but be sure to provide a way to logout easily, or time it out)
Firing off a separate web server for each session (useful in low-volume
applications)
Each has advantages and disadvantages. Be sure to steer clear of anyone that
advises you to use any of the following:
IP address, even if attached to browser type (it's not unique for proxies,
and can even change within a single session)
The Referer (accessed through $ENV{HTTP_REFERER}) which can
be trivially faked and is stripped automatically at some corporate firewalls
Any kind of client-side session management using Java or Javascript
(some firewalls actually strip this stuff, making your site useless to them,
and all security-conscious people have this stuff turned off anyway)