Impedir Login em Duplicidade

Delphi

27/07/2005

No meu sistema faço o controle manual do acesso de cada usuário a cada módulo. Atribuo níveis de acesso e só permito que um usuário acesse determinado módulo se o usuário administrador lhe concedeu autorização para isso. Guardo os dados de cada usuário em uma tabela.
Até aqui tudo certo.
Minha dúvida: preciso fazer uma rotina para impedir que um mesmo usuário se logue duas vezes. Por exemplo, o usuário X acessa o programa no servidor e, sem efetuar o logoff, se loga também na estação. Pensei em criar um campo - Logado - na tabela de usuários e gravar o log ali e, quando fizer o logoff ou sair do programa, liberar o acesso daquele usuário novamente. Seria o ideal. O problema é se ocorre um desligamento inesperado do micro - uma queda de energia por exemplo. O sistema não faria a liberação daquele usuário e ele não poderia mais se conectar no programa.

Alguém tem alguma idéia de como eu poderia fazer isso?
Obrigado.


Valdirdill

Valdirdill

Curtidas 0

Respostas

Rjun

Rjun

27/07/2005

Poderia ter uma tabela em que o sistema registrasse o usuario logado. Quando o sistema fechasse ele apagaria esse registro. Caso caia a energia, na próxima inicialização do sistema ele verificaria que existe um usuário logado e apagaria o registro liberando o usuário.


GOSTEI 0
Valdirdill

Valdirdill

27/07/2005

Não funciona.
E se o usuário se logar no servidor e, sem sair do programa, for numa estação e tentar se logar.
Por essa sua sugestão, quando o usuário tentasse se logar na estação, o sistema apagaria e liberaria para ele entrar novamente.
Entendeu?


GOSTEI 0
Rjun

Rjun

27/07/2005

A sugestão que dei foi para complementar a sua. Se ele estivesse logado no servidor não conseguiria logar em outra máquina.

1. Ele se loga no servidor. A aplicação registraria que ele o usuario ZÉ se logou e também registraria no login ZÉ que ele esta conectado.

2. Quando o usuário tentasse se logar em outra máquina o login dele estaria bloqueado.

3. Somente quando o usuário desligasse a aplicação em que ele está logado, na finalização da aplicação ela faria o registro de que naquela máquina ninguem está registrado e também liberaria o login do ZÉ.

4. Se caisse a luz, quando a maquina fosse reinicializa, ela verificaria que o ultimo usuario nao se deslogou e faria as liberações.


GOSTEI 0
Valdirdill

Valdirdill

27/07/2005

Obrigado RJun. Desculpe a minha ignorância, mas não estou conseguindo fazer a rotina que vc sugere.

Vamos a um exemplo mais prático:

1) Quando o usuário Zé acessar o programa no serivdor, atribuo ´S´ para o campo LOGADO na tabela de cadastro de usuários.

2) Se ele tentar acessar o programa na estação, verifico que o campo LOGADO do BD está como ´S´ e não permito que acesse. No servidor ele não vai conseguir se conectar de novo, pois o programa não abre mais de uma vez simultaneamente na mesma máquina;

2) Quando o Zé sair do sistema no servidor, atribuo ´N´ parar o campo LOGADO. Agora, se ele for na estação e tentar acessar o programa, vai conseguir. Normal. Até aqui tudo certo, né?;

É assim que eu tinha feito.
Como eu diferencio, no passo 2 acima, se o campo LOGADO do registro Zé está como ´S´ porque o Zé ainda não saiu ou porque a energia havia caído?


Obrigado.


GOSTEI 0
Rjun

Rjun

27/07/2005

Nesse ponto acho que você deveria ter mais uma coluna na tabela de usuário, com o nome da maquina. Quando o usuario logasse colocaria ´S´ no campo logado e preencheria o campo MAQUINA com o nome da máquina. Quando o usuário se deslogar, coloca ´N´ e apaga o nome da máquina. Se cair a energia, quando a aplicação for reinicializada, ela varre a tabela de usuário e verifica se o nome da maquina esta em algum registro. Se estiver ela apagar o nome da máquina e altera o estado para ´N´.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

valdirdill eu estou com o mesmo problema seu !!!!

Eu pensei em fazer assim:
assim que o usuario logar o nome do mesmo sera gravado em uma variavel, assim antes de logar o sistema iria ´conversar´ com todas outras estaçoes perguntando o valor da variavel que esta armazenado o nome do usuario ai caso alguma extaçao tenha a variavel com o mesmo nome de usuario o logon nao sera feito caso contrario sera logado normal isso tudo usando sockets (so que nao sei usar estou procurando material), assim evitaria o problema do usuario ficar logado no banco de dados em caso de queda de energia etc....


o q vc´s acham ??????

acho que o unico problema é que nao sei usar os sockets (Espero que vc´s saibam :D )


