Login do usuário
Pesquisa no site
Assine o RSS do Drupal-BR
Download
Itens ativos
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?
- Se logue ou se registre para poder enviar comentários
- 2098 leituras



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
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.
$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:
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.
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
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
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.
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
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.
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:
{
$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
{
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 =)
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
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:
{
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.
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
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:
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 =)