[RESOLVIDO] Opinião Login

ThinkBrunus

Power Member
Olá!
Mais uma vez venho em busca de uma opinião sobre como fazer um sistema de login.

O que pretendo é que o user faça o login no form normal e os dados sejam validados na mesma página, e se a autenticação for validada, queria que desaparecesse o tal formulário e aparecesse os dados do user, por exemplo.

Entretanto já fiz umas pesquisas e algum estudo para desenvolver algo em AJAX e PHP, ou só em PHP. De momento estou a tentar implementar AJAX com PHP mas já tenho a cabeça quase em àgua....

Gostava de saber opiniões.
Obrigado!
 
Última edição:
Depois de alguma pesquisa conclui que a forma mais segura para utilizar num sistema de login é utilizar AJAX + PHP.
Agora tou com dificuldades numa situação, ou seja:

ao inserir os dados para autenticar escrevo em php o form com uma cláusula if

index.php

<div id="iBlockUser">
<?php
if (!isset($_SESSION['nome'])) {
unset($_SESSION['nome']);
echo"<script language='javascript' src='scripts/ajax.js'></script>
<table><form id='frmLogin' name='frmLogin' method='post' >
<tr>
<td>Username:</td>
<td><input type='text' name='txtUserName' id='txtUserName' size='14' maxlength='14' /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type='text' name='txtPassword' id='txtPassword' size='14' maxlength='14' /></td>
</tr>
<tr>
<td colspan='2' align='right'><input name='btnLogin' value='Login' id='btnLogin' type='submit'
onclick='java script:login();' /></td>
</tr>
</form>
</table>";
}else{
include('seguranca.php');
}
</div>
?>


aqui é chamado o ficheiro AJAX, busca os dados e envia-os para a página onde faz a validação dos dados

ajax.js

function login(){
xmlHttp = getXmlHttpObject(); //inicializa variável com identificação do browser
var username = encodeURI(document.getElementById('txtUserName').value);
var password = encodeURI(document.getElementById('txtPassword').value);
nocache = Math.random();
xmlHttp.open("GET", "login.php?username="+username+"&password="+password+"&nocache="+nocache);
xmlHttp.onreadystatechange = function(){
if (xmlHttp.readyState == 4) {
alert(xmlHttp.responseText);
//document.getElementById("iMenuV").innerHTML = xmlHttp.responseText;
}
}
xmlHttp.send(null);
}


Agora valida dados enviados e retorna valor para AJAX, e se validar correctamente cria a session com o username...
login.php
<?php
include('includes/config.php');

//CÓDIGO LOGIN AJAX&PHP
$username = $_GET['username'];
$password = $_GET['password'];
$sql = "SELECT * FROM ndetalhe WHERE nome='" . $username . "' AND password='" . $password . "'";
$query = mysql_query($sql) or die('Query failed: ' . mysql_error());
$result = mysql_num_rows($query);
if ($result > 0){
echo "Confere!";
session_start();
$_SESSION['nome'] = $username;
}else{
echo "Dados incorrectos!";
}
?>

index.php
Por fim, está aqui o meu problema:

......
}else{
include('seguranca.php');
}
?>


O que pretendo é que quando o user for validado, desapareça o formulário e seja apresentado o nome do user, por exemplo. Este include refere-se a essa mensagem

seguranca.php
<?php
echo "Olá, " . $_SESSION['nome'];
?>


Que não está a funcionar....o formulário mantem-se e a mensagem não aparece....
Alguma sugestão para contornar a situação?
coloquei on-line em : http://teste.vibeltaxis.com/index.php

Obrigado!
 
Deixa a validação toda para o PHP porque o javascript pode ser desactivado sem problemas. Tens também variaveis a ser usadas em queries sem qualquer tipo de protecção.
 
referes-te à página login.php?

<?php
include('includes/config.php');

//CÓDIGO LOGIN AJAX&PHP
$username = $_GET['username'];
$password = $_GET['password'];
$sql = "SELECT * FROM ndetalhe WHERE nome='" . $username . "' AND password='" . $password . "'";
$query = mysql_query($sql) or die('Query failed: ' . mysql_error());
$result = mysql_num_rows($query);
if ($result > 0){
echo "Confere!";
session_start();
$_SESSION['nome'] = $username;
}else{
echo "Dados incorrectos!";
}
?>
 
