Login sytem with PHP - php

Good day.
I have questions about the login system , that disturbed me quite a long time. For this i want you to imagine that i have 2 pages login.php and userpage.php. The login page contains fields for input of user name and password. While userpage contains all the information about the logined user. When user inputs his data, some class Connection checks him in the database and if user exists, creates a session.
When I'm creating a redirection from login.php to userpage.php, how should i redirect users data? (Should I use global arrays (like $_SESSION) to transfer the info or I should connect the db again from the user page?)
Should I create some multi-threading (Do not judge strictly, I'm a newbie) for userpage.php, to be created for multiple users, which are trying to login at the same time?
How should I protect the information (code side), for being hard to read? (For example Facebook pages source-code. because i don't want some "bad guys" to view my sources) and other things.
How can I make some users to see what the others can't ? For example userpage.php shows different links and information for different users and all the information for me .
How can i prevent membership.php from being viewed?(Is there some other way than using header?)
How can i prevent my require and require_once from being viewd at the login.php and userpage.php ?

1.) When I'm creating a redirection from login.php to userpage.php, how should i redirect users data? (Should I use global arrays (like $_SESSION) to transfer the info or I should connect the db again from the user page?)
You need to have a connection to the db everytime you want to get the user's data. You can create a session to store a unique attribute for the user, like $_SESSION['id'], when the user is successfully logged in, and you can use that value on any page to query the db and get the necessary user data.
2.) Should I create some multi-threading (Do not judge strictly, I'm a newbie) for userpage.php, to be created for multiple users, which are trying to login at the same time?
No, you don't need to worry about users connecting at the same time. The server can handle this. When you have a million users or so, you can start considering this. (Although, even then I'm not too sure. Unfortunately I've never had that problem ;) )
3.) How should I protect the information (code side), for being hard to read? (For example Facebook pages source-code. because i don't want some "bad guys" to view my sources) and other things.
You cannot prevent anyone from seeing your markup and styles, that is, your html and css, or any client side scripting, like javascript. However, your php is server side and not displayed in the source. The 'bad guys' will not be able to view source to see your db connections, php logic, etc.
4.) How can I make some users to see what the others can't ? For example userpage.php shows different links and information for different users and all the information for me .
There are different approaches to take. The simplest is probably to store the user's 'permission level' in the db, and then check that every time you load content. For example,
if ($user['permission']==1)
// Show something
elseif ($user['permission']==2)
// show something else
5.) How can i prevent membership.php from being viewed?(Is there some other way than using header?)
The easiest way to do this is by checking to see if there is an active session, and if not, redirect:
if (!isset($_SESSION['id']))
header("Location: login.php");
6.) How can i prevent my require and require_once from being viewed at the login.php and userpage.php ?
Not too sure what you mean by this, but consider this: require and require_once are the exact same as including the code directly in the file. If you are referring to them being viewed directly by the client by hitting 'view source', don't worry - see answer to question 3.
Note:
These answers are simplified, and there are plenty of other complications to consider. Some of this stuff may not make sense, but I wouldn't sweat it too much. I would recommend starting small - find a decent tutorial or two on how to create a simple user database, a registration, and login page, and start there. No answers you get here will substitute research, practice, and trial and error. Start small, and things will quickly become clearer as you progress.

Save the users state in a cookie or in a session. Note that you need the session_start() the userpage.php page as well as the rest of the page were the user is connected.
More info on http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
See the above link.
No one can read PHP code because it is server side and not client side. So your code is secure already from its own structure.
Let users have different level from the swl-database. If a user got auth 1 they see some links, if they got user auth 2 they see other things.
See page from answer 1
See page from answer 1

