Jump to content
Thiago Moreira

[Resolvido] Sistema de login seguro

Recommended Posts

Pra criptografar a senha, pra deixar mais difícil para um hacker, eu geralmente faço isso:

$senha=md5(hash('sha512', $_POST['senha']));

Porque só o com o md5 fica fácil, pois já existem sites e dicionários para decodificar esses códigos.

 

 

Gabriel, obrigado pela dica, já inclui em meu sistema.

 

o quê não conseguiu entender desse script ?

as constantes ?

 

o autoload ?

 

??

 

 

 

não

 

as finalidades são diferentes...

 

o código do ini.php desse tutorial é um bootstrap... como o p'roprio nome do arquivo sugere, um arquivo de inicialização do ambiente..

PHPID está bem claro e definido no site do Thiago... é um filtro contra injeções de comandos nos parâmetros

 

 

Hinom, vamos por parte, para iniciar, não entendi como usar esse código no sistema.

// se formos usar classes elas nao precisaram ser incluidas nos scripts só estanciadas.
function __autoload($classe){
       require_once $classe.".php";    
}

 

Entendi o conceito.

As classes não precisarão serem chamadas via require ou include e isso é ótimo, mas como usar isso na prática?

Share this post


Link to post
Share on other sites

referente ao autoload

 

1. O nome do arquivo deve ser idêntico a nomenclatura do nome da classe

 

exemplo:

 

class Foo{

}

O nome do arquivo deve se chamar Foo.php

 

Por questão de padronização e organização, mantenha uma classe por arquivo.

 

Evite fazer isso, por exemplo:

 

Foo.php

class Foo{

}

class Foo2{

}

class Foo3{

}

 

Quer saber como que o autoload consegue incluir o arquivo automaticamente, certo ?

Isso está definido no parâmetro de configuração do PHP "include_path", veja o passo seguinte:

 

 

2. basepath e include_path

 

set_include_path('.' . PATH_SEPARATOR . BASEPATH . 'includes'
       . PATH_SEPARATOR . BASEPATH . 'classes'
       . PATH_SEPARATOR . get_include_path());

 

Antes desse código, temos a definição da constante BASEPATH:

 

//crio umas constantes para podermos usar no sistema
define("ROOT", $_SERVER["DOCUMENT_ROOT"]);
define("BASEPATH", getcwd()."/");

 

BASEPATH carregará a informação do diretório base do seu aplicativo.

 

Os arquivos PHP estarão basicamente em

 

/ (aqui onde fica o index.php)
/classes/  (obviamente aqui devem estar as classes)
/includes/ (aqui outros arquivos php)

 

 

 

 

observações:

 

Se não entendeu algo, poste para que eu ou alguém que estiver acompanhando possa lhe ajudar.

É sempre bom também mostrar o que fez, como está fazendo, etc.

 

* Aconselho a aplicar o BASEPATH num diretório fora da pasta pública, para reforçar a segurança.

No entanto, não comentarei sobre o assunto para evitar complicar o tópico.

Share this post


Link to post
Share on other sites

hinom, desculpe a demora em responder o fórum é que tenho estado muito ocupado com o trabalho.

 

Agradeço por se dispor em compartilhar seus conhecimentos, obrigado mesmo, está sendo de grande aprendizado para mim.

 

Entendi que a classe e o nome do arquivo devem ser idênticos.

Também entendi o funcionamento das constantes "ROOT" e "BASEPATH".

 

Não entendi o funcionamento do "include_path" e nem o "__autoload".

Quero dizer, compreendi que o "include_path" define o diretório e o "__autoload" tenta carregar o arquivo contendo a classe caso o mesmo não seja encontrado, mas quem carrega o "__autoload"?

 

Sei que esse entendimento não é necessário levando em consideração que compreendi o uso do código, mas como sou curioso por conhecimento, me questionei quanto a isso.

 

Mas minha maior questão vem logo a seguir.

Vou colocar abaixo o meu cenário/minha necessidade atual, pois não estou visualisando uma solução para ele.

 

 

Tenho a seguinte estrutura de arquivos

 

web (aqui fica os arquivos de meu site(web))

adm (toda a administração do site(web))

adm/noticias (sistema de notícias)

adm/usuario (sistema de usuários)

classes (as classes usadas tanto pelo admin quanto pelo site(web))

lib (biblioteca de funções que não são classes e são usadas pelo admin ou site(web))

 

 

Dentro do diretório "classes" tenho a classe "DB.php" por exemplo e quero que ela seja inclusa automaticamente tanto no "site(web)" quanto no "admin".

 

