Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa tarde galera,
A muito tempo tenho problema com meu sistema de login, acabei deixando de lado, mas como não é somente eu quem vai utilizar, acabou que tenho que achar o problema de uma vez, mas anda bem difícil..
Sempre quando faço o login pela 1ª vez no dia.. ele acessa avisa, que a conexão foi feita com sucesso, mas retorna para a tela de login.php novamente, entretanto, se eu digitar corretamente e novamente o usuário e senha (2ª vez), ele informa que deu sucesso e enfim passa para a área administrativa.. Se eu der logout e acessar novamente, vai embora, o problema é o 1º acesso no dia.
login.php
<form name="loginform" method="post" action="userauthentication.php">
<input name="usuario" type="text" placeholder="usuario" size="25" maxlength="50"/><br /><br /><input name="senha" type="password" placeholder="Senha"/><br /><br />
<input type="submit" value="Entrar" />
</form>
userauthentication.php
<?php
$host = "REMOVIDO";
$user = "REMOVIDO";
$pass = "REMOVIDO";
$banco = "REMOVIDO";
$conn = mysqli_connect($host, $user, $pass, $banco);
if(!$conn){
die("Falha na conexao: " . mysqli_connect_error());
}
?>
<html>
<head>
<title>testeeeeeeee</title>
<script type="text/javascript">
function loginsuccessfully() {
setTimeout("window.location='admarea.php?usuario=<?php echo $_POST['usuario'] ?>'", 1000);
}
function loginfailed() {
setTimeout("window.location='login.php'", 1000);
}
</script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<?php
$usuario=$_POST['usuario'];
$senha=$_POST['senha'];
$sql = mysqli_query($conn, "SELECT * FROM masterdata WHERE usuario = '$usuario' and senha = '$senha'") or die (mysqli_error());
$row = mysqli_fetch_assoc($sql);
if($row > 0) {
session_start();
$_SESSION[ 'usuario' ] = $row[ 'usuario' ]; //armazenando usuario
$_SESSION[ 'dados_user' ] = $row; //armazenando tudo em forma de array associativo
echo "<center>Autenticação OK! Você será redirecionado, Aguarde!</center>";
echo "<script>loginsuccessfully()</script>";
} else {
echo "<center>Senha ou Usuário invalidos</center>";
echo "<script>loginfailed()</script>";
}
?>
</body>
</html>
admarea.php
<?php include("classe/conexao.php");
$consulta = "SELECT * FROM usuarios";
$con = $mysqli->query($consulta) or die($mysqli->error);
$usuario=$_GET['usuario'];
?>
<?php
session_start();
if((!isset ($_SESSION['usuario']) == true) and (!isset ($_SESSION['senha']) == true)){
unset($_SESSION['usuario']);
unset($_SESSION['senha']);
header('location:login.php');
}
?>
<!DOCTYPE html>
<html>
<head>
<title>teste</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
Teste
</body>
</html>
Será que ha alguma anomalia nesse meu código, que está causando isso?
Isso ocorre para qualquer navegador.>
2 horas atrás, ESerra disse:
Comece alterando a posição do session_start() ele deve estar sempre antes da liberação do buffer, dito de outra forma, antes que você enviei qualquer coisa para o navegador, para simplificar, coloque no topo do código sempre.
Obrigado ESerra pela dica, adaptei conforme orientação.
Entretanto ainda fica a dúvida, por que será que ainda só conecta depois da 2º tentativa de login?
Ninguem???
Tem algo estranho no seu código. De acordo com o código que você colocou acima, você não criou uma sessão para a senha no arquivo userauthentication.php, assim por exemplo:
$_SESSION['senha'] = $row[ 'senha' ];
E no admarea.php você chama a sessão senha, que não criou, na autenticação:
if((!isset ($_SESSION['usuario']) == true) and (!isset ($_SESSION['senha']) == true)){
Esse if tem muitos parenteses , você pode colocar assim:
if (!isset($_SESSION["usuario"]) and !isset($_SESSION["senha"])) {
Não precisa colocar true nem parenteses em volta do isset. Não sei se vai resolver o seu problema, mas parece que fora isso e a questão da segurança, está tudo certo.Obrigado Luiz, pelo retorno e help.
Entretanto, fiz os ajustes citados e estranhamente o problema persiste.
Eu já não sei mais o que olhar.
Nesses casos nada melhor do que o "//" e o "echo"...
Se você faz a autenticação e esta voltando para a página de login você simplesmente tem que
ver qual chamada esta fazendo este retorno e assim ter mais clareza de onde esta o problema.
São 2 as chamadas para a pagina login.php, aqui:
>
On 6/29/2018 at 2:53 PM, Casas Junior said:
setTimeout("window.location='login.php'", 1000);
e aqui:
>
On 6/29/2018 at 2:53 PM, Casas Junior said:
header('location:login.php');
Comenta uma delas, reinicia o pc e faz o teste, se continuar com o problema, descomente
a anterior e comente a proxima, ai voce tem uma noção de qual pagina esta o problema e
fica mais facil de resolver. Depois de achar qual página (userauthentication.php ou
admarea.php) esta dando problema, vá comentando e dando echo nas linhas...
Eu particularmente nao gosto de usar javascript para redirecionamentos assim,
tirando ela ficaria muito mais facil para trabalhar... use o header(); e ao inves de recuperar
a variável usuário via POST, recupere ela da session().
<?php
$usuario=$_POST['usuario'];
$senha=$_POST['senha'];
if(!isset($usuario) or !isset($senha)){
// Se nao forem passados usuário e senha
// Nem tente conexão, já redireciona para o login
header('location:login.php');
}
// Se ja exite o arquivo de conexão você nao
// precisa criar denovo, facilita a manutenção
require_once("classe/conexao.php");
$sql = mysqli_query($conn, "SELECT * FROM masterdata WHERE usuario = '$usuario' and senha = '$senha'") or die (mysqli_error());
$row = mysqli_fetch_assoc($sql);
if($row > 0) {
session_start();
$_SESSION[ 'usuario' ] = $row[ 'usuario' ]; //armazenando usuario
$_SESSION[ 'dados_user' ] = $row; //armazenando tudo em forma de array associativo
header('location:admarea.php');
}else{
header('location:login.php');
}
?>
Caramba, depois de escrever isso tudo vi que você passa o parametro usuario como POST no
javascript e na hora de receber no adm area você recebe via GET, nem sei como ta funcionando rsrsrs...
De qualquer forma vai um palpite no admarea.php também:
<?php
session_start();
$usuario = $_SESSION['usuario'];
if(isset($usuario)){
header('location:login.php');
}
require_once("classe/conexao.php");
$consulta = "SELECT * FROM usuarios";
$con = $mysqli->query($consulta) or die($mysqli->error);
?><html>
<head>
<title>teste</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body></body>
</html>
Escrevi mais ou menos so para dar uma noção mas nao testei, tem mais algumas coisas a serem
feitas para melhorar o codigo como receber as variáveis de forma terciária, diminuir os colchetes
e etc, mas isso é mais estética, o que realmente me parece bem preoculpante é a falta de tratamento
nas entradas dos dados, antes de fazer a consulta e a forma que a senha esta sendo armazenada (texto puro)...Quero agradecer ao ESerra, luiz14 e MichellHenrique pelo apoio em tentar solucionar o problema.
MichellHenrique, fiquei alguns dias para responder as suas orientações, porque também não estava dando certo e eu fiz vários testes diferentes, nesse seu formato e também não resolvia.
Hoje 4:40h da manhã, me levantei da cama, tive uma ideia e deu certo, acho que eu sonhei com isso.. pq eu já não tava mais encontrando a resposta pra esse problema "bizarro".
Como não dava mensagem nenhuma, eu nunca iria descobrir que o problema era cookie, mas me veio do nada esse arquivo na minha cabeça, que eu já tinha usado outra vez, pra resolver problema de cookie:
php.ini
output_buffering = on
E resolveu o problema!!
Bizarro!!!!
Bom dia
A primeira coisa que eu iria lhe sugerir é criar uma classe para conexão ao BD para você não ter que toda vez abrir uma conexão manualmente.
A segunda coisa seria separar o PHP do HTML. Temos varias maneiras de fazer isso, usando TPL, JavaScript e etc.
Outra coisa seria você criar uma classe usuário e criar um método verificar login (exemplo) para verificar o login e senha do usuário.
Caso a senha digitada no campo senha seja = a senha do BD você redireciona o usuário para tela de adm.
Segue um exemplo das classes que eu uso:
Classe para conexão:
<?php
namespace Livro\Database;
use PDO;
use Exception;
/**
* Cria conexões com bancos de dados
*/
final class Connection{
/**
* Não podem existir instâncias de TConnection
*/
private function __construct() {}
/**
* Recebe o nome do conector de BD e instancia o objeto PDO
*/
public static function open($name)
{
// verifica se existe arquivo de configuração para este banco de dados
if (file_exists("App/Config/{$name}.ini"))
{
// lê o INI e retorna um array
$db = parse_ini_file("App/Config/{$name}.ini");
}
else
{
// se não existir, lança um erro
throw new Exception("Arquivo '$name' não encontrado");
}
// lê as informações contidas no arquivo
$user = isset($db['user']) ? $db['user'] : NULL;
$pass = isset($db['pass']) ? $db['pass'] : NULL;
$name = isset($db['name']) ? $db['name'] : NULL;
$host = isset($db['host']) ? $db['host'] : NULL;
$type = isset($db['type']) ? $db['type'] : NULL;
$port = isset($db['port']) ? $db['port'] : NULL;
// descobre qual o tipo (driver) de banco de dados a ser utilizado
switch ($type)
{
case 'pgsql':
$port = $port ? $port : '5432';
$conn = new PDO("pgsql:dbname={$name}; user={$user}; password={$pass};
host=$host;port={$port}");
break;
case 'mysql':
$port = $port ? $port : '3306';
//$conn = new PDO("mysql:host={$host};port={$port};dbname={$name}", $user, $pass);
//echo "teste";
$conn = new PDO("mysql:host=$host;dbname=$name;charset=utf8",$user,$pass);
break;
case 'sqlite':
$conn = new PDO("sqlite:{$name}");
break;
case 'ibase':
$conn = new PDO("firebird:dbname={$name}", $user, $pass);
break;
case 'oci8':
$conn = new PDO("oci:dbname={$name}", $user, $pass);
break;
case 'mssql':
$conn = new PDO("mssql:host={$host},1433;dbname={$name}", $user, $pass);
break;
}
// define para que o PDO lance exceções na ocorrência de erros
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
}
Arquivo para informar qual banco de dados quero usar:
<?php
/*host = localhost
name = estoque//App/Database/livro.db
user = root
pass = ''
type = mysql*/
host = 127.0.0.1
name = estoque
user = root
pass = ''
type = mysql
?>
Se eu quiser usar outro banco de dados do trocar essa configuração.
classes para fazer busca no banco de dados de maneira orientada a objeto. As três classes são necessárias:
<?php
namespace Livro\Database;
/**
* Classe abstrata para permitir definição de expressões
*/
abstract class Expression
{
// operadores lógicos
const AND_OPERATOR = 'AND ';
const OR_OPERATOR = 'OR ';
// marca método dump como obrigatório
abstract public function dump();
}
<?php
namespace Livro\Database;
require 'Filter.php';
/**
* Permite definição de critérios
*/
class Criteria extends Expression
{
private $expressions; // armazena a lista de expressões
private $operators; // armazena a lista de operadores
private $properties; // propriedades do critério
/**
* Método Construtor
*/
function __construct()
{
$this->expressions = array();
$this->operators = array();
}
/**
* Adiciona uma expressão ao critério
* @param $expression = expressão (objeto Expression)
* @param $operator = operador lógico de comparação
*/
public function add(Expression $expression, $operator = self::AND_OPERATOR)
{
// na primeira vez, não precisamos de operador lógico para concatenar
if (empty($this->expressions))
{
$operator = NULL;
}
// agrega o resultado da expressão à lista de expressões
$this->expressions[] = $expression;
$this->operators[] = $operator;
}
/**
* Retorna a expressão final
*/
public function dump()
{
// concatena a lista de expressões
if (is_array($this->expressions))
{
if (count($this->expressions) > 0)
{
$result = '';
foreach ($this->expressions as $i=> $expression)
{
$operator = $this->operators[$i];
// concatena o operador com a respectiva expressão
$result .= $operator. $expression->dump() . ' ';
}
$result = trim($result);
return "({$result})";
}
}
}
/**
* Define o valor de uma propriedade
* @param $property = propriedade
* @param $value = valor
*/
public function setProperty($property, $value)
{
if (isset($value))
{
$this->properties[$property] = $value;
}
else
{
$this->properties[$property] = NULL;
}
}
/**
* Retorna o valor de uma propriedade
* @param $property = propriedade
*/
public function getProperty($property)
{
if (isset($this->properties[$property]))
{
return $this->properties[$property];
}
}
}
<?php
namespace Livro\Database;
/**
* Permite definir filtros de seleção
*/
class Filter extends Expression
{
private $variable; // variável
private $operator; // operador
private $value; // valor
/**
* Instancia um novo filtro
* @param $variable = variável
* @param $operator = operador (>,<)
* @param $value = valor a ser comparado
*/
public function __construct($variable, $operator, $value)
{
// armazena as propriedades
$this->variable = $variable;
$this->operator = $operator;
// transforma o valor de acordo com certas regras
// antes de atribuir à propriedade $this->value
$this->value = $this->transform($value);
}
/**
* Recebe um valor e faz as modificações necessárias
* para ele ser interpretado pelo banco de dados
* @param $value = valor a ser transformado
*/
private function transform($value)
{
// caso seja um array
if (is_array($value))
{
// percorre os valores
foreach ($value as $x)
{
// se for um inteiro
if (is_integer($x))
{
$foo[]= $x;
}
else if (is_string($x))
{
// se for string, adiciona aspas
$foo[]= "'$x'";
}
}
// converte o array em string separada por ","
$result = '(' . implode(',', $foo) . ')';
}
// caso seja uma string
else if (is_string($value))
{
// adiciona aspas
$result = "'$value'";
}
// caso seja valor nullo
else if (is_null($value))
{
// armazena NULL
$result = 'NULL';
}
// caso seja booleano
else if (is_bool($value))
{
// armazena TRUE ou FALSE
$result = $value ? 'TRUE' : 'FALSE';
}
else
{
$result = $value;
}
// retorna o valor
return $result;
}
/**
* Retorna o filtro em forma de expressão
*/
public function dump()
{
// concatena a expressão
return "{$this->variable} {$this->operator} {$this->value}";
}
}
Exemplo de uso:
<?php
/*
A diferença entre a Active Record e Row Data table é que active record possui meotodo de nogocio e RDG não
*/
class Produto{
private static $con;
private $data;
function __get($prop){
return $this->data[$prop];
}
function __set($prop, $value){
$this->data[$prop] = $value;
}
public static function setConnection(PDO $con){
self::$con = $con;
}
public function find($id){
$sql = "SELECT * FROM produto WHERE id = '$id'";
print $sql."<BR />";
$result = self::$con->query($sql);
return $result->fetchObject(__CLASS__);
}
public function all($filter = ''){
$sql = "SELECT * FROM produto ";
if ($filter) {
$sql.="WHERE $filter";
}
print $sql."<br />";
$result = self::$con->query($sql);
return $result->fetchAll(PDO::FETCH_CLASS, __CLASS__);
}
public function delete(){
$sql = "DELETE FROM produto WHERE id = '{$this->id}'";
print $sql."<br />";
return self::$con->query($sql);
}
public function save(){
if (empty($this->data['id'])) {
$id = $this->getLastId() + 1;
$sql= "insert into produto (id,descricao,estoque, preco_custo,preco_venda,codigo_barras,data_cadastro,origem) ".
"values ('{$id}',".
"'{$this->descricao}',".
"'{$this->estoque}',".
"'{$this->preco_custo}',".
"'{$this->preco_venda}',".
"'{$this->codigo_barras}',".
"'{$this->data_cadastro}',".
"'{$this->origem}')";
}else{
$sql= "update produto set ".
"descricao = '{$this->descricao}',".
"estoque = '{$this->estoque}',".
"preco_custo = '{$this->preco_custo}',".
"preco_venda = '{$this->preco_venda}',".
"codigo_barras = '{$this->codigo_barras}',".
"data_cadastro = '{$this->data_cadastro}',".
"origem = '{$this->origem}'".
"where id = '{$this->id}'";
}
print "$sql <br>";
return self::$con->exec($sql);
}
public function getLastId(){
$sql = "select max(id) as max from produto";
$result = self::$con->query($sql);
$data = $result->fetch(PDO::FETCH_OBJ);
return $data->max;
}
public function getMargemLucro(){
return (($this->prec_venda - $this->preco_custo) / $this->preco_custo) * 100;
}
public function registraCompra($custo,$quantidade){
$this->custo = $custo;
$this->estoque += $quantidade;
}
}
?>
Então como eu disse. Depois de feito, só chamar o método de onde precisar que você terá os dados em mãos.
Espero poder ter dado uma visão do quanto orientação a objeto pode ajudar no seu caso.Na realidade output_buffering "resolver" o problema apenas indica que existe alguma coisa sendo enviada para o navegador antes do session_start()...
Tirar um tempo, analizar e resolver os erros é essencial, principalmente os problemas de segurança,
senha em texto puro no bd (salve usando hash e salt), prevenção contra inject e etc...
Como havia mencionado anteriormente nao testei o código e para variar ao passar os olhos no codigo
esses dias para tras por desencargo de consiência encontrei um erro e atualizei, mas ainda assim não
cheguei a testar na prática. Vale a pena dar uma estudada e dar uma melhorada no seu código. Abraço!
Obrigado por todas as dicas pessoal.
Vou melhorar conforme orientações indicadas.
Comece alterando a posição do session_start() ele deve estar sempre antes da liberação do buffer, dito de outra forma, antes que você enviei qualquer coisa para o navegador, para simplificar, coloque no topo do código sempre.