Considering your stated fact that you are newbie,I will also assume that the login system is more of practice thing and not a real world app.
Now to answer your queries point-wise.
Storing data in SESSION variables is alright.However,do not store too many data in SESSIONS.I would suggest just store the userid for the user and use that to gather and display info in the userpage.php. As the app gets bigger,you will definitely need to make connections in each individual page.
Use SESSION and COOKIE combination to create multiple user logins. However,Refrain from trying to implement/allow same browser multiple logging-in.SECURITY ISSUE.
PHP source code is anyways not readable from client-side.Regarding javascript & css-u can maybe minify it.But that would still not make it client-safe.
There are many ways to implement this.Maybe have a $_SESSION['admin'] =true when a admin logs-in and use it to display/hide info on userpage.php.
Same as NEXT
What it is that u want to hide?If its HTML/JS ,u dont't have much choice. One solution may be to use if-else in ur php code and restrict display of code present in header.php and the pages included via require and require_once.
This is a very basic guide.Your strategies may vary depending on the complexity of your application and also if/when you start using framweorks . Happy logging-in !!
ADDITIONS wrt to application structure.
Considering that your end product would be a system that allows a user to register and login/logout,i would suggest a following structure to begin with.
Structure-
index.php
|--action
|---register.php
|---logged_in_user_landing.php
index.php-- This is main page and used to redirect to individual pages based on actions.
check if SESSION is set.
If yes,include action/logged_in_user_landing.php else include action/register.php.
As actions increase,you can add if-else and include more pages accordingly.
In register.php,u have the form for login. On submit, redirect to index.php (via form action).
establish db connection in index page and check username-password combination.If correct,set the SESSION for that user and include the 'action/logged_in_user_landing.php'.
Have a unique identifier sent along when redirecting from each individual page,So that u can identify what to do in index.php.
This is a very simple architecture that should get u started.Its kind of a controller based architecture and will help you in the future when u go into MVC architectures.

Related

PHP splitting up classes

I'm fairly new to PHP and trying to figure out how to logically split up my classes. Here is the very basic setup.
index.php -- Top page. When login button is pressed, it calls an external authentication server.
callback.php -- Authentication server sends call back here. I store the user's login name.
game.php -- this is where I have a web game that makes a POST request to callback.php
Here is what I thought is "correct" practice from other OO languages.
I'd like to get the data received in callback.php and store it somewhere else (data.php). The only way I can figure out how to do this is to use a session in callback.php and read it in data.php. Is there a better way to do this or should I keep the data in callback.php (and make the POST request to callback.php instead of data.php)?
After the callback.php gets the data from the authentication server, I use a redirect to go to game.php. If the user goes straight to game.php and isn't logged in, I also use a redirect. Is there a better way?
header("Location: http://www.mypage.com/game.php");
I'm happy to post any code but I'm guessing it's not necessary for these types of questions. Let me know and thanks!
The purpose of OO programing to keep code as module as possible while bundling relative modules together.
Example:
User Object - contains all code relative to users
Game Object - contains all code relative to games
It is still very likely that you will have code that doesn't belong to a specific object, but more to a particular set of actions. However, OO programming can still be applied even to these.
Example:
Action page: contains all code relative to dealing with a specific group type of actions (Like handling all the actions/callbacks from a specific frontend page).
That being said, your initial statement of separating into the 3 different files is fine.
I'm assuming the index.php is the front facing said that the user interacts with, so separating that from the backend process or controller is good. It would be better to use an require_once("data.php") versus sending the data over the network again and this way you can save the data to that instance and access it without having to use session variables. I can process the data however you want, and once you get the desired results you can do your header() redirect.

login form how to give access only to one device