O meu arquivo "init.php" encontra-se dentro do diretório "lib".

 

 

 

Resumindo minha estrutura está assim:

web/index.php

adm/usuarios/usuarios.php

classes/DB.php

lib/init.php

 

Preciso que o "__autoload" para a classe "DB" que encontra-se em "classes/DB.php" funcione nos diretórios abaixo:

- adm/usuarios/usuarios.php

- web/index.php

 

obs: Note que no "adm" existe um nível a mais que em "web"

Share this post


Link to post
Share on other sites

está usando a versão 5.4 do php..

note que o script desse tutorial é de 2007..

 

 

aconselho que primeiramente, configure o log de erros:

http://forum.imasters.com.br/topic/447379-configuracao-de-log-e-eventos-de-erros-do-php/

 

 

 

já expliquei de forma técnica sobre o set_include_path, e outros.. então vou tentar ser mais prático, pois você não entendeu..

 

 

 

no index.php coloque

define("ROOT", $_SERVER["DOCUMENT_ROOT"]);
define("BASEPATH", getcwd() . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR );

set_include_path('.' 
       . PATH_SEPARATOR . BASEPATH . 'lib' . DIRECTORY_SEPARATOR
       . PATH_SEPARATOR . BASEPATH . 'classes' . DIRECTORY_SEPARATOR
       . PATH_SEPARATOR . get_include_path());

require_once "init.php";
require_once "config.php";

 

 

no usuarios.php coloque

define("ROOT", $_SERVER["DOCUMENT_ROOT"]);
define("BASEPATH", getcwd() . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR );

set_include_path('.' 
       . PATH_SEPARATOR . BASEPATH . 'lib' . DIRECTORY_SEPARATOR
       . PATH_SEPARATOR . BASEPATH . 'classes' . DIRECTORY_SEPARATOR
       . PATH_SEPARATOR . get_include_path());

require_once "init.php";
require_once "config.php";

 

 

 

no arquivo init.php, na parte de baixo, desative esses trechos de código.. mantenha somente o autoload

/*
//crio umas constantes para podermos usar no sistema
define("ROOT", $_SERVER["DOCUMENT_ROOT"]);
define("BASEPATH", getcwd()."/");

//pego o conteudo do include_path e ainda incluo mais paths, muito util para o sistema
set_include_path('.' . PATH_SEPARATOR . BASEPATH . 'includes'
       . PATH_SEPARATOR . BASEPATH . 'classes'
       . PATH_SEPARATOR . get_include_path());
*/

// se formos usar classes elas nao precisaram ser incluidas nos scripts só estanciadas.
function __autoload($classe){
       require_once $classe.".php";    
}
/*
//adiciono o arquivo de configuração
if (file_exists(BASEPATH . "config.php")){
       require_once BASEPATH . "config.php";
} else {
       die("Erro: Arquivo config.php nao localizado");
} 
*/
//http://br.php.net/manual/pt_BR/function.clearstatcache.php
clearstatcache();

 

 

obs: os códigos sugeridos não quer dizer que sejam a solucão..

não fiz testes.. apenas escrevi enquanto postava..

imagino que deva fazer isso aí.. mas podem ocorrer outros erros..

 

suporte..

caso queira auxílio específico para o seu caso, consulte o autor do script ou alguém qualificado/experimente em php para lhe prestar consultoria ou mesmo fazer o serviço.

Edited by hinom

Share this post


Link to post
Share on other sites

hinom, muito obrigado pelas dicas.

 

Peguei seu código e fiz um pequeno ajuste a minha realidade.

Como não queria ir colocando uma parte do código aqui e outra ali, criei um if no arquivo "init.php" o qual verifica, através do nome do diretório, se estou no admin ou no site e aplica "BASEPATH" correto.

 

Segue código.

Talvez ajude mais alguém com a mesma dificuldade.

		# crio umas constantes para podermos usar no sistema
	define("ROOT", $_SERVER["DOCUMENT_ROOT"]);

	# Verifico se estou no admin ou no site
	if(stristr(getcwd(), DIRECTORY_SEPARATOR.'adm'.DIRECTORY_SEPARATOR)) {
		define("BASEPATH", getcwd() . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); // EX: adm/usuarios/usuarios.php

	} else {
		define("BASEPATH", getcwd() . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR ); // EX: web/index.php

	}

	# pego o conteudo do include_path e ainda incluo mais paths, muito util para o sistema
	set_include_path('.' 
       . PATH_SEPARATOR . BASEPATH . 'lib' . DIRECTORY_SEPARATOR
       . PATH_SEPARATOR . BASEPATH . 'classes' . DIRECTORY_SEPARATOR
       . PATH_SEPARATOR . get_include_path());

	# se formos usar classes elas nao precisaram ser incluidas nos scripts só estanciadas.
	function __autoload($classe){
			require_once $classe.".php";
	}

 