Boas!

O o código já está ajustado, e já está a funcionar!
O problema agora é implementar as sessões entre AJAX e PHP, e não sei onde hei-de colocar, estou a tentar mandar escrever assim:

document.getElementById("iBlockUserLogout").innerHTML = "session_start(); $_SESSION['test'] = $username;";

Pelo que já me disseram, o session_start(); deve estar no inicio da página, mas na verdade já vi vário exemplos no meio de código....

Como não está a funcionar não me parece que seja boa ideia...alguém já teve algum problema idêntico?
 
Boas!

O o código já está ajustado, e já está a funcionar!
O problema agora é implementar as sessões entre AJAX e PHP, e não sei onde hei-de colocar, estou a tentar mandar escrever assim:

document.getElementById("iBlockUserLogout").innerHTML = "session_start(); $_SESSION['test'] = $username;";

Pelo que já me disseram, o session_start(); deve estar no inicio da página, mas na verdade já vi vário exemplos no meio de código....

Como não está a funcionar não me parece que seja boa ideia...alguém já teve algum problema idêntico?

Acho que estás a fazer um pouco confusão e a misturar PHP com Javascript :)

Para manteres o código como está agora uma possível solução seria, se a verificação do username for válida, isto é, existir um registo válido na tabela, retornas o nome, e no Javascript verificas que se foi retornado um valor então é porque o login é válido, caso contrário, mostras a tal mensagem a dizer dados incorrectos.


Tenta fazer estas alterações e verifica se resultam:

No index.php adiciona este código no inicio do ficheiro:
PHP:
<?php
session_start();
?>

No login.php, substitui isto:
PHP:
if ($result > 0){
echo "Confere!";
session_start();
$_SESSION['nome'] = $username;
}else{
echo "Dados incorrectos!";
}

Por isto:

PHP:
session_start();
if ($result > 0){
  $_SESSION['nome'] = $username;
  $response=$_SESSION['nome'];
}
else{
  $response="";
}
echo $response;



No ajax.js, dentro da condição "if (xmlHttp.readyState == 4) {", substitui isto:

Código:
alert(xmlHttp.responseText);
//document.getElementById("iMenuV").innerHTML = xmlHttp.responseText;

Por isto:

Código:
var result=xmlHttp.responseText;
if(result) {document.getElementById("iBlockUser").innerHTML="Ola "+result;}
else {alert("Dados Incorrectos!");}


- não te podes esquecer que se o utilizador tiver o Javascript desactivo, o formulário vai ser submetido e não estás a fazer esse tratamento;
- cuidado ao construir a tua instrução SQL, como já referiram;
- o teu campo de password não devia estar como text :p;
- neste caso de validação de dados, acho que o melhor é enviar o username e password por POST e não GET;
- o teu botão de submit altera o onclick para: onclick='javascript: login();return false;'
 
Última edição:
Acho que estás a fazer um pouco confusão e a misturar PHP com Javascript :)
Tens razão p3dro, as voltas foram tantas que a dada altura já não sabia para me onde virar!

Esta página tem um bom sistem de login/register com "remember me" feature (em php, usando DB). Acho que podes aprender muito com isto.

http://evolt.org/node/60265
Optei por implementar este código e não outro porque pelas pesquisas que fiz, fiquei com a sensação que login em ajax é mais seguro, e depois quero que o form de login apareça se o user não tiver logado e vice-versa.

Agora que já acertei algumas coisas e está parcialmente a funcionar, venho aqui partilhar convosco, talvez com as vossas opiniões possa fazer melhorias!

index.php
Código:
session_start();
?>
...
<script src="scripts/ajax.js"></script>
...
    <div id="iBlockUser">
        <?php
            if (empty($_SESSION['username'])){
                include('login.php');
            } else {
                echo "<div id='iBlockUserLogout'>" . $_SESSION['username'] . "</div>";
            }
        ?>
        </div>
Pretende-se que no index seja apresentado o form para o utilizador se logar, apenas se este ainda não estiver logado, se estiver logado será apresentado uma mensagem com o nome do utilizador.

ajax.js
Código:
var xmlHttp;

var nocache = 0;