For learning reason, trying to give login access only for one device
so I added new row inside user table in database called ip which stored registered user ip then for example I did something like that
if($user->ip == $myip){ echo 'success'; }
the problem here that ip changing so the form can't let me access or logged in,
So my question is there anyway to logged in from only by using one device without using ip ?
Fixing the IP address might not be possible. There are a number of other ways to achieve your goal, ranging from cheap and simple to very complicated and expensive. Here are a couple.
Use a USB key (such as this one) that enters a strong password on the push of a button.
Use two way SSL (see question), safe but complicated
The easiest of these options (and my recommendation) is to set a long living cookie (using a browser developer toolbar or extension) and check in PHP for the existence of the cookie in the $_COOKIE array
Good luck!
You must use a cookie, and if the cookie is set, you must not allow a new login.
The following experts and accepted solutions agree:
how to identify remote machine uniquely in php?'
Accepted solution: uniquely identify the computer via cookie
Uniquely identify one computer
Accepted solution: set a cookie that must be present on future logins
How to uniquely identify a computer?
Accepted solution: the solution discusses Evercookie but the point seems to be you need a cookie
So, in summary, however you identify this user, if the user has a cookie, let them in. If they don't, I don't know what you're going to do, but maybe that's part of what you are mysteriously trying to learn here.
Not the best solution:
Public IP's are dynamic, meaning when a router is restarted - they obtain a new IP address. Yes, you could never restart the router but you cannot protected against physical things like electricity meaning check-ups, power outs, etc..
The best idea here is to make this Software un-accessible from outside the node you want to be able to interact with. Meaning, use Apache and MySQL (like XAMPP) and run it only on that node.
If you're looking for a long-term solutions to be able to add IP's, used a shared network. Or implement security conventions like Authentication (login).
However, if you want to consist in building it from your point of view: use the $_SERVER super variable to access the current IP and you'd need to know it before they visit (so find it out by going to something like what is my ip.
if($_SERVER['SERVER_ADDR'] == $somePreknownIp) {
// authorised
}
I would recommend using a cookie instead. First add the following code:
If ($user -> me) {
setcookie("HeyItsMe", 'SomeReallyHardToGuessValue', time()+3600*24*365); /* this would expire in 1 year */
}
This will set the cookie for just you since you're logged in. Then, you can get rid of the the code and add the following in your login screen:
if (isset($_COOKIE['HeyItsMe']) && $_COOKIE['HeyItsMe']== 'SomeReallyHardToGuessValue') {
/**show them the login screen **/
} else {
exit;
}
If your have dynamic IP then you can not do it using IP address. Therefor I suggest you to use sessions.
To do that you have to create another PHP file in your root folder(project folder). And do not share that file name with others. (I named that file as loginHandler.php)
loginHandler.php file has following content.
<?php
session_start();
// assign value to loginHandler.
$_SESSION['loginHandler'] = "99";
// redirect to login page
header('Location: login.php');
?>
On your login page (login.php), you have to start session top of the page. And if $_SESSION['loginHandler'] set, Then it will display your login form. Otherwise it will display only rest of the content.
<?php session_start(); ?>
<p>Page Content</p>
<?php if(isset($_SESSION['loginHandler'])): ?>
<div id="loginBlock">
<form method="post" action="">
<p>Your Login Form</p>
</form>
</div>
<?php endif ?>
<p>Page Content</p>
If you want to login. Then first you have to access loginHandler.php file. Then you will be redirected to login.php page. And you can access login form.
But others do not know about loginHandler.php, Therefor they try to access login form directly. Then that login form will not display for them.
Edit:
Upon re-reading the question I see that I've misunderstood what the OP was really asking for. Leaving my original reply underneath, in case someone else finds it useful.
The proper answer to this questions is: Why care about who gets to see the login form? Just use a properly strong password, and the correct techniques for preventing brute-force attempts (throttle limiting).
Any secret key, or similar, you add to this script is just another password after all. Any other information derived from your connection, browser or whatever, can be sniffed and spoofed by an attacker (or even changed from underneath you, for any reason).
Limiting to a single (or range of) IP(s) is only really useful if you have a static IP, and want to make it a bit more difficult for any potential hacker to break your password.It is not a replacement for a good password.
Original answer:
This is actually a rather common problem, and solved quite a few times. While it takes a bit of work to implement the solution, it is quite straight forward.
First off you need to create a table to keep track of the sessions for each user. This table needs only two (or three) fields:
user id
session id
(timestamp)
The timestamp can be omitted as it's not essential, but it might be nice to have for debugging/logging purposes.
Once you have that you need to re-write your login script a bit. So that it first checks if the user has any active sessions already, if they don't then simply create a new session and store its ID in the abovementioned table.
However, if the user does have a session active already, then you need to do one of two things:
If you want to disallow any further logins, simply return an error explaining that they are already logged in.
Or, delete the old sessions and then log them in on the new device.
Of these two approaches I'd prefer the latter one, as the first one can lead to a user accidentally locking himself out of the system. Until you, as the administrator, go in and manually delete the old session.
The second approach will require a bit more work, in order to delete/invalidate the old sessions, but is generally more robust. It will also give the users the least amount of surprise, as they expect to be logged in when attempting to do so. Instead of having to go chase down whatever unit they think they logged in with last.
Another thing you could do, if you decide on approach 1, is to log the timestamp and then use this in conjunction with the max session lifetime. If time_now - max_session_lifetime > timestamp then you know the session is old, and can be deleted automatically. Ensuring that the user will, eventually, be able to log in without having to rely upon finding/getting the old unit, or you manually deleting it.
I won't post any code on this, for two reasons:
You haven't posted the code in which you handle the logins, making it impossible for me to suggest any specific changes.
The changes needs to be done in quite a few places, and requires a redesign of your logic.
However, follow my logic and set up a pseudo code/flowchart diagram and it should be quite easy to implement.
one thing goes into my mind.
If you know his phone number, send him SMS with token to log in.
Of course there is technical issue about sending SMS message, that i'm as newbie are unable to solve...
You can use Mobile-Detect php library and get the device information of particular device and can add device details in db then you can put a check for that particular device.
Official documentation for library is here - Mobile-Detect
And for usage go here - Usage example
There is one for Client side also - mobile-detect.js
Hope this will help you some way (y).
You can combine 2 approaches into one. You have a list with 3 IP-addresses. For example:
$whitelist = [
'192.168.1.2',
'192.168.1.3',
'192.168.1.4',
];
Then you should check address or cookie:
$accessCode = 'Xvj482Sfjfi2Ghj23PoqT'; //some random string
$cookieExpireValue = time() + 3600 * 24 * 365 * 3; //3 years
$isIpValid = ($_SERVER['REMOTE_ADDR'] && in_array($_SERVER['REMOTE_ADDR'], $whitelist, true));
$isCookieSet = (isset($_COOKIES['access_code']) && $_COOKIES['access_code'] === $accessCode);
if ($isIpValid || $isCookieSet) {
setcookie("access_code", $accessCode, $cookieExpireValue);
echo 'success';
}
Pros:
It restricts access
If IP-address changes, user has access for 3 years
You can change $accessCode and $whitelsit to block users which already got access
It simple
Cons:
If some user gets whitelisted IP, he will get access
If a user loses the cookie (OS reinstall, browser clean, etc) with new IP-address, he will lost access (just change the $whitelist)
In case, you have different user's records for every device and you restrict access after form's submitting, you can save a new IP-address for that user if the user has a valid cookie:
if ($isIpValid || $isCookieSet) {
setcookie("access_code", $accessCode, $cookieExpireValue);
$user->ip = $_SERVER['REMOTE_ADDR'];
$user->save();
echo 'success';
}
and change the validation:
$isIpValid = ($_SERVER['REMOTE_ADDR'] && (in_array($_SERVER['REMOTE_ADDR'], $whitelist, true) || $user->ip === $_SERVER['REMOTE_ADDR']));
In this case you can get rid of the whitelist of addresses, just set ip for every whitelisted user.