-----------------------------------------------------------------------------------------------------------------

 

hinon, do trecho de código que postei no início, mais da metade compreendi.

 

A última parte do código era este

		# adiciono o arquivo de configuração
	if (file_exists(BASEPATH . "../config/config.php")){
			require_once BASEPATH . "../config/config.php";
	} else {
			die("Erro: Arquivo config.php nao localizado");
	}

 

 

Com seus ensinamentos dos códigos anteriores, compreendo que aqui está sendo carregado um arquivo com configurações necessárias ao sistema, mas surge a dúvida.

Todas as configurações necessárias ao sistema não deveriam estar no arquivo "init.php" ?

 

Não entendi o porque o autor criou outro arquivo de configurações.

É comum isso? Se for, que tipo de configurações ficariam neste arquivo?

 

-----------------------------------------------------------------------------------------------------------------

 

Uma pergunta que surgiu agora.

 

A "function __autoload" se encarrega de carregar automaticamente todas as classes de determinado diretório, neste caso do diretório "classes/".

 

Digamos que meu sistema esteja com "50 classes".

Quando o usuário acessa meu site as "50 classes" serão carregadas certo?

Isso fica carregado onde? Na memória do server?

 

Caso eu tenha 20mil acessos únicos e diários no meu site, esse método não sobrecarrega o servidor?

 

 

Dúvidas de um iniciante em OOPHP.

 

Desde já grato pelos ensinamentos.

Edited by ezequielg

Share this post


Link to post
Share on other sites

beleza! pra dizer a verdade fiquei surpreso.. te subestimei rsss

 

A "function __autoload" se encarrega de carregar automaticamente todas as classes de determinado diretório, neste caso do diretório "classes/".

 

Digamos que meu sistema esteja com "50 classes".

Quando o usuário acessa meu site as "50 classes" serão carregadas certo?

não.. as classes são carregadas pelo autoload conforme são chamadas...

 

Aconselho o uso do sp_autoload.. pesquise sobre o assunto e comece a usá-lo agora que já entendeu como funciona o autoload

 

 

 

Todas as configurações necessárias ao sistema não deveriam estar no arquivo "init.php" ?

 

Não entendi o porque o autor criou outro arquivo de configurações.

É comum isso? Se for, que tipo de configurações ficariam neste arquivo?

Não...

O arquivo init.php nesse caso, faz o papel do bootstrap.

 

Veja que apesar do script ser bem antigo, ainda sim consegue seguir uma boa organização.

Considere também que é apenas um tutorial para iniciantes que deve ter sido escrito de "cabeça em 10 minutos".

Não é uma library com suporte a atualizações, documentação, etc. Tampouco é um WYSWYG.

A finalidade é educacional somente.

Share this post


Link to post
Share on other sites

Hinom, obrigado novamente.

 

Estou procurando aprender PHP a fundo e criar um código mais seguro, ágil e de fácil manutenção possível.

Sei que ele não ficará perfeito, mas espero que seja útil pelos próximos 3 anos.

Claro que neste período sempre vamos fazendo ajustes.

 

Você sugeriu o seguinte

Aconselho o uso do sp_autoload.. pesquise sobre o assunto e comece a usá-lo agora que já entendeu como funciona o autoload

 

Por acaso não seria "spl_autoload"?

Comecei a pesquisar e separar um material para leitura no fim de semana, por exemplo:

http://www.portalphp.org/artigos/bibliotecas-spl-spl_autoload

 

Também pesquisei levemente sobre "bootstrap"

http://www.serversidemagazine.com/php/bootstrap-php-code/

 

E os estudos continuam.

Caso tenha referências para passar sobre esses assuntos, fico grato.

Share this post


Link to post
Share on other sites

Oi Ezequiel

 

como voce quer aprender PHP a fundo, recomendo começar a estudar OOP, MVC

 

e quando estiver com mais conhecimento e pratica pegue algum framework para estudar/usar, recomendo o Zend Framework

mas tem muitos outros como CakePHP e CodeIgniter

 

estudar esses framework vai abrir sua mente e perceber muito mais do que voce esta acostumado, e sem contar que a nivel de profissao geralmente uma vaga sempre pede um conhecimento de algum framework.

 

bons estudos.

Share this post


Link to post
Share on other sites

