After a user signs in and his password is verified, I need to store his username in a cookie. I tried to simply add setcookie() when the password is successfully verified in the section that looks like if ( $password_match == $user_login_password ) {... but for some reason it doesn't seem to be working. I can't set cookies when a user successfully logins with correct password/username. Is there some reason you can't setcookies from inside a function?
public function write($p) {
if ( $_POST['user_login_username'] )
$user_login_username = mysql_real_escape_string($_POST['user_login_username']);
if ( $_POST['user_login_password'] )
$password = mysql_real_escape_string($_POST['user_login_password']);
$password .= 'some_Salt';
$user_login_password = hash('sha256', $password);
} elseif ( $user_login_username && $user_login_password ) {
$q = "SELECT * FROM users WHERE username = '$user_login_username'";
$r = mysql_query($q);
if ( $r !== false && mysql_num_rows($r) > 0 ) {
while ( $a = mysql_fetch_assoc($r) ) {
$password_match = stripslashes($a['password']);
}
if ( $password_match == $user_login_password ) {
echo $this ->display_login('Correct!');
setcookie('user','some_username');
} else {
echo $this ->display_login('Wrong Password!');
}
} else {
echo $this ->display_login('That username does not exist.');
}
return;
} else {
return false;
}
}
I'd do this that way:
function mysetcookie($name, $value, $timestamp=null, $directory='/') {
return setcookie($name, $value, time()+$timestamp, $directory);
}
And I'd be using mysetcookie() instead of setcookie() :) And I'd consider reading this:
http://php.net/manual/en/function.setcookie.php
Ahh I got it. Protocol restriction with setcookie, I was trying to set it after the tags. Thanks to everyone who looked, I should have read the documentation better. Sorry!
Related
I'm working on a loader that will load a file once the user authenticated correctly, but before I want to start my file stream I want to check their HWID to check so it matches the HWID on the database and I have managed to do it and I do it like this:
function validate_Hwid(){
global $db, $encryptionEngine;
if (isset($_GET['username']) && isset($_GET['hwid'])) {
$username = $encryptionEngine->init($_GET['username'],"decrypt");
$hwid = $encryptionEngine->init($_GET['hwid'],"decrypt");
$query = $db->simple_select("users", "*", "LOWER(username)='".$db->escape_string(my_strtolower($username))."'", array('limit' => 1));
$user = $db->fetch_array($query);
if ($hwid == $user['hwid']) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
but I have a problem, if the user never logged in before the HWID on the DB will be null, how can I change so if HWID on the user is null, than insert the string I provide?
if ($user['hwid'] == null)
{
// insert and call func again
} elseif ($hwid == $user['hwid']) {
return 1;
} else {
return 0;
}
I have a problem with wordpress userprofile editing.
The problem is that the validate function is executing after the update function so what i get on my wordpress is the error but the fields updated.
function bw_admin_validate_fields($errors, $update, $user){
if(isset($_POST["credits"]) && !ctype_digit($_POST['credits'])){
$errors->add("credits_error","The field credits must be a number");
}
if(isset($_POST['ipaddress']) && !filter_var($ip, FILTER_VALIDATE_IP)){
$ip = gethostbyname($_POST['ipaddress']);
if($ip == $_POST['ipaddress'])
$errors->add("ip_error","You must enter a valid ip address or a hostname");
}
}
.
function bw_admin_save_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) || !ImAdmin() )
return false;
if(isset($_POST['generate']) && isset($_POST["ipaddress"])){
$ip = $_POST['ipaddress'];
if(!filter_var($ip,FILTER_VALIDATE_IP)) $ip = gethostbyname($_POST['ipaddress']);
$key = API::I()->createApi($ip);
update_user_meta($user_id,"api_key",$key);
}
else{
$apikey = trim(get_user_meta($user_id,'api_key',true));
$banned = isset($_POST['banned']) && $_POST['banned'] ? true : false;
if($banned) API::I()->Ban($apikey);
else API::I()->UnBan($apikey);
if(isset($_POST['credits']) && ctype_digit($_POST['credits']))
{
if(((int)$_POST['credits']) < 0) $_POST['credits'] = 0;
API::I()->setCredits($_POST['credits'],$apikey);
}
}
}
And when i hit the edit button wordpress says me that i have to enter a valid ip or valid hostname but the Api is already created.
I have form with client-side verification by jQuery, which works good. But now for security reasons I want to add also server-side verification (php) for users without JavaScript. I created few functions and array "errors", where errors are logged. After submit I want run the verification. If no errors are logged, continue, if there are errors exit the script. But that part doesn't work, it always continue. My script:
if (isset($_POST['submit'])) {
require_once 'verify_form.php';
$errors = array(
'username' => null,
'password1' => null,
'password2' => null,
'email1' => null,
'email2' => null,
'age' => null
);
validate_all($errors);
if(empty($errors['username']) && empty($errors['password1']) && empty($errors['password2']) && empty($errors['email1']) && empty($errors['email2']) && empty($errors['age'])) {
//do something
} else {
$_SESSION['errorsArray'] = $errors;
header('Location: /registracia');
exit;
}
}
verify_form.php
<?php
function validate_all($errors)
{
validUsername($errors);
validPassword1($errors);
validPassword2($errors);
validEmail1($errors);
validEmail2($errors);
validAge($errors);
}
function validUsername($errors)
{
include 'config.php';
$username=$_POST['usernameReg'];
if (strlen($username) < 3 || strlen($username) > 16) {
$errors['username'] = "Zadajte uživateľské meno v rozmedzí 3 - 16 znakov.";
}
$query = "SELECT * FROM `users` WHERE `username` = '$username'";
$result = mysqli_query($link, $query) or die(mysqli_error($link));
if (mysqli_num_rows($result) > 1) {
$errors['username'] = "Toto uživateľské meno už niekto používa.";
}
}
function validPassword1($errors)
{
$password1=$_POST['password1Reg'];
$regex = '/^([a-zA-Z]|[0-9]|[-]|[_]|[/]|[.])+([a-zA-Z]|[0-9]|[-]|[_]|[/]|[.])+([a-zA-Z]|[0-9]|[-]|[_]|[/]|[.])$/';
if (!preg_match($regex, $password1)) {
$errors['password1'] = 'Vaše heslo obsahuje nepovolené znaky.';
}
if (strlen($password1) < 6) {
$errors['password1'] = 'Heslo musí obsahovať minimálne 6 znakov.';
}
}
function validPassword2($errors)
{
$password2=$_POST['password2'];
if ($password1 != $password2) {
$errors['password2'] = 'Zadané heslá sa nezhodujú.';
}
}
function validEmail1($errors)
{
include 'config.php';
$email1=$_POST['email1'];
$regex = "/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/";
if (!preg_match($regex, $email1)) {
$errors['email1'] = 'Neplatná e-mailová adresa.';
}
$query = "SELECT * FROM `users` WHERE `email` = '$email1'";
$result = mysqli_query($link, $query) or die(mysqli_error($link));
if (mysqli_num_rows($result) > 1) {
$errors['email1'] = "Tento e-mail už niekto používa.";
}
}
function validEmail2($errors)
{
$email2=$_POST['email2'];
if ($email1 != $email2) {
$errors['email2'] = 'Zadané e-maily sa nezhodujú.';
}
}
function validAge($errors)
{
$age=$_POST['age'];
$regex = "/^([0-9]|[0-9][0-9])$/";
if (!preg_match($regex, $age)) {
$errors['age'] = 'Vek musí byť číslo v rozsahu od 0-99.';
}
}
?>
Why the script always continue?
You're passing the $errors array into the validUsername() function. The function doesn't actually receive the original array, but instead it gets a copy of it. You're modifying the copy, but the original is never modified. Here's a smaller example to show you how this works:
function addCheese(Array $arr)
{
$arr[] = 'cheese';
}
$a = array();
addCheese($a);
var_dump($a);
// Outputs:
// array(0) {
// }
One way to fix this would be to modify each validation function to return the modified array:
function validSomething($errors)
{
// ... do validation checks
return $errors;
}
... and then assign the updated version to the external value:
function validate_all($errors)
{
$errors = validUsername($errors);
$errors = validPassword1($errors);
$errors = validPassword2($errors);
$errors = validEmail1($errors);
$errors = validEmail2($errors);
$errors = validAge($errors);
return $errors;
}
Alternatively you could return the local array of errors and assemble them together, or just pass by reference (although this might cause other problems later on).
I'd strongly recommend using some sort of framework to do your validation: this will save you a lot of time in the long run.
function validEmail2($errors) doesn't make sence... $email1 is not defined and will always be != $_POST['email2']
You need to give the valid functions pointers to $errors. For example
function validUsername(&$errors)
I'm writing an application that allows users to upload reference letters for potential employees.
Every reference is sent an email containing a unique string at the end of the url. So, for example, an address would look similar to: www.mywebaddress?url=503241a20b5085_18720621.
To determine if the unique string is valid (i.e. exists in the database) I need to do a query search. However, when a reference attempts to access the URL he needs to answer a security question. So, I also need to check if the answer is valid, if he has previously uploaded, etc to determine what page to redirect him to.
But because of the query, my code requires the user to click "Submit" twice. This is really annoying, but I'm not sure how to fix it.
Here is a relevant excerpt of my code:
if ( isset ($_GET['url']) ) {
$query = "SELECT * FROM ref_info WHERE url='" . $_GET['url'] . "'";
$result = $db->execute($query);
if ( empty ($result) ) {
//error message
} else {
$url = $_GET['url'];
if ( $_SESSION['validated'] ) {
if ( $result[0]['uploaded'] ==1 ) {
$_SESSION['uploaded'] =true;
} else {
$_SESSION['uploaded'] =false;
}
include_once("process_upload.php");
} else {
if ( empty($result[0]['answer']) ) {
include_once("security.php");
} else {
include_once("security_check.php");
}
}
}
}
Is there anything I can do so that the form only needs to be submitted once?
Thanks in advance for any suggestions!!
if ( isset ($_GET['url']) ) {
$query = "SELECT * FROM ref_info WHERE url='" . $_GET['url'] . "'"; //that is really not secure. Take a look at mysql_real_escape_string or something like that in yor $db
$result = $db->execute($query);
if ( empty ($result) ) {
//error message
} else {
$url = $_GET['url'];
if (empty($result[0]['answer']) ) { // page is just opened,form is not yet submitted - ask sequrity question
include_once("security.php");
} else { //oh. Submit is done - let me check if it is Ok
include_once("security_check.php");
}
if ( $_SESSION['validated'] ) { //validation is Ok? Yeah. Answer is not posted yet, so validation fails and we do nothing. Just show a form with a question
if ( $result[0]['uploaded'] ==1 ) {
$_SESSION['uploaded'] =true;
} else {
$_SESSION['uploaded'] =false;
}
include_once("process_upload.php");
}
}
}
I have a validation function which returns either true or false.
However, I want it to provide info as to what the problem is, when there is one.
Let's say the function is like this:
function is_valid($val) {
$result = true;
if( rule_1_not_met ) $result = false;
if( rule_2_not_met ) $result = false;
return $result;
}
Which is used like this
$val = $_GET['some_param'];
if(!is_valid($val)) $out .= 'Not so helpful feedback.';
...
I thought I could change it like this:
function is_valid($val) {
$result = array(true, array());
if( rule_1_not_met ) $result[1][] = 'Reason 1';
if( rule_2_not_met ) $result[1][] = 'Reason 2';
if(count($result[1]) > 0) $result[0] = false;
return $result;
}
And use it like this:
$val = $_GET['some_param'];
$validation_result = is_valid($val);
if(!$validation_result[0]) $out .= implode('<br/>', $validation_result[1]);
...
My question is
Am I in, for unexpected results with this?
Are there better ways to achieve this?
P.S. Would make this community wiki
You are in the right track but I would like to do this in this way
function is_valid($val,&$mes) {
$result = true;
if( rule_1_not_met ) { $mes[]='message one'; $result = false; }
if( rule_2_not_met ) { $mes[]='Message two'; $result = false; }
return $result;
}
$mes=array();
if(isvalid($val,$mes) ===false) $out .= implode('<br/>', $mes);
In my opinion, your proposed solution works fine. The only problem with it is that you have to remember that $validation_result[0] is the status and $validation_result[1] contains the messages. This might be OK with you but it will be hard to maintain if other people use your code. One thing you can do is when you call your function, you can use array destructuring to at least store the results with meaningful variable names. For example:
[$valid, $errors] = is_valid($val);
if(!$valid) $out .= implode('<br/>', $errors);
For the reason mentioned above, I like Brad Thomas's solution of creating a specialized class that contains the messages and status. Since the properties are named, you don't have to guess how to access the validation information. Also, most good IDEs will autocomplete when you try to access their properties.
I also have an alternate solution. Instead of including a boolean true or false. Just return the array of messages. The caller would just have to check if the returned array has a non-zero number of errors. Here is an example:
function get_errors($val) {
$errors = array();
if( rule_1_not_met ) $errors[] = 'Reason 1';
if( rule_2_not_met ) $errors[] = 'Reason 2';
return $errors;
}
Then the caller would use it like this:
$val = $_GET['some_param'];
$validation_result = get_errors($val);
if (count($validation_result) > 0) $out .= implode('<br/>', $validation_result);
You could use a Result object that encapsulates return data, a message and a status.
i.e.
class Result( $bResult, $sMessage, $mData ) {
public function __construct() {
$this->bResult = $bResult;
$this->sMessage = $sMessage;
$this->mData = $mData;
}
}
In Your code:
$result = new Result(true, 'some helpful message here', null);
$reasons = array();
function is_valid($val)
{
global $reasons;
if ( rule_1_not_met ) $reasons[] = 'Reason 1';
if ( rule_2_not_met ) $reasons[] = 'Reason 2';
if ( count($reasons) == 0 )
return TRUE;
else
return FALSE;
}
if (!is_valid($condition))
{
echo 'Was not valid for these reasons<br />';
foreach($reasons as $reason)
echo $reason, '<br>';
}
else
echo 'Is valid!';
This question is old, and makes a showcase of bad and outdated practices. Using global is frowned upon, and using references in this context is just the same.
Only Cave Johnson's answer makes it straight, but still the usage could be confusing. A better solution would be to write a class, but not as silly one as in the Brad Thomas's answer.
class NumberValidator
{
protected $errors;
public function validate($number)
{
if(!is_numeric($number))
{
$this->errors[] = "The value provided is not numeric";
return false;
}
if($number < 10)
{
$this->errors[] = "The number is less than 10";
return false;
}
return true;
}
public function getErrors()
{
return $this->errors;
}
}
and then it can be used like this
$validator = new NumberValidator();
if($validator->validate($number)) {
/*success*/
}
and then $validator->getErrors() can be used elsewhere