• Cadastro
  • Fóruns
  • Manual
  • Tradução
  • Tutoriais
  • OpenAtrium
  • Eventos
  • Ofertas de Emprego
  • DBR
Início

Login do usuário

  • Criar uma conta
  • Recuperar senha

Pesquisa no site

Google

Assine o RSS do Drupal-BR

RSS dos itens mais ativos

RSS conteúdo página inicial

RSS de todo conteúdo

RSS dos comentários

Lista de Discussão

Drupal-BR

Lista de Mantenedores

DBR Maintainers

Download

Últimas versões

Drupal 7.22Drupal 6.28

Contribuições

Módulos Temas Tradução

Itens ativos

  • layout com varias divs
  • Dúvidas sobre permissões
  • Filtro com campo relacionado ao usuário logado
  • Importar dados do Banco de Dados
  • Sugestão de tema
  • Publicação de site
  • Webforms
  • Cópia local de Site Drupal
  • Filtro com campo relacionado ao usuário logado
  • Escolha de servidor para Simplenews
Veja mais
Início » Fórum » Suporte » Drupal

Drupal reconhece login de outros sistemas?

Eu tenho um sistema pronto com banco de dados de usuários e tudo e um outro site todo feito em drupal. Eu gostaria de saber como eu posso fazer pra um usuário logado no meu sistema (que não tem nada a ver com drupal) automaticamente ser reconhecido no site (que foi feito no drupal). Tenho que criar algum módulo pra isso? Seria perfeito se eu pudesse criar uma variável de sessão comum aos dois para fazer login.

Eu já criei um módulo de autenticação que permite ao drupal reconhecer o meu banco de dados de usuário e fazer o login isso foi até fácil de fazer com o hook_auth. Mas ainda assim os usuários precisam se autenticar 2x.

Alguém aí teria uma idéia de como eu posso fazer o usuário logar apenas uma vez e ser reconhecido nos 2 sistemas?

‹ Qual modulo utiliza... Gerar automaticamente um site profile ›
Enviado por bilongs em sex, 01/02/2008 - 10:30
  • Drupal
  • Se logue ou se registre para poder enviar comentários
  • 2098 leituras
Em sex, 01/02/2008 - 12:38 rafael disse:

Olá bilongs,

Talvez com algumas mexidas no seu hook_auth seja possível melhorar isso.
Por padrão o Drupal guarda o ID da sessão em uma tabela sessions. É por lá que ele controla se o usuário com aquela sessão está logado ou não. Talvez seja por aí o que você terá que mexer. Só estou dando um palpite, uma vez que nunca fiz isso.

Abraço

--
Rafael Ferreira Silva
http://www.rafaelsilva.net

  • Se logue ou se registre para poder enviar comentários
Em qua, 13/02/2008 - 10:06 bilongs disse:

Percebi que quando agente preeche usuário e senha em 'drupal/user' o formulário é submetido pra ele mesmo 'drupal/user' usando o método POST. Que vai fazer toda a validação, criação de sessão, permissões etc.

Então adaptei um código que tem na documentação do php que cria as variáveis, o cabeçalho POST, e submete a uma página como se o usuário tivesse preenchido um formulário e depois clicado no botão login.

        $usuario = 'root';//este é o usuario administrador da minha instalação
        $senha = 'teste'; //esta é a 'senha' do administrador correta
        $postdata = http_build_query(
            array(
                'name' => $usuario,
                'pass' => $senha,
                'form_id' => 'user_login',                                                     
                'op' => 'Login'
            )
        );
       
        print_r($postdata);// só pra visualizar o array criado acima
       
        $opts = array('http' =>
            array(
                'method'  => 'POST',
                'header'  => 'Content-type: application/x-www-form-urlencoded',
                'content' => $postdata
            )
        );
       
        $context  = stream_context_create($opts);
       
        $result = file_get_contents('http://localhost/drupal/user', false, $context);
        echo $result;

As variáveis name, pass, form_id, op são as variáveis que o drupal envia quando agente preeche login e senha em 'drupal/user'. Eu gostaria de saber por que o código acima não funciona no drupal? Se vc comentar a linha:

'name' => $usuario
vai perceber que aparece a mensagem de erro no formulário dizendo que falta o login e a senha. Ou seja, teoricamente ele funciona.

Eu adicionei este código em um módulo de autenticacao que eu criei. E chamei ele dentro de

drupal/includes/common.inc
no método drupal_access_denied()

pra quando o drupal tentar negar acesso ao usuário ele primeiro verificar se no meu sistema ele já está logado.

Poxa eu já varri todo o google atras dessa solução mas parece que ninguém sabe.
Perdoem a minha burrice mas eu uso o drupal a 3 semanas. 2 Só tentando fazer ele logar automaticamente.

  • Se logue ou se registre para poder enviar comentários
Em qua, 13/02/2008 - 17:01 pedrofaria disse:

ao invez de fazer assim, nao seria mais facil vc dar uma olhada como o drupal faz para logar e usar o mesmo esquema?

IMAGINO que se voce usar estas duas funcoes deve funcionar

$user = user_authenticate($name, trim($pass));
if (!$user->uid) { NAO LOGOU }
sess_regenerate();

flw!

--
Pedro Faria de Miranda Pinto
http://www.eusouopedro.com
http://www.phpavancado.net
Bate Papo sobre Drupal? irc://irc.freenode.net/drupal-br

  • Se logue ou se registre para poder enviar comentários
Em qui, 14/02/2008 - 17:20 bilongs disse:

O drupal agora reconhece o login de outro sistema automaticamente.
Muito obrigado ao Rafael e ao Pedro pela força misturei a dica dos dois e funcionou.

  • Se logue ou se registre para poder enviar comentários
Em qui, 14/02/2008 - 22:35 pedrofaria disse:

Boa cara...

Agora vc poderia mostrar a solução para todos... :)

flw!

--
Pedro Faria de Miranda Pinto
http://www.eusouopedro.com
http://www.phpavancado.net
Bate Papo sobre Drupal? irc://irc.freenode.net/drupal-br

  • Se logue ou se registre para poder enviar comentários
Em sex, 15/02/2008 - 12:00 bilongs disse:

A única maneira que eu achei para poder fazer isso foi alterando o núcleo do drupal. Numa futura atualização vai ter que ser alterado de novo. Por isso tentei alterar o mínimo possível. Se alguém por acaso souber como eu poderia pegar o "acesso negado" do drupal usando um hook e puder postar aqui eu agradeço.

No arquivo drupal/includes/common.inc existe um método chamado drupal_access_denied()
Eu adicionei uma linha nele pra chamar o meu método que faz a autenticação automática. A idéia é basicamente esta:
Se o usuário tentar acessar uma parte restrita do drupal ele tera acesso negado. Mas antes de negar acesso eu verifico se é possível autenticar automaticamente baseado no login e senha previamente salvos de uma sessão qualquer.

function drupal_access_denied() {

        autenticacao_automatica(USERNAME, PASSWORD);
...
...
...
}

autenticacao_automatica(USERNAME, PASSWORD) - é o nome do método que está dentro do meu módulo chamado de autenticacao.

USERNAME e PASSWORD - constantes com o nome de usuário e senha do meu sistema que eu capturei usando variável de sessão. Só a título de curiosidade para usar a variável de sessão de outro sistema a sessão teve que ser iniciada [session_start()] e depois destruida [session_destroy()] antes do arquivo drupal/includes/bootstrap.inc entrar em ação, o que acontece no arquivo index.php do drupal. Depois que o drupal inicia a sesão dele qualquer outra sessão desaparece =/.

abaixo está o método que autentica automaticamente dentro do meu módulo drupal/modules/autenticacao.module:

function autenticacao_automatica($username, $password)
{
        $user = user_authenticate($username, trim($password)); 
       
        if ($user->uid)
        {
                sess_regenerate();
                header("Location: http://".$_SERVER['HTTP_HOST']."/drupal/user/".$user->uid);exit;
        }
}

Se o usuário for reconhecido é redirecionado pra página inicial de usuário que é mais ou menos assim:
http://localhost/drupal/user/1
que eu defini no header();

Se não for reconhecido a execução volta para o método drupal_access_denied() que vai negar o acesso ao usuário que não está autenticado.

 

Curiosidades:

O metodo autenticacao_automatica($username, $password) só faz autenticar o usuário. Como o meu banco de dados de usuário não está dentro do banco do drupal foi necessário criar o hook_auth que faz a validação de usuário e senha de fora do drupal em drupal/modules/autenticacao.module

function autenticacao_auth($username, $password, $server)
{
        db_set_active('meu_banco_de_dados');//seleciona a minha base (que não é a do drupal)
        $sql = "SELECT login, senha
                        FROM usuario
                        WHERE login = '$username' AND senha = '"
.base64_encode($password)."'";
       
        $consulta = db_query($sql);
        db_set_active('default'); //retorna para a base padrão (drupal)
       
        if(db_fetch_array($consulta)) return true;
        else return false;
}

Para o drupal reconhecer um banco de dados diferente do padrão é necessário adicionar uma linha em:
drupal/sites/default/settings.php

$db_url['meu_banco_de_dados'] = 'mysql://usuario_do_meu_banco_de_dados@localhost/meu_banco_de_dados';

 

Foi essa a solução que eu encontrei espero que seja útil a alguém. Sugestões para melhorar o código são bem vindas =)

  • Se logue ou se registre para poder enviar comentários
Em sex, 15/02/2008 - 12:51 pedrofaria disse:

Então... sou totalmente contra mexer no nucleo do drupal...

Tente com o hook_init... flw!