function login(){
xmlHttp = getXmlHttpObject(); //inicializa variável com identificação do browser
var username = encodeURI(document.getElementById('txtUserName').value);
var password = encodeURI(document.getElementById('txtPassword').value);
nocache = Math.random();
xmlHttp.open("GET", "loginResponse.php?username="+username+"&password="+password+"&nocache="+nocache);
    xmlHttp.onreadystatechange = function(){
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.responseText == 0){
                alert('Dados incorrectos!');
            } else{
                document.getElementById("iBlockUser").innerHTML = xmlHttp.responseText;
            }
        }
    }
xmlHttp.send(null);
}


//verifica qual o browser utilizado
function getXmlHttpObject(){
var xmlHttp = null;
    try {  // Firefox, Opera 8.0+, Safari
        xmlHttp=new XMLHttpRequest();
    }
    catch (e) {  // Internet Explorer
          try {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        }
          catch (e) {
            try {
                xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
              }
            catch (e) {
                   alert("O browser não suporta AJAX!");
                  return false;
              }
        }
      }
    return xmlHttp;
}
Verifica o browser e faz um request com os dados inseridos para os validar.

responseLogin.php
Código:
session_start();
include('includes/settings.php');

$username = $_GET['username'];
$password = $_GET['password'];
$sql = "SELECT * FROM ndetalhe WHERE nome='" . $username . "' AND password='" . $password . "'";
$query = mysql_query($sql) or die('Query failed: ' . mysql_error());
$result = mysql_num_rows($query);
    if ($result > 0){
        $_SESSION['username'] = $result -> nome;
    }else{
        echo "0";
    }
</div>
Apenas estou a deparar-me com alguns pormenores, quando o user faz o login e é autenticado aparece um warning, e torna-se necessário fazer um refresh manual. Depois se tiver pastas dentro da raiz e for navegar pelo site até essas pastas e fizer o login não dá, pois ele vai dizer que não encontra o objecto, e refere-se aqui:
Código:
xmlHttp.open("GET", "loginResponse.php?username="+username+"&password="+password+"&nocache="+nocache);
para desenrrascar criei outro ficheiro para estas situações:
Código:
xmlHttp.open("GET", "../loginResponse.php?username="+username+"&password="+password+"&nocache="+nocache);

Se alguém tiver algum comentário será bem vindo!
 
Última edição:
Tens razão p3dro, as voltas foram tantas que a dada altura já não sabia para me onde virar!

Optei por implementar este código e não outro porque pelas pesquisas que fiz, fiquei com a sensação que login em ajax é mais seguro, e depois quero que o form de login apareça se o user não tiver logado e vice-versa.

Agora que já acertei algumas coisas e está parcialmente a funcionar, venho aqui partilhar convosco, talvez com as vossas opiniões possa fazer melhorias!

index.php
Código:
session_start();
?>
...
<script src="scripts/ajax.js"></script>
...
    <div id="iBlockUser">
        <?php
            if (empty($_SESSION['username'])){
                include('login.php');
            } else {
                echo "<div id='iBlockUserLogout'>" . $_SESSION['username'] . "</div>";
            }
        ?>
        </div>
Pretende-se que no index seja apresentado o form para o utilizador se logar, apenas se este ainda não estiver logado, se estiver logado será apresentado uma mensagem com o nome do utilizador.

ajax.js
Código:
var xmlHttp;

var nocache = 0;

function login(){
xmlHttp = getXmlHttpObject(); //inicializa variável com identificação do browser
var username = encodeURI(document.getElementById('txtUserName').value);
var password = encodeURI(document.getElementById('txtPassword').value);
nocache = Math.random();
xmlHttp.open("GET", "loginResponse.php?username="+username+"&password="+password+"&nocache="+nocache);
    xmlHttp.onreadystatechange = function(){
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.responseText == 0){
                alert('Dados incorrectos!');
            } else{
                document.getElementById("iBlockUser").innerHTML = xmlHttp.responseText;
            }
        }
    }
xmlHttp.send(null);
}


//verifica qual o browser utilizado
function getXmlHttpObject(){
var xmlHttp = null;
    try {  // Firefox, Opera 8.0+, Safari
        xmlHttp=new XMLHttpRequest();
    }
    catch (e) {  // Internet Explorer
          try {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        }
          catch (e) {
            try {
                xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
              }
            catch (e) {
                   alert("O browser não suporta AJAX!");
                  return false;
              }
        }
      }
    return xmlHttp;
}
Verifica o browser e faz um request com os dados inseridos para os validar.