php session to check if you already redirected the user

I do not have a database.
My website will use a php class (mobiledetect.php) to find the user agent and type of browser, whereby a certain .css file is parsed. If the user prefers to view the full css site, how can I create a php session so as not to redirect the user again. So, only to ask the first php class once?
I am new to php.
Basically, I see two options that you have -- one is to just store the information locally (in the PHP session), the other is to store the user preferences in a cookie.
If you could actually show us your mobiledetect.php code, it would probably be easier to help you with actual code.

Should I use sessions for "LOGINS" on my site?

I have a classifieds website, where anyone (no need for login currently) can post a classified. It is PHP based.
The procedure for posting is currently like this:
click on "New Classified" --->
fill in a form of all information and hit "View classified before publishing it" --->
the form submits to a "verify classifieds" page, where users verify their inputs --->
If everything is okay in the "verify" page, then the user hits OK and the classified is published.
The above procedure isn't exactly optimized. The first page (new_classified) where the form is, is pretty good, but the second page (verify) uses x number of hidden inputs in another form, used to contain the previous pages form inputs.
Now you know how it works on my site.
The issue today is that alot of companies want to publish their classifieds, and alot of classifieds at the same time. This means they have to fill out the form again and again currently.
I am thinking about creating a login, for companies only, so that their information is automatically inputted into the form, so all they would have to do is fill out the specific classified details like "headline" and "description" etc.
How should I do this in my case? Sessions?
This means I will have to create a new MySql table (I use MySql mainly) and store company-profiles there.
So do you think converting to sessions is alot of work? Worth it? More reliable?
I have never used sessions so I wouldn't know.
As a last note, you should know that I use a picture upload tool on the first page of "new_classified". When a user choses a file to upload, the page is automatically *refreshed*, and then the image is displayed on the same page under section "images uploaded". I hope the session wont interfere with this approach.
Thanks
I think it is worth your while to do logins, and even on a very basic level it will help you to identify who is using your site etc.
This is probably a big debate around developers, what is the best way to do a good login system, whether it's basic or not doesn't matter, I think the concepts still stay the same.
In your case I would suggest session cookies along with a login table consisting of user details. This would help you to verify the user on more than one occasion during his/her visit to the site.
A login is checked against a user entry in a table and then a session cookie is created. This session you can choose to never expire also.
You can then on every step check that the user is the user that is supposed to be logged in and get the companies details by checking the username. This would make for a better query in my opinion.
Sessions aren't a lot of work and it's relatively easy to learn.
http://www.php.net/manual/en/book.session.php
http://www.9lessons.info/2010/02/php-login-script-with-encryption.html is a good example of what you can do with this. Have a look around still. There are a bunch of these great tutorials on the web.