GOSTEI 0
Fabio Nascimento

Fabio Nascimento

27/07/2005

valdirdill, a sua idéia é perfeita, faça desse jeito.

Não é possível prever uma queda de energia, e com certeza, aonde o seu sistema está funcionando, alguém tem que ter um login com provilégios de ´admin´.

Caso haja uma queda de energia, como isso é uma excepcionalidade, algo que com certeza não vai acontecer com frequencia, esse ´admin´, terá poderes para apagar o registro que vai estar bloqueando o acesso de quem estava logado no momento da queda.

Logo, apenas adicione um usuário que possa logar sem restrições e que possa alterar os registros dessa tabela que controla os acessos.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

cara eu particularmente nao gosto de tratar isso em uma tabela nao pois ja passei muita raiva :x usando dessa maneira, ainda prefiro aprender usar os sockets para fazer como disse !!!!!!


Mais estamos aki para achar uma forma de fazer isso !!!!!! Vao postando suas ideias :idea: !!!!!!


GOSTEI 0
Beppe

Beppe

27/07/2005

Não vejo problemas disso ser feito com um campo numa tabela. Pode ser um timestamp, com isso dá pra estimular um timeout.

Com sockets é meio inviável, ao menos dá mais trabalho, pois ainda é preciso saber quem se logou.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

mais trabalhoso é sim !!!!!!

sei temos q usar alguma campo a caso o sistema ´caia´ ele fique totalmente em banco novamente !!!! nao sei si estou certo pois nunca usei mais acho q um campo calculado faz isso ne ???????


GOSTEI 0
Beppe

Beppe

27/07/2005

mais trabalhoso é sim !!!!!! sei temos q usar alguma campo a caso o sistema ´caia´ ele fique totalmente em banco novamente !!!! nao sei si estou certo pois nunca usei mais acho q um campo calculado faz isso ne ???????

Campo calculado não é pra isso, mas a idéia é boa sim. Com n-camadas dá pra implementar isso, mas de forma geral, ao se conectar ao banco deve ser feito up UPDATE que limpasse os campos.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

pode ser um campo ´virtual´ ou algo parecido !!!!


GOSTEI 0
Beppe

Beppe

27/07/2005

pode ser um campo ´virtual´ ou algo parecido !!!!

E como vc iria indicar que um usuário se logou?


GOSTEI 0
Guilherme

Guilherme

27/07/2005

no sistema q uso esse tipo de logon pela tabela um faço assim :

eu bloqueio nos edit o uso do coringa ´´¬´´ (uso ib)
ai eu coloco um ibdataset (aba interbase)
coloco o seguinte comando no ibdataset

select cod,usuario,senha,conectado,permicoes from funcionarios
where
usuario = :usuario and
senha = :senha


ai no botao logar coloco assim :
begin
ibdataset1.close;
ibdataset1.parambyname(´usuario´).asstring:=edit1.text;
ibdataset1.parambyname(´senha´).asstring:=edit2.text;
ibdataset.open;
if tbdataset1.count = 1 then begin 
//mostra tela e aplica permiçoes 
ibdatasetconectado.value:=´S´;
end else 
//tratamento
end;


e no onclose do mainform assim :
ibdatasetconectado.value:=´N´;


pois o usuario ja esta localizado !!!!!!

:arrow: é +- isso ai pq fiz sem olhar na aplicaçao !!!!!![/code]


GOSTEI 0
Beppe

Beppe

27/07/2005

Campos calculados(tanto em SQL como em Delphi), só são visíveis pra quem chamou uma query, isto é, cada cliente tem seus dados independentes.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

intao vc tem uma soluçao ?????


GOSTEI 0
Beppe

Beppe

27/07/2005

Em vez de campo calculado, use um campo real. No caso do servidor cair, um rollback será dado automaticamente, o que acabaria ´desconectando´ o usuário.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

vo fazer o teste aki vamos ver !!!!!


me add ai no msn !!!!!!

ta na assinatura !!!


GOSTEI 0
Guilherme

Guilherme

27/07/2005

ai cara fiz um pequeno exemplo aki com o campo do tipo real i ai como q faz agora esse rollback hora q o servidor kai ????


GOSTEI 0
Fabio Nascimento

Fabio Nascimento

27/07/2005

ai cara fiz um pequeno exemplo aki com o campo do tipo real i ai como q faz agora esse rollback hora q o servidor kai ????


Cara, rollback só defaz as transações que ainda não foram comitadas no banco, ou seja, ainda estão em cache.

Se as transações ainda estão em cache, elas não podem ser visualizadas pelos outros ´clientes´, a menos que você trabalhe com nível de transação ReadUncommitted, mas aí todo o seu banco vai trabalhar assim, e isso pode ser prejudicial ao seu sistema.

