Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Miguel Rocha1

class login

Recommended Posts

Class login

<?php
class Login{
private $tabela = 'teste_as';
private $prefixo = 'teste_';
   public $erro = '';
private $dados_user_id = '';

private function db(){
$con = new PDO("mysql:host=localhost;dbname=teste", 
      'root', '');
return $con;	
}

private function codifica($senha){
  return md5($senha);	
}

private function validarLogin($email, $senha){
$senhamd5 = md5($senha);
try{
$validar = $this->db()->prepare('SELECT * FROM `'.$this->tabela.'` WHERE `email`=:email AND `senha`=:senha AND `status` = "2"');
$validar->bindParam(':email', $email, PDO::PARAM_STR); 
$validar->bindParam(':senha', $senhamd5, PDO::PARAM_STR); 
$validar->execute();

  if($validar->rowCount()==1){
	  $dados_user = $validar->fetch(PDO::FETCH_OBJ);
	  $this->dados_user_id = $dados_user->id;
	return true;
  }else{
	return false;
  }
}catch(PDOException $e){
	$this->erro = 'Sistema indisponível';
	logErros($e);
	 return false;
   }
}

public function logar($email, $senha, $lembrar=false){

	  if($this->validarLogin($email, $senha)){
		  if(!isset($_SESSION)){
	    	session_start();	  
	  }

	$_SESSION[$this->prefixo.'cid'] = $this->dados_user_id;

		  if($lembrar){
                  $this->lembrardados();
             }
	    return true;
         }else{
   $this->erro = 'usuarionaoexiste';
  return false;
      }
}

public function logado(){
	if(!isset($_SESSION)){
		session_start();
	}
if($_SESSION[$this->prefixo.'cid'] OR $_COOKIE[$this->prefixo.'cid']){
	return true;
		}
   	return false;		
   }

public function sair(){
	if(!isset($_SESSION)){
		session_start();
	}
     unset($_SESSION[$this->prefixo.'cid']);
  session_destroy();

	if(isset($_COOKIE[$this->prefixo.'cid'])){
		setcookie($this->prefixo.'cid',false,(time()-3600),'/');
		unset($_COOKIE[$this->prefixo.'cid']);
	}
}

private function lembrardados(){
  $tempo = strtotime('+7 day',time());
  setcookie($this->prefixo.'cid',$this->dados_user_id,$tempo,'/');	  
}


}

?>

 

teste.php

require_once("engine/classes/login.class.php");
$objLogin = new Login();

if($objLogin->logado()){
    header("Location: ./");
 exit();
}

if (getenv("REQUEST_METHOD") == "POST"){

if($_POST['email'] == ""){
	  $erro = 'Tens de indicar o teu email';
}elseif(!eregi("^[a-z0-9_\.\-]+@[a-z0-9_\.\-]*[a-z0-9_\-]+\.[a-z]{2,4}$", $_POST['email'])){
     $erro = 'Email invalido';	
}elseif($_POST['senha'] == ""){
	  $erro = 'Teens de preencher os teus dados de login';
 }else{

if($objLogin->logar(strip_tags(trim($_POST['email'])),strip_tags(trim($_POST['senha'])),strip_tags(trim($_POST['lembrar'])))){
           header("Location: testeindex.php"); 
 }else{
  if($objLogin->erro == 'usuarionaoexiste'){
	  $erro = errologin;
  }else{
 $erro = $objLogin->erro;		  
    }
 }
}
}

 

 

Criei este sistema de login e gostava de saber a vossa opinião em questão a segurança e performance

 

Obrigado a todos desde de ja

Compartilhar este post


Link para o post
Compartilhar em outros sites

posso dar minha opiniao sem medo ? (tem gente q pede opiniao e nao gosta de critica, ae eu pergunto pq pediu opinao?)

 

1- nao utilize a conexao direto nas classes, se um dia os dados de login ao banco mudar, vctera q mudar em todas as classes-sugestao utilize uma classe pra conexao e somente conexao

 

2- PDO eh forte, mas nem todos os hosts tem o pdo habilitado-sugestao utilize mysqli, eh nativo, habilitado e tem as mesmas funcoes de statements prepared

 

3-apesar de muita gente gostar do md5 h sites q conseguem descriptografar o md5, eu gosto de usar o hmac_hash, q me oferece mais opcoes de criptografia, eu gosto de usar nela o sha512, enquanto o md5 tem 32bits o sha512 tem 128bits.

 

4-você usou o mesmo codigo 2x, pra q? uma as filosofias da OO eh reuso

 

