PHP - Php Login Class And One More Question
Hello,
I'm doing something that looks like framework. It's my first serious "project". And now, I have a few questions: what basic functions are needed in MVC model class? Just tell me some functions, that could use, so I could try to code them. And the next question is... I'm going to create a login system for users. In my website there will be pages, that are visible for all visitors, and only for members. For example main website page should be visible for all visitors, but the page, where member can change his password, should be visible only for member. I know only one way to do this: allways and everywhere check if user is logged in. But isn't there smarter and simpler way? I hope you understood what I need. Sorry for bad english Similar TutorialsI have created this login class (In all honesty this is the most commented and well structured class I have ever written, I usualy just use random functions in a functions.php file, which works but this felt good when I finished it ) I just wanted some advice to how safe and whether the way I have done this is 'good practise', or if there is anything I should add to future proof it. This is the class: Code: [Select] <?php /* Author: Craig Dennis File: user_session.class.php Purpose: Flexible user login class that handles logging in, checking a user is logged in, and logging out. NOTE TO USE THIS CLASS YOU MUST ALREADY HAVE ALREADY CONNECTED TO THE DATABASE Include this file at the top of each page you wish to protect include("inc/user_session.class.php"); //(This could be put at the top of a global include file) Use the following code to check the user is logged in: $user_session = new user_session; //(This could be put at the top of a global include file) $user_session->validate_user(); //(This should only be left on the pages you wish to check for user validation) You will want to use the public redirect_if_logged_in() function instead of validate_user() on the login page like this: $user_session->redirect_if_logged_in(); //(This will redirect a user from the current page to the specified landing page) */ class user_session{ // Change these variables below if the table and fields in your database do not match public $t_name = "admins"; public $t_user = "username"; public $t_pass = "password"; public $t_lastlogin = "last_login"; //set $t_lastlogin = NULL if you do not have this field in your database //Change $login_page and $landing_page if your page names are different to this one public $login_page = "login.php"; public $landing_page = "logged_in.php"; //Change $log_in_error_msg if you wish to change the general error message when the user is unable to log in public $log_in_error_msg = "The username or password you have entered is incorrect or does not exist"; //Do not touch anything below unless you know what your doing /* * logged_in_user() * Returns value of the current logged in username */ public function logged_in_user(){ return $_SESSION['user_username']; } /* * log_in() * Takes 2 parameters ($username, $password) * Attempts to log in with the provided credentials, on success, the username and password are saved in the session for future testing */ public function log_in($username, $password){ $username = stripslashes(mysql_real_escape_string($username)); $password = stripslashes(mysql_real_escape_string($password)); $query_login = mysql_query("SELECT * FROM ".$this->t_name." WHERE ".$this->t_user."='$username' AND ".$this->t_pass."='$password'");; $login_accepted = mysql_num_rows($query_login); if($login_accepted == 1){ if($t_lastlogin != NULL){ $query_update_last_login = mysql_query("UPDATE ".$this->t_name." SET ".$this->t_lastlogin."='".time()."' WHERE ".$this->t_user."='$username'"); } $_SESSION['user_username'] = $username; $_SESSION['user_password'] = $password; return true; }else{ return false; } } /* * check_user() * Returns true if the current session credentials can be found in the database, otherwise returns false */ public function check_user(){ $query_login = mysql_query("SELECT * FROM ".$this->t_name." WHERE ".$this->t_user."='".$_SESSION['user_username']."' AND ".$this->t_pass."='".$_SESSION['user_password']."'"); $login_accepted = mysql_num_rows($query_login); if($login_accepted == 1){ return true; }else{ return false; } } /* * validate_user() * Returns true if the current session credentials can be found in the database, otherwise logs user out and returns false */ public function validate_user(){ $login_accepted = $this->check_user(); if($login_accepted == 1){ return true; }else{ $this->log_out(); return false; } } /* * redirect_if_logged_in() * Redirects the user to the specified landing page if the user is logged in */ public function redirect_if_logged_in(){ if($this->check_user()){ header("Location: ".$this->landing_page); } } /* * log_out() * Logs the user out by setting the session credentials to an empty string and redirecting them to the specified login page */ public function log_out(){ $_SESSION['user_username'] = ""; $_SESSION['user_password'] = ""; header("Location: ".$this->login_page); } } ?> Any comments or advice are appreciated. (Main Objective) I need this login class to encrypt the password before it sends it to the database for login verification. (Alternative Solution) Force a login with just the username and captcha no password.. This is the original working script.. <? session_start(); include "config.php"; global $c; include "data.php"; global $config; require('funciones.php'); if ($_POST['username']) { session_start(); if($_POST['code']!=$_SESSION['string']){ header("Location: login.php?error=1"); } //Comprobacion del envio del nombre de usuario y password $username=uc($_POST['username']); $password=uc($_POST['password']); if ($password==NULL) { header("Location: login.php?error=2"); }else{ $query = mysql_query("SELECT username,password FROM tb_users WHERE username = '$username'") or die(mysql_error()); if(mysql_num_rows($query) == 0) { header("Location: login.php?error=3"); } else { $data = mysql_fetch_array($query); if($data['password'] != $password) { header("Location: login.php?error=4"); }else{ $query = mysql_query("SELECT username,password FROM tb_users WHERE username = '$username'") or die(mysql_error()); $row = mysql_fetch_array($query); $nicke=$row['username']; $passe=$row['password']; //90 day cookie setcookie("usNick",$nicke,time()+7776000); setcookie("usPass",$passe,time()+7776000); $lastlogdate=time(); $lastip = getRealIP(); $querybt = "UPDATE tb_users SET lastlogdate='$lastlogdate', lastiplog='$lastip' WHERE username='$nicke'"; mysql_query($querybt) or die(mysql_error()); header("Location: members.php"); // echo "Has sido logueado correctamente ".$_SESSION['s_username']." y puedes acceder al index.php."; // echo "<script>location.href='index.php';</script>"; ?> <META HTTP-EQUIV="REFRESH" CONTENT="0;URL=members.php"> <? } } } } ?> <div class="heading">Login</div><br /> <? if($_GET['error'] == 1) { print "<b>Error</b> - Wrong Captcha Code<br /><br/>"; } if($_GET['error'] == 2) { print "<b>Error</b> - Please supply a password<br /><br/>"; } if($_GET['error'] == 3) { print "<b>Error</b> - Invalid Username<br><br>"; } if($_GET['error'] == 4) { print "<b>Error</b> - Invalid Password<br /><br />"; } ?> <form action="login.php" method="post"> <table> <tr> <td class="midtext">Username:</td> <td> <input type="text" name="username" size="25" class="form" autocomplete="off"></td> </tr> <tr> <td class="midtext">Password:</td> <td> <input type="password" name="password" size="25" class="form" autocomplete="off"></td> </tr> <tr> <td class="midtext" valign="top">Security Code:</td> <td class="midtext"> <img src="image.php" onclick="this.src='image.php?newtime=' + (new Date()).getTime();">(Click to reload)<br /> <input type="text" name="code" size="17" maxlength="17" autocomplete="off" class="form"></td> </tr> <tr> <td></td> <td align="right"> <input type="submit" value="Login" name="loginsubmit" class="form"></td> </tr> </table> </form> Let me know if you need any files... I'm starting to use a class to perform DB functions because I think it is more efficient. I found this class on the internet and understand pretty well what is going on. My problem is that I can't put the results on the screen when I use the class. (I can do it with out using the class but I'd like to learn to use it) function fetch($info) { return mysql_fetch_array($info); this is how I'm attempting to use it $db = new mysql; $db->connect(); while($row = $db->fetch($db->query("SELECT * FROM Attributes"))) { echo $row['Attribute']."<br>"; } This just echos the first row forever and I'm not sure how else to go about this. Any help would be appreciated. Hi! So I know that when redirecting to administrator pages after login is very often done like this: header(location:admin.php); But what if I didnt want to use header? I'm asking because I would just like to include the admin section within the part of the website I'm currently residing, if that makes any sense. Also, I think using headers is a bit cumbersome. I have just recently started learning PHP, so please excuse me if this is a dumb question One major problem I want to fix is that as of right now any user who knows the link to my admin panel can go to it directly. What I want to do is see if the the user is logged in (session exists). And if they are not logged in meaning no session exists then to kick them back to the login.php script. index.php(admin page only php coding) <?php session_start(); // Access the existing session // Include the variables page include ('inc/variables.php'); // If no session is present, redirect the user: if(!isset($SESSION['id'])) { header("Location: login.php"); exit(); } ?> However on my login page after I log in its as if with the top code goes right back to it for some reason? Any fixes? Hi. I'm new to this forum so it may be the wrong place i am posting. In school I'm working on a project where i have to make website with php and a database in MySQL. I have made one project. It was good (for one with my lack of skills), but now my teacher asks me to do it in another way. Problem is, I have no way how I can improve it. Right now i'm stuck on my login part. I figure that i have to post my code somewhere if I want some help, but how is the easiest way of doing that? Don't get me wrong. I'm not asking for anyone to make my project. All i need is a nod in the right direction Why is the proper way to call a class is to call a method at the same time? For example Code: [Select] $class = new SomeClass(); $class->some_method(); I understand why you would do this but lets say you just have a simple class that you pass some data. The class than processes the data in some way than returns it. It is my understanding if you were to make a class likes this. Code: [Select] class SomeClass{ function __construct($data){ //process data// return $data; } } That this code is considered an improper way of doing this because you should never return data from the __construct. So would this follow code be the proper way to handle this? Code: [Select] class SomeClass{ function __construct($data){ $this->some_method($data); } function some_method($data){ //process data// return $data; } } Any good explanation on the proper way to handle this would be greatly appreciated. When I am making simple classes to do a specific task it would seem more efficient not having to know about any particular method inside the class. Hi, I'm newbie to php opp. I just need to know if it is possible to instantiate a class like this? $import = new geoIpImportCSV(obtainDownloadFileName(), 'table1'); class geoIpImportCSV { private $input_zip_file; private $db_table; function __construct($input_zip_file, $db_table) { $this->input_zip_file = $input_zip_file; $this->db_table = $db_table; } /* "GeoLiteCity_" . $date . ".zip". */ function obtainDownloadFileName() { return "GeoLiteCity_20101201.zip"; } // ... } It is possible to call a method(obtainDownloadFileName()) like this to the constructor? Best Regards, OK so sorry if my understandings a bit off, but if a I want to introduce a class into my doc is the best way to fo this with the include() function? heres an example of the code i have Code: [Select] class someclass { public function run($parm) { system($parm); } public static function create($item1,$item2) { $this->run($item1 . $item2); } } then i have a file that attempts to use the create method: someclass::create($one,$two); when interpreting, i get this error: "Using $this when not in object context in" does anyone know how I can fix this? I think I understand why its wrong (the class hasn't really been set up) - I just dont know how to correct it. Is there a way I can access class functions without using $this ? additionally I tried making the run method static too, but that didnt seem to work. I have a quick Question guys about a code i am using! Basicly i have a from which call the login.php which should create a cookie and display Welcome $_cookie['username'] but it doesnt seem to work? If anyone here spots my error please call me on in. Code: [Select] <form name="login" method="post" action="scripts/login.php"> Username: <input type="text" name="username"> <br> Password: <input type="password" name="password"> <br> Remember Me: <input type="checkbox" name="rememberme" value="1"> <br> <input type="submit" name="submit" value="Login!"> </form> Login.php Code: [Select] <?php /* These are our valid username and passwords */ $user = 'guest'; $pass = 'guest'; if (isset($_POST['username']) && isset($_POST['password'])) { if (($_POST['username'] == $user) && ($_POST['password'] == $pass)) { if (isset($_POST['rememberme'])) { /* Set cookie to last 1 year */ setcookie('username', $_POST['username'], time()+60*60*24*365, '/account', 'c:/wamp/www/notemapper'); setcookie('password', md5($_POST['password']), time()+60*60*24*365, '/account', 'c:/wamp/www/notemapper'); } else { /* Cookie expires when browser closes */ setcookie('username', $_POST['username'], false, '/account', 'c:/wamp/www/notemapper'); setcookie('password', md5($_POST['password']), false, '/account', 'c:/wamp/www/notemapper'); } header('Location: ../index.php'); } else { echo 'Username/Password Invalid'; } } else { echo 'You must supply a username and password.'; } ?> here is how i am testing to see if my cookies are being set which they arnt! Code: [Select] <?php if (isset($_COOKIE['username'])) { echo $_COOKIE['username']; } else { include("widgets/login.html"); } //This is just to see if the cookie is set? echo $_COOKIE['username']; ?> I have been reading (here and on the internet) about login security, and I have now formulated a dumb question to ask. Not having a secure connection is there any way to NOT send plain text over the internet. In other words, when you have a login form plain text is entered. It is then passed to some type of encryption (hash, md5, sha1) BUT is the password always vulnerable between these two? And just for the record I am asking this because McAfee Secure is giving me a rash of (insert your favorite word here) about my login form which encrypts using sha1. Hey, So I have a couple of files, and I'm trying to create a login script. There is a MySQL query that accesses a database with a list of usernames and passwords. I have a feeling something is wrong with my SQL query, because it's not working correctly. Code: [Select] <?php $connect = mysql_connect("localhost", "root", "root"); if(!$connect){//If user can't connect to database die('Could not connect: ' . mysql_error()); //Throw an error } mysql_select_db("colin_db", $connect); //Get given username and password from username field and password field $givenUsername = $_POST["usernameField"]; $givenPassword = $_POST["passwordField"]; $myQuery = "SELECT * FROM ADMINS WHERE USERNAME = $givenUsername AND PASSWORD = $givenPassword"; $queryResult = mysql_query($myQuery); $numRows = mysql_num_rows($queryResult); if($numRows == 1){ //If the details are correct... //Reload the page and login echo "<script type = 'text/javascript'> window.location.reload() </script>"; echo "Details correct"; } elseif($numRows == 0){ //Else if the details are not found //Display error accordingly echo "Details not correct!"; //This is what happens every time } mysql_close($connect); ?> The database is configured correctly, but I'm not sure how to correctly create a SQL query to determine if the given username and password are correct. In case you'd like to see it, the segment from the index.php file is below. Code: [Select] <form action = "login.php" method = "POST"> Admin Login: <br> Username: <input type = "text" name = "usernameField"/><br> <!-- Password field--> Password: <input type = "password" name = "passwordField"/><br> <!-- Username field --> <input type = "submit" value = "Login" name = "submitButton"/> <!-- Login button --> </form> Any ideas? Thanks, Jake I created a database class to connect to a database. The code is below. I'm not sure how to call this connection in other classes. Do I use: $db->pdo = $conn->prepare($sql); or what? Note that the db object is instantiated at the end of the class file. Here is the class:
class DB { public $pdo = ''; //public $message = 'A message from db'; // Debug function __construct() { // Database info located elsewhere $servername = "localhost"; $username = "root"; $password = ""; $dbname = "dbname"; try { $this->pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // set the PDO error mode to exception $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } // End Try catch(PDOException $e) { echo "Error: " . $e->getMessage(); } //echo '<h3>Everything wnet OK.</h3>'; // Debug } // End __construct } // End class definition DB.php $db = new DB; Thanks,
--Kenoli I'm confused as to why assigning these variables in the class causes the page not to load... var $RootFolder = '/shyid/'; var $PagePath = str_replace($this->RootFolder, '', dirname($_SERVER['PHP_SELF'])); var $PageSections = explode('/', $this->PagePath); but when i set them on the page, everything works correctly? $head->RootFolder = '/shyid/'; $head->PagePath = str_replace($head->RootFolder, '', dirname($_SERVER['PHP_SELF'])); $head->PageSections = explode('/', $head->PagePath); Insight? Thanks. Hello, I am slightly nervous about posting this because I am almost completely new to php, I have a few introductory books on the subject which I am working through at the moment as well as some reference books but I am still getting through the basics of it all. I recently downloaded a login script, which allows a user to login and also allows the protection of some pages if users are not logged in. This script was a free one from easykiss123. it comes with other .php files and I have given them all a look over and I get the general idea of what's going on for the most part, and I THINK as I keep reading my books I will understand everything even more. However, what I really want to do right now is make it so a website would know which user is logged on, and then use this information elsewhere. For example if a particular user logged on and submitted something, I would like obviously the submission to be recorded but also the id of the user that submitted it, at the moment with this code, I do not think that is possible, however I could be wrong. I am looking for any pointers or a nudge in the right direction or link to a tutorial of how I would go about this, anything that may help. I think I would be storing the user ID in a global variable that can be used throughout the site, but again I am not sure. Thanks in advance for any help, I have included both the login script and the script used for protecting pages, as its already freely available online I see no issue with posting snippits of it here since the source has been referenced. Code: [Select] <?php # Script 16.8 - login.php // This is the login page for the site. require_once ('includes/config.inc.php'); $page_title = 'Login'; include ('includes/header.html'); if (isset($_POST['submitted'])) { require_once (MYSQL); // Validate the email address: if (!empty($_POST['email'])) { $e = mysqli_real_escape_string ($dbc, $_POST['email']); } else { $e = FALSE; echo '<p class="error">You forgot to enter your email address!</p>'; } // Validate the password: if (!empty($_POST['pass'])) { $p = mysqli_real_escape_string ($dbc, $_POST['pass']); } else { $p = FALSE; echo '<p class="error">You forgot to enter your password!</p>'; } if ($e && $p) { // If everything's OK. // Query the database: $q = "SELECT user_id, first_name, user_level FROM users WHERE (email='$e' AND pass=SHA1('$p')) AND active IS NULL"; $r = mysqli_query ($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc)); if (@mysqli_num_rows($r) == 1) { // A match was made. // Register the values & redirect: $_SESSION = mysqli_fetch_array ($r, MYSQLI_ASSOC); mysqli_free_result($r); mysqli_close($dbc); $url = BASE_URL . 'index.php'; // Define the URL: ob_end_clean(); // Delete the buffer. header("Location: $url"); exit(); // Quit the script. } else { // No match was made. echo '<p class="error">Either the email address and password entered do not match those on file or you have not yet activated your account.</p>'; } } else { // If everything wasn't OK. echo '<p class="error">Please try again.</p>'; } mysqli_close($dbc); } // End of SUBMIT conditional. ?> <h1>Login</h1> <p>Your browser must allow cookies in order to log in.</p> <form action="login.php" method="post"> <fieldset> <p><b>Email Address:</b> <input type="text" name="email" size="20" maxlength="40" /></p> <p><b>Password:</b> <input type="password" name="pass" size="20" maxlength="20" /></p> <div align="center"><input type="submit" name="submit" value="Login" /></div> <input type="hidden" name="submitted" value="TRUE" /> </fieldset> </form> <?php // Include the HTML footer. include ('includes/footer.html'); ?> Code: [Select] <?php require_once ('includes/config.inc.php'); $page_title = 'YOUR PAGE TITLE GOES HERE'; // Start output buffering: ob_start(); // Initialize a session: session_start(); // Check for a $page_title value: if (!isset($page_title)) { $page_title = 'User Registration'; } // If no first_name session variable exists, redirect the user: if (!isset($_SESSION['first_name'])) { $url = BASE_URL . 'index.php'; // Define the URL. ob_end_clean(); // Delete the buffer. header("Location: $url"); exit(); // Quit the script. } ?> Code: [Select] <?php // Flush the buffered output. ob_end_flush(); ?> Hi y'all. It's been forever and a day since I've dealt with cookies, and I can't get through the cobwebs in my brain about them. I know that cookies have to be set before any output goes to the browser, but if I'm not mistaken, it's the same with sessions and sessions work in this situation. Unfortunately, the client needs cookies for integration with an existing piece of software.
Basically, what's happening is this: You load a page, click the 'login' button, which uses JQuery to change the display on the login screen from 'none' to 'block'. Use the newly-visible login form to enter username and password, which are passed via ajax to my login function. If the login is successful, I set the cookie variable and redirect the user to the protected page. However, despite the ajax reporting a successful login and redirecting the browser as expected, the check on the protected page is kicking the user back to the beginning because the cookie was never actually set.
FunctionsClass.php:
/** * Logs in the requesting user with the agent and email values supplied via AJAX. * @return string JSON-encoded array */ public function agentLogin(){ $ret['success'] = $this->_site->login($_POST['username'],$_POST['password']); $ret['location'] = '/protected-page'; print(json_encode($ret)); die(); }Site.php (that's $_site in FunctionsClass): /** * Logs in the agent. * Checks to see if the user is already logged in, if not, attempts to do so. * @param string $un username * @param string $pw password * @return boolean */ public function logIn($un, $pw){ if($this->isLoggedIn()){ return true; } return $this->logAgentIn($un,$pw); } /** * Check to see if the cookie set so we know if the user has logged in. * @return boolean */ public function isLoggedIn(){ // return !empty($_SESSION['mycheckvariable']); return !empty($_COOKIE['mycheckvariable']); } /** * Log the user in. * @param string $un username * @param string $pw password * @return boolean */ private function logAgentIn($un,$pw){ // $_SESSION['mycheckvariable']['email'] = 'me@notmyemail.com'; setcookie('mycheckvariable','me@notmyrealemail.com',time()+60*60*8,'/'); return true; }It's not as though I'm even actually checking a database - just trying to stub this out for client presentation. And, if I uncomment the two lines using sessions and comment out the cookies, it all works perfectly. I'm not at all sure what I'm missing and would very much appreciate some other eyes on this - any takers? I'm using WordPress, if that matters at all... Thanks in advance! I have a login system that uses a flat file database. The flat file is in a directory outside the public_html. My questions; 1- Is is still possible to hack into that file? Currently I do not encrypt the passwords as I have been told that having the file outside the public_html makes the file unavailable to the public. This allows me the advantage of sending the Username and Password to the user in an email if they forget there password or username. Otherwise- I would have to set up a more complicated method to allow them to change their password to re-gain access to the site. I have an SSL on the site also so I am not worried about packet sniffing. Thanks Someone parses the html login form and gets the csrf token from hidden field. Now can he request with that csrf token to login through jquery ajax? Imagine 6 PHP classes (one each for a product line), that have very similar coding structures, that go like this:
//function that computes stuff inside each of 6 files: //they vary slightly from file to file but essentially it is this: function computeFunction { $this->x = new X(); $this->x->calcD(); if ($this->x->dOk) { $this->x->calcE(); $this->x->calcN(); } //more complicated logic that is essentially like above //and by the way! print $this->x->someVarThatIsUsedLater; }Then there is a single class like so : class X { function calcD() { //compute some condition if (<computed condition is met>) $this->dOk = true; else $this->dOk = false; //and by the way $this->someVarThatIsUsedLater = 4; } }Just to bring your attention to it, none of these functions return any result or value, but they nevertheless operate on variables of key interest via side-effects. That is, they modify variables that essentially act like globals, and then use those variables later ($this->dOk and $this->someVarThatIsUsedLater are one more prominent examples). I need to untangle this mess. And make it clean and clear again, and make sense. How do I best proceed? I have been wrestling with some ideas... like $this->dOk, can within reason be turned into a return variable of calcD() function, and then be tested against like if ($this->x->calcD()) and I think it will be reasonable enough. But then there are other functions that don't return anything and just act on variables via side-effects anyway so $this->dOk is one of the lesser troubles... Other than that, what I am thinking of doing is getting rid of these mini-functions (calcE(), calcN(), etc.), removing them as a funciton, and putting their body directly into the code, as a first step to refactor. Many of the computations done inside are just a few lines of code anyway, and the functions kind of hide a lot of side-effects that happen, instead of actually encapsulating the behavior. So while it may be counter-intuitive to dismantle the functions that appear to be doing something that normally can be encapsulated (computing key variables E, N, etc), I think dismantling them will actually clean things up as far as collecting all the side-effects inside a single parent function thereby making them more visible. Caveat: while doing so I will end up with 6 copies of untangled dismantled functions, because dismantling class X and putting its content into each of the 6 product line classes will have that effect. But my hope is that from that point I will see more clearly to start identifying places where I can start to truly encapsulating the behavior via various structures, instead of masking it. Problems / Questions: I would like to but I am not entirely sure that I can skip that step of dismantling functions & the 6x multiplying effect. It's probably the same like skipping steps in solving polynomial equations. Some can do it and some need to list each step of their work. And I am not entirely sure what structures I can replace it with in the end after I dismantle the functions. It also looks like a lot of work. Is there a better way? P.S. I already put tests on computeFunction() for each product line so I can be less paranoid about hacking stuff up. Edited by dennis-fedco, 19 January 2015 - 03:06 PM. |