Não reinvente a roda, crie um login de administração, que possa logar sem restrições, para resolver este tipo de problema, que como eu já disse, é muito raro de acontecer.

Só lembrando que TODO sistema possui um usuário de administração, isso é um procedimento padrão, o Windows tem o Admin, o linux tem o root, porque o seu não pode ter?

t+


GOSTEI 0
Guilherme

Guilherme

27/07/2005

é cara so que é assim :

apos salvar eu tenho q dar um ´Transacao.CommitRetaining´ para salvar no banco de dados si nao o usuario nao ficaria conectado para as outras estaçoes assim sa estaria salvo e ACHO q nao tem como dar um rollback intao !!!!!!

agora qto ao adminitrador ja tem no meu sistema so q onde ele roda so trabalha mulher e elas achan dificil fazer isso o q me leva ir la direto ou por causa de queda de energia ou travamento do pc !!!!

pelo mesmos to no meio da mulherada direto !!!! heheheheheheh

vamos dar um jeito nisso !!!!!!!


GOSTEI 0
Fabio Nascimento

Fabio Nascimento

27/07/2005

é cara so que é assim : apos salvar eu tenho q dar um ´Transacao.CommitRetaining´ para salvar no banco de dados si nao o usuario nao ficaria conectado para as outras estaçoes assim sa estaria salvo e ACHO q nao tem como dar um rollback intao !!!!!! agora qto ao adminitrador ja tem no meu sistema so q onde ele roda so trabalha mulher e elas achan dificil fazer isso o q me leva ir la direto ou por causa de queda de energia ou travamento do pc !!!! pelo mesmos to no meio da mulherada direto !!!! heheheheheheh vamos dar um jeito nisso !!!!!!!


Se elas acham difícil, é porque está difícil.

Faça um form amigável, com bastante informação, para que seja necessário apenas algums cliques.

Por exemplo, coloque um botão que apenas o admin pode ver com o nome ´USUÁRIOS LOGADOS´, clicando nesse botão, voce mostra em um grid todos os usuários que estão logado no sistema, e disponibiliza um botão ´EXCLUIR USUÁRIO DA LISTA´.

Se a mulher achar isso difícil, manda ela procura emprego num zoológico, que ela é uma anta hehe :twisted:


GOSTEI 0
Eniorm

Eniorm

27/07/2005

Ae galera, eu tenho uma idéia que acredito resolveria isso, mas nem imagino como implementar essa ideia.

Se o controle de verificar e impedir o acesso fosse feito pelo banco, atraves de triggers ou sei la oq, será que não resolveria?

Eu um tempo atrás estava em busca de algo para controlar o número de acesso ao banco, tipo, o cliente comprasse 10 copias, somente 10 maquinas poderiam acessar o banco, isso certamente teria que ser feito no banco e não no programa.

Acho uma ideia boa, mas não sei como fazer, talvez aqui alguem saiba.
Deixar que o banco cuide disso, controlar um usuário conectado e impedir que o mesmo usuário se conecte em outro terminal;

Abraços,


GOSTEI 0
Guilherme

Guilherme

27/07/2005

é mto mais facil



é so um button q varre toda tabela colocando tudo como ´N´

elas achan q o problema é com o prog nao intende q é pq o sitema fexo inadequadamente acha q é minha obrigaçao ir la arruma !!!!


GOSTEI 0
Ivanh

Ivanh

27/07/2005

pq vc não usa UDP , da paleta Indy?
é barbada de controlar esses acessos
cria um app que gerencia todos os conectados
qdo um programa roda manda um comando UDP dizendo ´usuarioquerentrar´, por exemplo, então seu app login percorre a lista de usuarios se ja encontrar o usuario na lista, pode perguntar via UDP, ´vc ainda esta ai´, caso nao tenha resposta, vc libera, +-isso é só botar a mão na massa...


GOSTEI 0
Guilherme

Guilherme

27/07/2005

vc nao tem um exemplo de como usar isso nao ????


GOSTEI 0
Ivanh

Ivanh

27/07/2005

é só botar a mão na massa...


indy tem exemplos de uso de UDP


GOSTEI 0
Guilherme

Guilherme

27/07/2005

nao sei porq mais meu delphi nao instalo os DEMOS
c:\arquivos de programas\borland\delphi7\ nao tem a demos !!!!


GOSTEI 0
Beppe

Beppe

27/07/2005

gborges_13, quando o servidor cai, os dados em cache naum são comitados, por isso o rollback é automático, vc não precisa fazer mais nada quanto a isso.


GOSTEI 0
Guilherme

Guilherme

27/07/2005

cara so ke caso de a energia cair é mto dificil a maioria das vezes o q acontece é o computador travar !!!!!!


GOSTEI 0
Rjun

Rjun

27/07/2005

Os exemplos dos componentes Indy podem ser baixados em http://www.indyproject.org/


GOSTEI 0
POSTAR