private function codifica($senha){
         return md5($senha);   
       }

       private function validarLogin($email, $senha){
       $senhamd5 = md5($senha);

 

5- validar login e logar sao metodos iguais, pq? pq de qq forma ele vai validar os dados...logo vai ambos tb retornar se o usuario eh valido ou nao, lembra do item 4 ali emcima?

 

por mim por enquanto eh isto...

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo para eu puder reparar os erros as pessoas tenhem de criticar, criticar e uma maneira de eu melhorar.

 

Eu tenho uma classe de conexao, so ainda nao descobri como passar para esta class, sei que dava para fazer com extends mas ouvi dizer que e pouco recomendavel.

 

No meu host tenho o pdo habilitado amigo.

 

Ja pensei em usar md5(sha512($senha)); ou ao contrario.

 

 

Essa parte de usar o codigo duas vezes escapou, nao reparei.

 

Nao percebi a 5- amigo, sera que me podia explicar melhor?

 

obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok...no item 5, veja q o validar login vai retornar se o login eh valido, e o logar vai retornar o resultado de validar login, logo você pode usar apenas um metodo ali...

 

o problema nao eh ter PDO habilitado, e sim ele estar habilitado onde você o puser, um cliente pode ja ter um host e você ser obrigado a trabalhr neste host, e q pode nao ter pdo habilitado e ae?...o pdo tb eh excelente quando você trabalha com multiplos bancos de dados..se trabalha so com mysql, nao vejo problema eh usar mysqli...

 

sobre a classe de conexao, vamos a um exemplo bem grosseiro

 


//aki usarei design pattern singleton( q prove uma unica e apenas uma instancia de determinado objeto) e usarei tb a agregacao(um dos principios do OO)

class Connection{
private static $instance = null;
private $conn = null;

private function _construct()
{
$data = $this->getData();
$this->conn =new mysqli($data['host'],$data['user'],$data['pass'],$data['db']);
return $this->conn;
}


private function getData()
{
return pase_ini_file('/app/config.ini');
/*
estrutura do config.ini
host=meuhost
user=meuuser
pass=mupass
db=meudb
*/
}

private function __clone(){}

public static function getInstance()
{
if(self::$instance === null)
{
self::$instance = new self;
}
return self::$instance;
}
}


class Login
{

private $conn ;

public function getConnection(Connection $conn)
{
$this->conn = $conn;
}

public function logar($user,$pass) 
{
$this->conn->query('select $user $pass');
}
}

$conn = Connection::getInstance();
$logar = new Logar();
$logar -> getConnection($conn);
$logar->login('igor','igor);

 

bem simples...qq duvida posta ae....eu fiz de cabeça, tem 80% de dar certo, mas a ideia eh esta...ae no caso você so muda os dados do banco no config.ini...

 

um ponto importante a lembrar eh q cada classe eh responsavel por algo...a responsabilidade do carro eh locomover, assim como ele nao eh responsavel pelo combustivel...

Compartilhar este post


Link para o post
Compartilhar em outros sites

amigo usar a extends esta fora de questao?

 

se o objetivo da classe se manter, no caso apenas de conectar, eu nao vejo pq nao ter extends...

 

no caso ali eu falei q ia usar apenas o singleton e agregacao, eu errei, eu fiz tb uma composicao...mas ha casos e casos...se estiver estudando OO eu aconelho a primeiro aprender OO e depois desing patterns...tem varios livros bons no mercado, eu aconselho do pablo dalloglio entre outros...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Miguel, você conhece o conceito de herança???

 

Me diga, porque uma classe de login seria herdeira de uma classe de DB? O que elas têm em comum? O que elas compartilham?

 

Veja, login não é um DB, ela usa um DB.

 

e MD5 é um hash, não é decriptografável. Hashes são algoritmos de mão única, não têm volta. O que já existe são tabelas de entrada e seus valores conhecidos. Se alguém tiver acesso ao seu banco e houverem senhas com MD5 conhecidas, elas podem ser utilizadas MESMO QUE NÃO SEJAM A SENHA CADASTRADA.

 

http://www.mscs.dal.ca/~selinger/md5collision/

 

dê uma olhada nesse par de funções que vai achar bastante interessante:

 

http://php.net/hash_algos

http://br2.php.net/manual/pt_BR/function.hash.php

 

Recomendo whirlpool

Compartilhar este post


Link para o post
Compartilhar em outros sites

entao, existem diversas design patterns pra isto...eu gosto de usar o active record...

 

da uma pesquisada, pq se for so pra sql eu nao acho necessidade de classe, mas se uma tabela estiver na responsabilidade de uma classe ae esta classe deve proveros metodos de crud, e suas regras de negocio...da uma pesquisada

 

http://pt.wikipedia.org/wiki/Active_record

Compartilhar este post


Link para o post
Compartilhar em outros sites
2- PDO eh forte, mas nem todos os hosts tem o pdo habilitado-sugestao utilize mysqli, eh nativo, habilitado e tem as mesmas funcoes de statements prepared

Errado. PHP é baseado em bibliotecas, como o C. MySQLi também é uma biblioteca externa, não é nativo da linguagem.

Caso o PDO não esteja habilitado, basta solicitar isso junto ao serviço de hospedagem, mesmo nas hospedagens compartilhadas, é possível fazer isso.

 

3-apesar de muita gente gostar do md5 h sites q conseguem descriptografar o md5, eu gosto de usar o hmac_hash, q me oferece mais opcoes de criptografia, eu gosto de usar nela o sha512, enquanto o md5 tem 32bits o sha512 tem 128bits.

MD5 é um hash, ou seja, é uma criptografia sem volta. Os sites que supostamente "quebram" o MD5 são baseados em banco de dados, pega-se a string, calcula-se o md5 e armazena-se esse par. Para "quebrar", basta procurar pelo hash e retornar a string original.

 

Quanto à sugestão do post #4, eu faria diferente.

Fica mais simples se você simplesmente utilizar uma Injeção de Dependências em conjunto com o padrão Adapter:

private function db(){
       $con = new PDO("mysql:host=localhost;dbname=teste", 
  	'root', '');
       return $con;    
       }

Remova essa função.

 

Adicione uma propriedade chamada adapter. No construtor, coloque:

public function __construct(AdapterAbstract $conn){
$this->adapter = $conn;
}

 

Aí você terá o seguinte conjunto de classes:

abstract class AdapterAbstract {
/**
    * Armazena as configurações do Adapter fornecidas pelo usuário
    * @var array
    */
protected $_config;

/**
    * Armazena a conexão com o banco de dados
    * @var null|resource|object
    */
protected $_connection;

/**
    * Construtor
    *
    * @param array $config : array de configuração de acesso ao banco de dados.
    * As configurações obrigatórias são:
    *
    * host			=> (string) o nome do servidor do banco de dados
    * username		=> (string) o nome do usuário do banco de dados
    * password		=> (string) a senha do usuário do banco de dados
    * dbname		=> (string) o nome do banco de dados desejado
    *
    * As configurações opcionais são:
    * port			=> (integer) a porta à qual se conectar [padrão 3306]
    * persistent	=> (boolean) indica se a conexão deve ser persistente [padrão false]
    */
public function __construct(array $config) {
	$this->_checkConfig($config);

	$this->_config = $config;
}

/**
    * Checa as configurações informadas pelo usuário
    * @param array $config
    * @return void
    * @throws Db_Exception
    */
protected function _checkConfig(array $config) {
	if(
		!array_key_exists('host', $config) ||
		!array_key_exists('username', $config) ||
		!array_key_exists('password', $config) ||
		!array_key_exists('dbname', $config)
	) {
		throw new Exception(sprintf('Estão faltando parâmetros de configuração para o Adapter "%s"', get_class($this)));
	}
}

/**
    * Retorna o objeto ou recurso de conexão com o banco de dados
    * @return object|resource|null
    */
public function getConnection() {
	$this->_connect();
	return $this->_connection;
}

/**
    * Retorna a configuração do Adapter
    * @return array;
    */
public function getConfig() {
	return $this->_config;
}

/**
    * Cria a conexão com o banco de dados
    * @return void
    */
abstract protected function _connect();

/**
    * Testa se a conexão com o banco de dados está aberta
    * @return boolean
    */
abstract public function isConnected();

/**
    * Fecha a conexão com o banco de dados
    * @return void;
    */
abstract public function disconnect();

/**
    * Prepara e executa um SQL statement com parâmetros associados
    * @param string|Db_Select $sql
	*/
abstract public function query($sql);

/**
    * Busca todas as linhas de retorno da consulta como um array sequencial
    * @param string|Db_Select $sql : um SQL Select Statement
    * @return array
    */
abstract public function fetchAll($sql);

   /**
    * Busca a primeira linha de retorno da consulta
    * @param string|Db_Select $sql : um SQL Select Statement
	*/
abstract public function fetchRow($sql);
}

class AdapterMysqlPdo extends AdapterAbstract {
// Implemente os métodos abstratos de AdapterAbstract utilizando PDO
}


class AdapterMysqli extends AdapterAbstract {
// Implemente os métodos abstratos de AdapterAbstract utilizando MySQLi
}


class AdapterPgsql extends AdapterAbstract {
// Implemente os métodos abstratos de AdapterAbstract utilizando o SGBD PostgreSQL
}

 

Quando for instanciar o login, faça:

$conn = new AdapterMysqlPdo(array('host' =>'localhost', 'user' => 'root', 'password' => '', 'dbname' => 'meu_bd'))
$login = new Login($conn);

 

Dentro de Login, utilize os métodos de interface (públicos) de AdapterAbstract para operações sobre o banco.

Se um dia você se deparar com algum servidor que não tem PDO habilitado e se recusa a habilitá-lo, você pode trocar para MySQLi simplesmente alterando esta linha:

$conn = new AdapterMysqli(array('host' =>'localhost', 'user'  => 'root', 'password' => '', 'dbname' => 'meu_bd'))

 

Se você tiver código PDO espalhado pelo seu código, aí sim você terá um problemão para fazer a alteração do SGBD

Compartilhar este post


Link para o post
Compartilhar em outros sites

Considerando o fato que você utiliza prepared statements e tirando a remota possibilidade de haver alguma senha cujo hash é um dos citados no artigo que o Evandro postou, não há problemas não.

 

Mas não desconsidere a possibilidade de fazer algo na linha do que te mostrei, pode parecer complicado e que não vale a pena, mas se um dia acontecer o que eu falei, você não precisará alterar TODAS as classes que fazem uso do banco de dados.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Caso o PDO não esteja habilitado, basta solicitar isso junto ao serviço de hospedagem, mesmo nas hospedagens compartilhadas, é possível fazer isso.

 

eu fiquei com a insite durante 3 anos e nunca habilitaram, e hj ela faz parte da uol host e mesmo assim nao habilitaram...enfim...eu nao coloquei tantas classes assim pra nao dizerem q eu estava a confundi-lo como da outra vez...mas...

 

 

aqui

private function db(){
       $con = new PDO("mysql:host=localhost;dbname=teste", 
       'root', '');
       return $con;    
       }

pq colocar aqui os dados do banco, e nao fazer um arquivo externo pra este tipode alteracao, como o zf?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo henrique eu antigamente estava usando esta classe:

defined('DSN') or define('DSN', 'mysql:host=localhost;dbname=teste');
defined('USUARIO') or define('USUARIO', 'root');
defined('SENHA') or define('SENHA', '');


class Conexao
{
private $_usuario;
private $_senha;
private $_dsn;

public function __construct()
{
	$this->defineUsuario(USUARIO);
	$this->defineSenha(SENHA);
	$this->defineDSN(DSN);	
	$this->abreConexao();
}
// Define o Usuário
public function defineUsuario($usuario)
{
	$this->_usuario = $usuario;
}
// Define a Senha		
public function defineSenha($senha)
{
	$this->_senha = $senha;
}
// Define o DSN		
public function defineDSN($dns)
{
	$this->_dsn = $dns;
}
// Abre a conexão sem retornar a mesma
public function abreConexao()
{
	$this->conexao = new PDO($this->_dsn, $this->_usuario, $this->_senha);
	$this->conexao->query("SET NAMES utf8");
}
// Fecha a conexao
public function fechaConexao()
{
	$this->_conexao = null;
}
}

e estava funcionando bem, tirando a parte de nao estar a conseguir chamala dentro das outras classes.

mas vou dar uma olhada e tentar implementar o seu codigo, parece ser melhor que este.

em questao ao hash eu alterei para wirpool, a diferença de tempo e milesimos de segundos, sera mais seguro que md5 certo amigo?

Compartilhar este post


Link para o post
Compartilhar em outros sites
em questao ao hash eu alterei para wirpool, a diferença de tempo e milesimos de segundos, sera mais seguro que md5 certo amigo?

Não vejo diferença entre a segurança. O que aconteceu é que encontraram lá alguns exemplos de colisão, nada tão alarmante.

Para alguém conseguir invadir seu sistema, precisa ter conhecimento do login de um dos usuários e ter a sorte de a senha dele ser alguma já manjada ou coincidir com um desses hashes que geram colisão.

 

E cá entre nós, alguém que possui esse tipo de conhecimento não vai ficar por aí tentando invadir seu sistema, vai querer invadir o site do FBI, do Itaú, do governo dos EUA.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.