--
Pedro Faria de Miranda Pinto
http://www.eusouopedro.com
http://www.phpavancado.net
Bate Papo sobre Drupal? irc://irc.freenode.net/drupal-br

  • Se logue ou se registre para poder enviar comentários
Em sex, 15/02/2008 - 15:11 bilongs disse:

Eu também não gosto de mecher no núcleo de nada. Vale apena só pelo aprendizado que agente adquire. Mas ainda não vejo como o hook_init pode ajudar neste caso. Este hook realmente seria uma mão na roda se o drupal a esta altura não tivesse destruído todas as sessões e criado a dele. Quando o hook_init é carregado apesar de o drupal ainda estar em bootstrap a sessão dele já foi criada.

experimente fazer isto no seu módulo:

function meuModulo_init()
{
    print_r($_SESSION);
    die('<br>imprimindo sessão no hook_init');
}

Você vai perceber que qualquer sessão criada anteriormente agora está vazia, ou seja, os dados de login do meu sistema já foram perdidos.

A modificação que eu fiz no núcleo foi adicionar 1 linha em drupal_access_denied(). Para eu poder fazer o login automático sem esta modificação eu precisaria interceptar este método e eu desconheço um hook que faça isso.

Perdoe se eu não compreendi a sua idéia.
aceito críticas e sugestões.

  • Se logue ou se registre para poder enviar comentários
Em sab, 16/02/2008 - 23:11 pedrofaria disse:

realmente faz sentido sua colocação...

Já vi gente usando o hook_menu para coisas do tipo também... lembre-se de fazer estas coisas qdo o parametro $may_cache for FALSE... ou seja.... provavelmente vai ficar no ELSE do if ($may_cache)... Lógicamente, se vc estiver usando o padrão...

Flw!

--
Pedro Faria de Miranda Pinto
http://www.eusouopedro.com
http://www.phpavancado.net
Bate Papo sobre Drupal? irc://irc.freenode.net/drupal-br

  • Se logue ou se registre para poder enviar comentários
Em qua, 20/02/2008 - 10:09 bilongs disse:

Tirei qualquer modificação que eu fiz no código do drupal.
No arquivo index.php antes de qualquer código que inicie o drupal eu peguei login e senha usando variável de sessão do outro sistema:

<?
if(!defined("USERNAME") || !defined("PASSWORD"))
{
        session_start();
        if(isset($_SESSION['username'], $_SESSION['password']))
        {
                //criando constantes com nome de usuário e senha
                define("USERNAME", $_SESSION['username']);
                define("PASSWORD", $_SESSION['password']);
        }
//      usar o sesseion_write_close() faz o login parar de funcionar
        session_destroy(); //tem que ser usada esta para o drupal funcionar corretamente
}
...
//codigo do drupal...
...

depois disso eu criei um modulo de autenticacação que valida os logins do meu outro sistema e autentica o usuário automaticamente.
http://drupal-br.org/criando-sua-propria-autenticacao-do-drupal ensina a fazer sua própria autenticação no drupal.

o código do meu módulo chamado de autenticacao ficou assim:

//esta função é só um exemplo que pode ser modificado para a necessidade de cada um
function autenticacao_auth($username, $password, $server)
{
        //seleciona o banco de dados do meu sistema
        db_set_active('meu_banco_diferente_do_drupal');
        $sql = "SELECT login, senha
                        FROM usuario
                        WHERE login = '$username' AND senha = '"
.base64_encode($password)."'";
       
        $consulta = db_query($sql);
        db_set_active('default');//volta para o banco de dados do drupal
       
        if(db_fetch_array($consulta)) return true;
        else return false;
}

//função que verifica se o usuário que entrou no site está logado em outro sistema
function autenticacao_init()
{
        global $user;
       
        $username = USERNAME;//Declarei esta constante em index.php
        $password = PASSWORD;//Declarei esta constante em index.php
       
        if(!$user->uid)
        autenticacao_usuario(USERNAME, PASSWORD);
}

//funcão que faz o login automático do usuário que já veio logado do outro sistema
function autenticacao_usuario($username, $password)
{
        $user = user_authenticate($username, trim($password)); 
        if ($user->uid) sess_regenerate();
}

Pronto! Tudo feito sem modificar nada dentro no núcleo do drupal =).
index.php foi modificado sim mas sem mecher no tal do 'core' do drupal.
A novidade é que usando o hook_init o usuário é logado bastando entrar no site do drupal. Não precisa mais chegar em acesso negado para o drupal ver que tem que logar o cara.

Vale lembrar que eu usei uma base de dados diferente do drupal então tem que configurar a nova base em
drupal/site/default/settings.php http://drupal.org/node/18429

Novas críticas e sugestões são bem vindas. Por causa delas já melhorei 200% esse código =)

  • Se logue ou se registre para poder enviar comentários

Este site é feito, orgulhosamente, com Drupal. Gentilmente hospedado por HostSH