I have found what looks like a good, secure PHP login script, however i am having trouble figuring out how to implement it. (It is located here http://www.adesdesign.net/php/tutorials/php/php_login1.php)
I am new to PHP so don't know much yet. I can't figure out how you actually authenticate a user and return a message to them if it fails and where to stick all the functions and classes mentioned throughout.
I know it may be very obvious to some but i just don't get it!
Thanks.
Not the easiest script/way to do it, but quite complete. You say you're new to php, what about OOP ?
IMO, this one seems easier : tutoriel.
Principle always stays the same : you have in your database a table with your user.
The visitor come and try to log.
If his login/password are good, you redirect him to his profil/any page you want and you store in $_SESSION['verifiedUser'] = true ,
if his login/pass are wrong, he's redirected to the login page, with an error message.
And in every page restricted to logged user, you add
if (!isset[$_SESSION['verifiedUser']) )
header('Location:loggingForm.php');
Clement answer is perfect.
May be the pear Auth class can be usefull
Just a note because you siad your are new to php: the authetication process is not the only important thing. You should also think about the ACL (access control list), a mechanism which allows an authenticated user to do some things but not others on one or more pages
--
Dam
Related
I'm currently making two different, but pretty similar web-based applications. So I'm using PHP, and standard MySQL (MariaDB in my case because I use XAMPP but I guess two of them are similar to one another). FYAI, I'm building my apps on a local server which located just right in my PC.
So let's say my first project is Project1, and it is stored in localhost/project1. Meanwhile, the Project2 is in localhost/project2. Both of them have a login feature for different account/user.
So when they try to log in I do this. By the way, it's MVC.
class Auth extends Controller {
public function index()
{
// verification such as prevent raw attempt with no post data, etc.
// verify the username and password, header back if fail, blablabla, u know...
// and then the following is if succeeded
$_SESSION['login'] = true;
$_SESSION['id'] = // user id;
}
}
I used that similar system in both of my projects.
The Problem
So I was trying to figure out how session work, and I log myself into the localhost/project1. And then I open localhost/project2. Surprisingly for me, I didn't need to type in my username and password in localhost/project2. I logged in already. These things gave me some concern. So these are my questions:
Did that happened because I develop my site on a local server in my very own computer?
Don't you guys think that anybody can break in to my site just by creating some simple procedural php code in their server like this:
$_SESSION['login'] =true;
// and other sessions
and then just access that file, which make their session login value is
true, and other validation session index that i used, and then just
access my web site and logged in, like some man with big AK-47 in his
hand walks in right from the very front door of the white house with no
secret service notice and hold him down in custody?
Why is this really happening and how do you think I should fix it? I also have some timeout feature so I'm afraid any big changes would bother most of my construction but any suggestion is really welcome.
Sorry if my English is bad, or my php knowledge is pathetic. I'm new.
Sessions are normally driven by a cookie that contains your session ID. Since cookies are shared within the same domain by default, if you have two projects both located on the same host/domain (e.g. localhost), and both use sessions, then they will both share the same cookie and thus the same session data.
This means someone could NOT hack into your site by setting up a random session in their own site. Their session data would only be applicable to their own site.
On a side note, it's not usually a good idea to suggest analogies that involve storming the white house with a gun. Just a friendly piece of advice.
I have a PHP application custom_appli in /var/www/httpdocs.
Wordpress is installed on the same server in /var/www/httpdocs/new_cms/wordpress.
I need to retrieve user->ID using SESSION of custom_appli.
I have tried to insert :
require( './new_cms/wp-snapshots/wp-blog-header.php' );
global $user;
$user = wp_get_current_user();
echo "ID :".$user->ID;
writing wp-load instead of wp-blog-header doesn't change anything no matter whether I use include or require_once.
Could you please give me a link or advice on how to obtain user from SESSION?
Thanks in advance
Details and info are sparse, but here's how I would do it (I know about 5 methods, these are the least painful):
As mentioned, wp_get_current_user() gets you close, but that is generally only usable on the page for the user as in "on load" only. So from the WP served page you can get user ID (and all other info) and the session and have something that is usable. There are many ways to use that data to solve your problem, not really smooth all the time. Session data is etherial, beware.
Another way to go about it is to use wp-load.php and wrap it in middleware. this script bootstraps WP and allows queries and similar in the "bootstrapped" wordpress environment providing the applications internal API. I would consider adding wp-load to custom_appli "in the right way" and use that as middleware between the 2 applications. You will still need to identify the user as in many cases.
Without more information it is hard to guide you, but I can tell by your needs and the code already in the post that you are setting up for possible problems with dependencies, possible name-spacing collisions($user is something that could bite you as a global), and a myriad of other ways to loose time. If custom_appli needs a user ID, send it the user from WP on page load or similar.
When/why do you need that info? What is the flow?
You can also traverse a lot via session ID info too (depending on configuration).
FWIW I have passed user information successfully from 2 freestanding applications on different servers, it was very hard to do correctly, but it is possible.
Update after clarification
As mentioned "wordpress-user and cusstom-appli have same users" is possibly a replication of functionality, specifically running 2 tables(?) or logic. Just some feedback.
Basically you are wanting to hook the "logged in" status of a WP user. I see no mention of:
FK/relationships built on user (easy but a little more work)
ACL/permission based access on custom appl
No serializing of data or similar to the WP user (user in general)
Any of the above might have me change the solution. Here is a pretty clean prototype I wrote for you that is about 15 lines of code.
It follows some code from wp and essentially:
Makes sure PHP session is initialized via the theme functions.php
Uses the WP login (authentication) success to add a var to the session
On logout unsets the var (!IMPORTANT!)
Also makes sure the session is set when not logged in or the key is not present
Is easy to pick up outside of WP via session (custom_appl.php)
I tested this and it worked fine locally on one of my installs, I don't see any reason why it would give you problems. I would harden this a little more, but this is only a prototype showing how to use the key tools in PHP and WP.
wp_get_current_user() is a function in wp-includes/pluggable.php, which is loaded by wp-settings.php. I'm not sure how exactly WordPress bootstraps itself but I'd try to include wp-settings.php if anything.
Note: Now that I know where the issue comes from, I modified the question. It now contains only the information needed.
I'm new to the Laravel PHP framework.
I have a very small app working on my computer. It is connected to a MySQL database and has a User model. I use the Auth class to log in and out.
Everything works fine, but when I am logged in, loading a page takes about a second which is very slow. When I'm not logged in, it's a matter of milliseconds.
By using the built-in profiler, I realized two problems. First, like I said, loading a page takes a bit more than 1000 milliseconds. Second, the framework makes one SQL every time I load a page when I'm logged in. The query searches a user with a certain id (my id). I guess it is there to get information about the logged in user. But isn't there supposed to be some sort of cache. Will this be a problem if my website will have to manage many requests per seconds.
I realized that using Auth::check() in the view is what is causing the issue. I have around 4 Auth::check() is my Blade view. When I have none, it goes fast. If I have one, it is slow. Then, no matter how many I have, it doesn't get much slower. It's like if the Auth class' initialization takes too much time or something like that. I guess it explains why it only happens when I'm logged in.
I dived into Laravel's code and I found out that when Auth::check() is called for the first time, the Auth class needs to "activate" my Session by retrieving the user's info from the database. That explains the query being executed every page request. But since the profiler says that the query doesn't even take a millisecond to execute, I still don't know why it slows down the app.
New information: Even when I'm not sending a query to the database, the simple act of connecting to it takes almost a second. This is the reason it is slow. I think I'm getting really close to solve the issue.
Any idea so far?
Thanks in advance.
Notes
The fact that Auth::check() is in the view doesn't change anything.
Using another method like Auth::guest() doesn't solve the issue.
New: Connecting to the database is what is slow.
I finally found a way to fix this.
When reading some posts on many forums about XAMPP, MySQL, and PHP, and I read somewhere that it is preferable to use 127.0.0.1 because locahost needs an extra DNS lookup.
In the database configuration file, I simply changed locahost for 127.0.0.1.
Now everything is fast.
I find this really strange. Using locahost in the configuration file used to make the database connection take more than a second!
I do not agree with Hammo's example. Having any user information other than their ID within the session is a security risk, which is why most frameworks take this route. Is there anything else being run when the user is logged in, apart from the query for their record? It's definitely not that that's slowing your application down.
I have read an answer to another question here on Stack Overflow. Let me first quote the incriminated part:
If your goal is to make people pay for it, you better register a key on your server side for each client. Then, when they connect to update, they will send the key and if she's in your database and valid, you output your zip file. If not, you don't.
I am asking that, technically, how would one secure his/her PHP-based project with the register a key method? Let's say we have this:
$key = file_get_contents('http://auth.project.example.com/auth.php?auth_key=asd123');
if ( $key === "auth_valid" )
define('AUTH', TRUE);
And after that, we check AUTH to see whether we (from the client's perspective) bought the system or not. Obviously, if we did not, AUTH will be FALSE or would not be defined at all. The problem is, that a client with only little-to-no knowledge to PHP would easily comment out these lines, hotwire AUTH to be TRUE and there he/she is, using the system with it thinking it had been bought, while, in reality, it hadn't.
You would use encryption and eval. Though, thinking about it, once it's evalled, then you have lost, as they could just change eval for echo. So, in that case you'll need to include the business parts on your server via an API.
I would suggest a look at ZendGuard or ionCube.
I'm currently writing a couple of MVC sites using Kohana as my framework. Each has a simple admin area where the admin can upload and edit content. I'm currently storing the admin's user model in a session and checking whether or not they're an administrator with the following method:
private function checkAdmin()
{
if (!isset($_SESSION['admin']) || $_SESSION['admin']->Level !== 'admin')
{
header('Location: /admin');
exit;
}
}
I call this method in all of the other Admin controller methods, like so:
public function writeReview()
{
$this->checkAdmin();
// rest of the method
}
I'm just wondering if there's anything I can do to improve this. It just seems like a single point of failure that's giving me a bad smell, so I'm a bit weary to move on before getting this nailed down.
If this is Kohana version 2.x, I would move the $this->checkAdmin(); into the constructor of your controller. If this is version 3.x, I would put it in the before() method. This will ensure that every route will be protected.
Your function appears to be redirecting to /admin only if the user is not an administrator. If that's the intended result, then fine.
-- Forget this, my mistake.
The checkAdmin() function, as it relies on a redirect, is only useful in situations where you want to redirect. If, for example, you are using this in the processing script (and you should be checking if it's an administrator in the processing script), you just want a return true or return false. I suggest that be the base function, and a redirect function call that, or alternative, accept and optional parameter to redirect.
If you want to let users share their logins fine, but otherwise generating a per session/login key and storing it in the DB will lock things down even further. This way, if someone logs in with your password, you'll get kicked out and instantly know that it's been compromised.
Other basic things to do - store dates of last login, IPs.. this kind of stuff. It's not just one single thing, but lots! :)