responseLogin.php
Código:
session_start();
include('includes/settings.php');

$username = $_GET['username'];
$password = $_GET['password'];
$sql = "SELECT * FROM ndetalhe WHERE nome='" . $username . "' AND password='" . $password . "'";
$query = mysql_query($sql) or die('Query failed: ' . mysql_error());
$result = mysql_num_rows($query);
    if ($result > 0){
        $_SESSION['username'] = $result -> nome;
    }else{
        echo "0";
    }
</div>
Apenas estou a deparar-me com alguns pormenores, quando o user faz o login e é autenticado aparece um warning, e torna-se necessário fazer um refresh manual. Depois se tiver pastas dentro da raiz e for navegar pelo site até essas pastas e fizer o login não dá, pois ele vai dizer que não encontra o objecto, e refere-se aqui:
Código:
xmlHttp.open("GET", "loginResponse.php?username="+username+"&password="+password+"&nocache="+nocache);
para desenrrascar criei outro ficheiro para estas situações:
Código:
xmlHttp.open("GET", "../loginResponse.php?username="+username+"&password="+password+"&nocache="+nocache);
Se alguém tiver algum comentário será bem vindo!

Para ultrapassares o problema de não encontrar o script, usa /loginResponse.php....
 
Obrigado, resolveu o problema!
Utilizando "/loginResponse.php...." ele vai buscar à pasta a cima, é isso?

Já agora, quando faço o login, ele dá-me o seguinte warning:
Warning: Unknown: Your script possibly relies on a session side-effect which existed until PHP 4.2.3.
Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled.
You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively.
in Unknown on line 0

Isto será porquê?
 
Última edição:
Obrigado, resolveu o problema!
Utilizando "/loginResponse.php...." ele vai buscar à pasta a cima, é isso?

Já agora, quando faço o login, ele dá-me o seguinte warning:


Isto será porquê?

1º - Não, o "/" é para ir à raiz;

2º - $_SESSION['username'] = $result -> nome; deve ser isto que vai originar o erro, o $result->nome não existe; a tua variável $result vai guardar 1 inteiro e não um object como a estás a referenciar, vê o mysql_fetch_object

Podes alterar o teu código para

PHP:
$result = mysql_fetch_object($query);
if ($result->nome){
E o resto fica igual
 
Ok, obrigado!

Ficou assim
Código:
while ($result = mysql_fetch_object($sql)) {    
    if ($result->nome){
        $_SESSION['username'] = $result -> nome;
    }else{
        echo "0";
    }
}
Desaparece o warning e aparece a janela dados incorrectos....
São inseridos os dados de login, autenticados, e aparece sempre a janela referente à parte do código AJAX

Código:
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.responseText == 0){
                alert('Dados incorrectos!');
            } else {
                document.getElementById("iBlockUser").innerHTML = xmlHttp.responseText;
            }
        }
Ele devia saltar a instrução certo? Pois na página que retorna o valor, se não for autenticado ele retorna 0...
Mas após fazer um refresh são actualizados os dados referentes ao user.
 
Última edição:
Ok, obrigado!

Ficou assim
Código:
while ($result = mysql_fetch_object($sql)) {    
    if ($result->nome){
        $_SESSION['username'] = $result -> nome;
    }else{
        echo "0";
    }
}
Desaparece o warning e aparece a janela dados incorrectos....
São inseridos os dados de login, autenticados, e aparece sempre a janela referente à parte do código AJAX

Código:
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.responseText == 0){
                alert('Dados incorrectos!');
            } else {
                document.getElementById("iBlockUser").innerHTML = xmlHttp.responseText;
            }
        }
Ele devia saltar a instrução certo? Pois na página que retorna o valor, se não for autenticado ele retorna 0...
Mas após fazer um refresh são actualizados os dados referentes ao user.

Nesse caso até é desnecessário teres 1 while. Não te falta o echo de quando a validação está bem feita?

PHP:
$result = mysql_fetch_object($sql);
if ($result->nome){
  $_SESSION['username'] = $result -> nome;
  echo $_SESSION['username'];
}
else{
  echo "0";
}
 
Back
Topo