Eu baixei o login.php e ta dando o seguinte erro qdo tento logar:


Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'usuario'@'localhost' (using password: YES) in C:\wamp\www\teste login\login2\login.php on line 20

Access denied for user 'usuario'@'localhost' (using password: YES)

 

A linha 20 do login.php é:

 

mysql_connect(SERVIDOR, USUARIO, SENHA) or die(mysql_error());

 

Alguem pode me ajudar por favor?

Obrigado desde já.

Share this post


Link to post
Share on other sites
Em 04/12/2007 at 15:33, Fabyo disse:

index.php

 

 


<?php
if(file_exists("init.php")){
require_once "init.php";
} else {
die("Arquivo de init não encontrado");
}

require_once "seguranca.php";

$dados = isset($_SESSION["dados"]) ? $_SESSION["dados"] : unserialize($_COOKIE["dados"]);
echo "Seja Bem-Vindo ". $dados["nome"]." ";
?>
<a href="sair.php">Sair</a>
 

 

 

seguranca.php:

 

 


<?php
session_start();
if(!isset($_COOKIE["dados"]) and !isset($_SESSION["dados"])){
header("Location: login.html");
}
?>
 

 

 

sair.php:

 

 


<?php
session_start();
$_SESSION["dados"] = null;
session_destroy();
setcookie("dados", "", time()-60*60*24*365);
header("Location: login.html");
?>
 

 

 

login.html:

 

 


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Login</title>
</head>

<body>
<form id="form1" name="form1" method="post" action="login.php">
 <label><strong>Nome</strong>
 <input name="nome" type="text" id="nome" />
 </label>
 <p>
<label><strong>Senha</strong>
<input name="senha" type="password" id="senha" />
</label>
 </p>
 <p>
<label for="cookie">
<input name="cookie" type="checkbox" id="cookie" value="1" />
<strong>Salvar Senha</strong></label>
 </p>
 <p>
<label>
<input type="submit" name="Submit" value="Entrar" />
</label>
 </p>
</form>
</body>
</html>
 

 

 

login.php:

 


<?php
session_start();			
if(file_exists("init.php")){
require_once "init.php";
} else {
die("Arquivo de init não encontrado");
}

function limpa($string){
$var = trim($string);
$var = addslashes($var);	
return $var;
}

if(getenv("REQUEST_METHOD") == "POST"){
$nome  = isset($_POST["nome"]) ? limpa($_POST["nome"]) : "";
$senha = isset($_POST["senha"]) ? limpa($_POST["senha"]) : "";

$sql = sprintf("select count(*) from usuarios where login = '%s' and senha = md5('%s')", $nome, $senha);
mysql_connect(SERVIDOR, USUARIO, SENHA) or die(mysql_error());
mysql_select_db(BANCO) or die(mysql_error());

$re = mysql_query($sql) or die(mysql_error());
if(mysql_result($re, 0)){
	$re 	   = mysql_query("select * from usuarios where login = '$nome' and senha = md5('$senha')") or die(mysql_error());		
	$resultado = mysql_fetch_array($re);

	if($resultado["nivel_acesso"] > 0){
		$dados			 = array();
		$dados["nome"]	 = $nome;
		$dados["senha"]	= $senha;			
		$_SESSION["dados"] = $dados;			

		if(isset($_POST["cookie"])){			
			setcookie("dados", serialize($dados), time()+60*60*24*365);			
		}
		header("Location: index.php");
	} else {
		header("Location: login.html");
	}		
} else {
	header("Location: login.html");
}
}
?>
 

 

 

Bom fiz da maneira mais simples possivel, para nao dificultar no seu entendimento, mas com certeza conforme voce for evoluindo da para melhorar bastante o sistema, e tbm se voce for usar mysqli ou PDO da para fazer muita coisa dahora

 

dai voce tendo a logica só fazer seu layout e colocar os codigos PHP.

 

vou deixar em anexo o sistema completo e funcionando, basta criar o banco de dados e configurar o config.php

 

dai todas as paginas que voce quer proteger com login basta incluir o arquivo 'seguranca.php'

 

agora só postar as duvidas para nos irmos esclarecendo elas

 

login.zip

 

 

Link do login.zip não abre. da erro no zip. agradeço se alguem tiver o novo link

Share this post


Link to post
Share on other sites
52 minutos atrás, Telmo Ademar Machado disse:

 

 

Link do login.zip não abre. da erro no zip. agradeço se alguem tiver o novo link

 

Esse sistema é bastante antigo, melhor você pesquisar por data mais recentes com conexões PDO

ou até mesmo usando frameworks PHP.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.