data between pages: $_SESSION vs. $_GET?

Ok, firstly this is not about forms this is about consistent layout as a user explores a site.
let me explain:
If we imagine a (non-ajax) digital camera online store, say someone was on the DSLR section and specified to view the cameras in Gallery mode and order by price. They then click onto the Compact camera's page. It would be in the users interests if the 'views' they selected we're carried over to this new page.
Now, i'd say use a session - am i wrong?
are there performance issues i should be aware of for a few small session vars ( ie view=1 , orderby=price) ?
Speaking of performances, there should not be much problems with either solutions.
Some things that have to be considered are :
With GET, if an URL gets copy-pasted (in a email or MSN), the other who will receive the URL will have the same GET parameters
is that a good thing, or not ?
On the other hand, session will not be shared, if an URL is copy-pasted
which means the first guy will say to the other "key, look at this", and the second guy will not see the same page ;; same thing with bookmarking, should I add.
GET is specific to each URL
While SESSION is shared accross all tabs of the user
Which means browsing with several tabs at the same time can cause troubles, when using Session, if you don't take care of that
I'd say use both. Store it in the session, but also put it in the get parameters for the page.
Why? This way the user is able to carry his options from page to page, but they are also in the URL so if he sends search results to his friend, his friend sees them the exact same way he did.
No, the session's performance will not degrade by putting those small variables in there. Unless you're storing monolithic arrays in your session, the vast majority of the time loading a session will be reading it from its storage medium (file, database, memcache, etc).
You should use GET in your case.
There is one simple rule in the web development: each page with different content must have it's own address. So, customer can save any page into favorites, send it to a frend. It's pain in the bottom then someone sends you a link to a particular page saying "Look!" but site uses frames and you land at the front page and dunno where to look.
You can save user's preferences into his profile/cookie (not session), but it should be reflected in the address bar as well.
Sessions being used for completely different purpose, shopping cart is an example.
It's a subjective question, it would work either way.
Personally I would go with sessions as it doesn't interfere with the URL so people can bookmark the url if they wanted.
However the argument for that would be if they bookmarked it they might see different things if it was done using $_SESSION.

Categories