Hi I m new to PHP and I m creating my own CMS for practice, and have two problems that I m not able to get the solution for. But let me show you my code before I ask my question. The login Page(index.php) <?php require('includes/connection.php'); if(isset($_POST['submit'])){ $username=$_POST['username']; $password= $_POST['password']; $query= mysql_query("SELECT * FROM users WHERE username='$username' "); $results= mysql_fetch_array($query); if($username==$results['username'] && $password==$results['password'] ){ echo "Logged In Succesfully! Welcome" ; session_start(); $_SESSION['user']="user"; header("Location: admin.php"); }elseif($username!==$results['username'] && $password!==$results['password']){ echo "<h5 class=\"shifterror\">Username or the password is incorrect</h5>"; }elseif($username==$results['username'] && $password!==$results['password']){ echo "<h5 class=\"shifterror\">Password is incorrect</h5>"; } } if(isset($_GET['m']) ){ $id=$_GET['m']; if($id==1){ echo "<h5 class=\"shifterror\">You have sucessfully logged out</h5>"; } } ?> <body> <div id="admin"> <img src="images/logo.png" /> <div id="loginarea"> <form action="index.php" method="post"> <p><label for="userlogin">Username</label></p><input type="text" name="username" id="userlogin" /> <p><label for="userpassword">Password</label></p><input type="password" name="password" id="userpassword"/> <label for="rememberme">Remember Me</label><input type="radio" value="1" name="remember" /> <input type="submit" name="submit" value="Login" class="button movebutton" /> </form> </div> </div> </body> </html> Code (markup): Landing page from login (admin.php) <?php if(isset($_POST['remember'])){ setcookie("user", 100 , time()+(60*60*24)); }else{ setcookie("user", 100 , time()-(60*60*24)); } ?> <!--Header --> <?php include('templates/header.php'); ?> <!--Sidebar --> <?php include('templates/sidebar.php'); ?> <div id="content_wrapper"> <div id="content"> <h1>Welcome to your Dashboard</h1> </div> </div> </body> </html> Code (markup): page for creating new pages(createpages.php) <?php require_once('../includes/functions.php'); ?> <link rel="stylesheet" type="text/css" href="../css/style.css"> <?php if(isset($_POST['submit'])){ $title= $_POST['title']; $content= $_POST['content']; $query= mysql_query("INSERT INTO pages(pagename,content) VALUES('$title', '$content')"); if(!$query){ die("Could not add a new page".mysql_error() ); }else { echo "<h5 class=\"littlemore\">Added sucessfully</h5>"; } } ?> <div id="content_wrapper"> <div id="content"> <h1>Add New Pages</h1> <form action="createpages.php" method="post"> <input type="text" placeholder="Enter Your Title Here" name="title" > <textarea cols="80" id="editor1" name="content" rows="10"></textarea> <p> <input type="submit" value="Add New" name="submit" class="button" > </p> </form> </div> </div> <!--sidebar2 --> <?php include('../templates/sidebar2.php') ?> </body> </html> Code (markup): so Problem1: As you can see, I have added one radio button "remember me" and the name is "remember" . I want to set the cookies only when the user checks that radio button or else unset the cookies. But its not happening when I write conditions (like if(isset($_POST['remember']))). But the cookies get set, when I dont write condition. Can you tell what mistake m I making or what I should do? Problem 2: I have created another form for creating new pages and I m inserting title and content into the database, which gets inserts with no problem however if the user uses a inverted commma or ' or any other special character in the input it shows an error "Could not add a new pageYou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's', ' ')' at line 1" Code (markup): for content I have chosen "text" and for title I have chosen VARCHAR type in the table. M i doing something wrong. Thanks
Problem 1: I tested that part of your code and it actually works fine for me. I would suggest to change the radio button into a checkbox. Because a radio button cannot be unchecked in case that the user clicks it by mistake and wants to undo it. All you have to do is change type="radio" into type="checkbox". This is what I did to test the code. Form <form action="test2.php" method="post"> <p><label for="userlogin">Username</label></p><input type="text" name="username" id="userlogin" /> <p><label for="userpassword">Password</label></p><input type="password" name="password" id="userpassword"/> <label for="rememberme">Remember Me</label><input type="checkbox" value="1" name="remember" /> <input type="submit" name="submit" value="Login" class="button movebutton" /> </form> HTML: PHP landing if(isset($_POST['remember'])){ echo "remember"; } else { echo "do not remember"; } PHP: Although I didn't change anything here from your code except "Checkbox". So it will likely not solve your problem. A small note: isset() only checks whether the variable exists. It does not care what the variable contains. So perhaps you should validate that the user really clicked the button by adding another if statement. Example if(isset($_POST['remember'])){ if ($_POST['remember'] == 1) { echo "remember"; } else { echo "do not remember"; } } else { echo "do not remember"; } PHP: The radio button has the value=1. As you wrote so in the form. So we check whether the posted variable contains 1 or if it's something else. This is just an extra verification. Problem 2: The reason you get an error from characters such as '. Is because it is actually an SQL injection. Visitors could modify your query by adding ' and additional content after. To fix this you'll need to escape EVERY variable that is being inserted into a mysql query by using mysql_real_escape_string(). Change from this: <?php if(isset($_POST['submit'])){ $title= $_POST['title']; $content= $_POST['content']; $query= mysql_query("INSERT INTO pages(pagename,content) VALUES('$title', '$content')"); if(!$query){ die("Could not add a new page".mysql_error() ); }else { echo "<h5 class=\"littlemore\">Added sucessfully</h5>"; } } ?> PHP: Into this: (Note the 2 variables $title and $content) <?php if(isset($_POST['submit'])){ $title = mysql_real_escape_string($_POST['title']); $content = mysql_real_escape_string($_POST['content']); $query= mysql_query("INSERT INTO pages(pagename,content) VALUES('$title', '$content')"); if(!$query){ die("Could not add a new page".mysql_error() ); }else { echo "<h5 class=\"littlemore\">Added sucessfully</h5>"; } } ?> PHP: This method will be deprecated in PHP 5.5.0 so it is recommended to learn MySQLi (MySQL Improved) instead. More info about it: http://www.php.net/manual/en/function.mysql-real-escape-string.php
Thanks a lot. Problem 2 has been solved with your help , but the first problem still persist. I tried to check if the $_POST['remember'] has been set or not same way you asked me to and also changes the radio button admin.php page <?php if(isset($_POST['remember'])){ if ($_POST['remember'] == 1) { echo "remember"; } else { echo "do not remember"; } } else { echo "do not remember"; } ?> <!--Header --> <?php include('templates/header.php'); ?> <!--Sidebar --> <?php include('templates/sidebar.php'); ?> <div id="content_wrapper"> <div id="content"> <h1>Welcome to your Dashboard</h1> </div> </div> </body> </html> Code (markup): but wheather I check 'remember me' checkbox or not , its always showing "do not remember." ): Just wanted to bring your attention to the fact that I m only redirecting to the admin page when the username and the password is correct or else the page is coming back to the same page which index.php <link rel="stylesheet" type="text/css" href="css/style.css" /> <title>Admin Login</title> </head> <?php require('includes/connection.php'); if(isset($_POST['submit'])){ $username=$_POST['username']; $password= $_POST['password']; $query= mysql_query("SELECT * FROM users WHERE username='$username' "); $results= mysql_fetch_array($query); if($username==$results['username'] && $password==$results['password'] ){ echo "Logged In Succesfully! Welcome" ; session_start(); $_SESSION['user']="user"; if(isset($_POST['remember'])){ $_SESSION['remember']='remember'; } header("Location: admin.php"); }elseif($username!==$results['username'] && $password!==$results['password']){ echo "<h5 class=\"shifterror\">Username or the password is incorrect</h5>"; }elseif($username==$results['username'] && $password!==$results['password']){ echo "<h5 class=\"shifterror\">Password is incorrect</h5>"; } } if(isset($_GET['m']) ){ $id=$_GET['m']; if($id==1){ echo "<h5 class=\"shifterror\">You have sucessfully logged out</h5>"; } } ?> <body> <div id="admin"> <img src="images/logo.png" /> <div id="loginarea"> <form action="index.php" method="post"> <p><label for="userlogin">Username</label></p><input type="text" name="username" id="userlogin" /> <p><label for="userpassword">Password</label></p><input type="password" name="password" id="userpassword"/> <label for="rememberme">Remember Me</label><input type="checkbox" value="1" name="remember" /> <input type="submit" name="submit" value="Login" class="button movebutton" /> </form> </div> </div> </body> </html> Code (markup):
Just some further advise. Your database queries are incredibly insecure. http://php.net/manual/en/function.mysql-query.php Also, no need to recreate variables that are already there. <?php if(isset($_POST['submit'])){ $title= $_POST['title']; $content= $_POST['content']; $query= mysql_query("INSERT INTO pages(pagename,content) VALUES('$title', '$content')"); if(!$query){ die("Could not add a new page".mysql_error() ); }else { echo "<h5 class=\"littlemore\">Added sucessfully</h5>"; } } PHP: Should be something like: // connect to db using [B]PDO[/B] $db_myHost = "localhost"; $db_myUser= "username"; $db_myPassword = "password"; $db_myDatabase = "database"; $dbconn = new PDO('mysql:host=$db_myHost;dbname=$db_myDatabase ','$db_myUser','$db_myPassword'); try { $dbPDO = new PDO('mysql:host='.$db_myHost.';dbname='.$db_myDatabase, $db_myUser, $db_myPassword); $dbPDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo "Error!: " . $e->getMessage() . " "; die(); } // insert info to the db $sth = $dbconn->prepare(" INSERT INTO pages (pagename, content) VALUES (:pagename,:content) "); $params = array( pagename=> $_POST[pagename], content=> $_POST[content] ); $sth->execute($params); PHP: The above method is incredibly more secure as PDO prevents SQL injections meaning no need to escape strings. Its also pretty much standard now alongside SQLi
I figured the solution. The problem was that since I had set in the action the page should go to the the same page first and then if the login was sucessfull it would be redirected to the admin page , it was not carrying the $_POST('remember') third time(which is logically correct). So I grabbed hold of that $_POST('remember') on the first page itself and then I passed that value in form of an id and grabbed that in the admin page to check the condition so here is what I did. <title>Admin Login</title> </head> <?php require('includes/connection.php'); if(isset($_POST['submit'])){ $username=$_POST['username']; $password= $_POST['password']; $query= mysql_query("SELECT * FROM users WHERE username='$username' "); $results= mysql_fetch_array($query); if($username==$results['username'] && $password==$results['password'] ){ echo "Logged In Succesfully! Welcome" ; session_start(); $_SESSION['user']="user"; if(isset($_POST['remember'])){ echo $s=2; } header("Location: admin.php?s=$s"); } elseif($username!==$results['username'] && $password!==$results['password']){ echo "<h5 class=\"shifterror\">Username or the password is incorrect</h5>"; }elseif($username==$results['username'] && $password!==$results['password']){ echo "<h5 class=\"shifterror\">Password is incorrect</h5>"; } } if(isset($_GET['m']) ){ $id=$_GET['m']; if($id==1){ echo "<h5 class=\"shifterror\">You have sucessfully logged out</h5>"; } } ?> <body> <div id="admin"> <img src="images/logo.png" /> <div id="loginarea"> <form action="index.php" method="post"> <p><label for="userlogin">Username</label></p><input type="text" name="username" id="userlogin" /> <p><label for="userpassword">Password</label></p><input type="password" name="password" id="userpassword"/> <label for="rememberme">Remember Me</label><input type="checkbox" value="1" name="remember" /> <input type="submit" name="submit" value="Login" class="button movebutton" /> </form> </div> </div> </body> </html> PHP: and on the admin page I did this <?php if($_GET['s']==2){ echo "remember me"; }else{ echo "do not remember me"; } ?> <!--Header --> <?php include('templates/header.php'); ?> <!--Sidebar --> <?php include('templates/sidebar.php'); ?> <div id="content_wrapper"> <div id="content"> <h1>Welcome to your Dashboard</h1> </div> </div> </body> </html> PHP: but that's seems a long way of doing it, can you think of any shortcut for this?
Instead of changing the cookie life on the admin page do it at the same time when you're creating the session. Also don't forget to escape $username and $password in the actual login part too. Otherwise you'll be extremely vulnerable. Also as for the session I noticed that it holds the 'username' to verify if you're logged in. That is also very insecure as an attacker could easily edit their session and rename them self to an admin. And would then be granted access. One easy way to prevent it would be to generate a random string (that no one could guess) and put that in the session instead of username. Then match the token with user in database somehow. And on logout the token should be destroyed and generate a new one on next login. You could also add a time limit for how long the token would be valid. And for extra security you could match it against a certain IP address. To prevent that someone would steal it.
Thanks for telling me the security loopholes i'll use the for sure. And one more thing if you could just guide me throught. I want the admin to have the option of creating new pages(though I know how to give the option of creating new content and title). I have created a 29 pages website which I m setting this cms for. I have included the header , footer sidebar , banner in a template folder, and I have given the option to edit and delete those pages and admin can also create title and content. but I m thinking how would I generate new pages(files) which would have the header , footer and sidebar already included. I hope that makes sense.(if it doesn't just refrence it from wordpress.)
I'd pass the ID through the URL and have most pages all coming from 1 page. So page.php?id=1 (you can rewrite the URL and have a field in the db called 'page-slug' or something so say ID 1 = about you can rewrite the url to be yoursite.com/about/ but back-end it would read yoursite.com/page.php?id=1 pointing your script to the ID in the db and thus bringing out the correct content for said page. <?php require_once ('includes/db.php'); include "includes/header.php"; include "includes/sidebar.php"; //check username password $sth = $dbconn->prepare("SELECT title,content FROM page WHERE id = :id"); $params = array("id" => $_GET[id]); $sth->execute($params); if ($row = $sth->fetch()) { echo ' <h1>', $row[title] ,'</h1> <p>', $row[content] ,'</p> '; } include "includes/footer.php";?> PHP:
can you tell me what this process(creating pages like this) is called, so that I can google it and read more about this
I'm not entirely sure what its called to be honest. Its a mixture of things... You'd use a .htaccess file (if you're on Apache) to rewrite page.php?id=1 to /page/1/ or /page/my-page-title-from-database/ this would look similar to: .htaccess RewriteEngine On RewriteRule ^\$title/([^/]*)/$ /page.php?id=$1 [L] Code (markup): I usually use a generator to do this such as this one here: http://www.generateit.net/mod-rewrite/ you simply put in your URL e.g. page.php?id=1 and you can fiddle with the variables to get the output you want. The above changes domain.com/page.php?id=1 to domain.com/title-from-db/ Then in your navigation you link to exactly that domain.com/title-from-db/ and use the code I sent over earlier to extract the information from the db.