Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
E aí gente, tudo bem?
Estou desenvolvendo um sistema para cadastro de esportes na escola onde trabalho.
Já está pronto... Mas eu acho que ainda falta um controle de flood, nem que seja de 30 segundos.
Eu de início pensei em um session com tempo limite e ia usar Session.TimeOut(uma que guardasse o IP).
Mas acredito que esse código sirva para todas as sessions, e no caso quero apenas uma durando pouco tempo.
Assim, talvez essa idéia seja viável, mas não sei como estipular o tempo de duração de UMA SÓ session.
Acho que inviabilizando o cadastro por 30 segundos ou 1 minuto já protege bastante.
Alguém sabe como posso fazer? Cookies talvez? Ou session mesmo? Ou algo mais?
Agradeço qualquer ajuda.
Giancarlo Braga
Olá Mário.
Obrigado pela resposta.
Olha, sim, irei cadastrar tudo em um DB no SQL Server.
Mas se fizer dessa forma como você disse precisaria de outra coluna correspondente a IP....pensando bem é viável.
Nesse caso, a cada inserção eu faço um SQL para verificar se o mesmo ip fez uma inserção naqueles segundos.
Só que isso envolve horário e horário pode mudar de sistema pra sistema, no entanto já ouvi que tem como pegar horário do servidor.
Como faço para usar horários do servidor e não do usuário?
Não tem como limitar o tempo de uma session em particular mesmo? rsrs
Abraços,
Giancarlo Braga.
mas em asp tudo é horario do servidor
javascript que é hora de usuario
Ah, certo!
Maravilha então.
Vou fazer uns testes com isso e depois posto o resultado aqui.
Obrigado pela ajuda.
Abraços,
Giancarlo Braga
positivo
qualquer coisa poste
Olá Mário.
Criei mais duas colunas no meu banco de dados, de ip e de hora.
Na de hora, uso uma função e ela coloca a hora nesse formato: hh:mm:ss
Agora meu código ficou assim:
'checando se não é flooder
'selecionando posts com o mesmo ip
sqlrs5 = "SELECT * FROM esportes WHERE (ip = '"& Session("ip")&"' ORDER BY hora DESC)"
Set rs5 = Server.CreateObject("ADODB.RecordSet")
rs5.Open sqlrs5, conexao, 3, 3
'se tiver mais que 1 registro com o mesmo ip...
If(rs5.RecordCount > 1) Then
'colocamos a hora do banco na variável 'horaop'
horaop = rs5("hora")
'e então verificamos se há diferença de 30 segundos
If( (pegahora - horaop) < 30) Then
Response.Write("deu certo, seu flooder")
End if
Wend
End If
Primeiro ele conecta ao banco.
Depois checa se o número de resultados é superior a 1.
Se for, a idéia é comparar através da diferença da hora atual a hora armazenada.
Mas..está dando erro:
Erro de tempo de execução do Microsoft VBScript (0x800A000D)
Tipos incompatíveis: '[string: "08:56:30"]'
E o erro é justamente na linha 84> If(pegahora - horaop > 30) Then
Você sabe como fazer a operação dar certo? Ou de repente inserir um tipo de dado pra HORA compatível com operações.
Outra dúvida é saber se devo usar while not rs5.EOF....rs5.movenext wend. Nesse caso acho que é necessário né?
Mas eu queria que ele checasse só o último...Como faço isso?
Agradeço qualquer ajuda. Valeu mesmo.
Abraços,
Giancarlo Braga.
você precisa usar a função dateadd
realmente pois calculo de hora creio que ñ funciona assim só com o dateadd, para melhor resultados
funcionar funciona mas tem que usar a data/hora e é melhor mesmo senao voce pode ter problemas caso o cara acesse em horarios proximos so que de dias diferentes, vai dizer qeu estar floodando mas nao estará
Eu andei lendo sobre essas funções de data ... e realmente há esse problema de dias diferentes que o Mário citou.
Mas depois de muita insistência e pensamento, eu acabei conseguindo implementar esse controle de flood de 1 minuto em 1 minuto.
Fiz uso de split em cima da hora atual usando a função que citei e da hora armazenada no banco. E depois, checa-se se a inserção e o primeiro dos dados a serem exibidos(ORDER by xxx DESC) são do mesmo minuto. Se forem no mesmo minuto e mesmo IP é um possível flood.
Foi algo como split(horaatual, 4, 7) e split(horabanco, 4, 7), considerando que a hora está no formato hh:mm:ss ele pega e armazena o minuto....então bastou comparar...
Assim funcionou perfeitamente o controle de flood, 30 segundos além do que eu precisava, mas melhor do que nada.
O que vocês acham dessa resolução?
Se gostarem eu posso de repente postar em alguma seção daqui do fórum para que possa ajudar alguém posteriormente.
Não devo ser o único que precisou desse controle de flood até hoje, rsrs.
O único problema do algoritmo usando a função split é que não funciona bem com segundos, apenas minutos.
Abraço.
funciona quase sempre mas quando se acessar no mesmo horario de dias diferentes vai pedir para esperar sem ser realmente necessario
Tem razão.
Mesmo horário, dias diferentes, com IP fixo. É um pouco difícil de dar esse bug mas pode acontecer sim.
Ainda bem que o sistema é algo de média escala, mais pra baixa. Não vai ter gente dia inteiro todos os dias entrando.
Serão apenas pais cadastrando os filhos nos esportes e outras atividades culturais, com limite de 3 por cada.
Mas ainda sim dá pra resolver!
Tenho coluna de data também. Se eu mandar um AND e analisar se a data é igual aí não tem perigo.
Que acha?
ai fica ok
Bacana!
Problema resolvido então.
Vou postar amanhã o código da resolução aqui.
Aonde mais no fórum você sugere para eu divulgar essa resolução?
Acho que de certa forma pode ser útil ainda um dia para alguém.
Abraços,
Giancarlo Braga.
ponha o code aqui mesmo
Algoritmo:
1 - Verifica se há mais de um registro do mesmo usuário(checa IP e data).
2 - Se houver mais de um registro localizado, ele pega hora, mês e ano atual e do banco de dados.
3 - Depois verifica se o post atual é da mesma hoa e do mesma dia, mês, ano, e se for, cria uma session que vai dar uma mensagem de erro por flood na index e depois redireciona para essa index, que terá tratamento contra esse flood.
4 - É bom TAMBÉM verificar o dia, mês e ano porque se as pessoas tentarem acessar no mesmo minuto em dias, meses ou anos diferentes receberiam a mensagem de flood sem estarem floodando.
OBS: Você precisa de um banco com tabelas com pelo menos as colunas 'data', 'hora', 'ip'. Tudo formato texto, char, varchar, como preferirem.
OBS2: A função que usei para pegar a HORA no formato hh:mm:ss foi:
Function pegahora()
hora = hour(now)
minutos = minute(now)
segundos =second(now)
if len(hora) = 1 or hora < 10 or hora = 0 then
hora = "0" + CStr(hora)
end if
if len(minutos) = 1 or minutos < 10 then
minutos = "0" + CStr(minutos)
end if
if len(segundos) = 1 or segundos < 10 then
segundos = "0" + CStr(segundos)
end if
pegahora = CStr(hora) + ":" + CStr(minutos) + ":" + CStr(segundos)
End Function
Essa aí é só usar 'pegahora' normal, como se fosse variável, que ele retorna a hora. ;)
Agora vem o código anti-flood:
<%
sqlrs5 = "SELECT * FROM esportes WHERE (ip = '"& Session("ip") &"') AND (data = '"& date() &"') ORDER BY hora DESC"
Set rs5 = Server.CreateObject("ADODB.RecordSet")
rs5.Open sqlrs5, conexao, 3, 3
'se tiver mais que 1 registro com o mesmo ip...
If(rs5.RecordCount > 1) Then
horaatual = pegahora 'pega hora atual
horagravada = rs5("hora") 'pega hora do banco
dataatual = date() 'pega data atual
datagravada = rs5("data") 'pega data do banco
'usando função mid
diaop = mid(dataatual, 1, 2)
diaat = mid(datagravada, 1, 2)
mesop = mid(dataatual, 4, 2)
mesap = mid(datagravada, 4, 2)
anoop = mid(dataatual, 7, 4)
anoat = mid(datagravada, 7, 4)
minutoop = mid(horaatual, 4, 2) 'separa 2 itens a partir do item 4, portanto o minuto.
minutoat = mid(horagravada, 4, 2) 'idem
'Então, basta verificar se a submissão e a hora a ser gravada pertencem ao mesmo minuto
'Se pertencer, uma mensagem é mostrada e o usuário é direcionado ao index.
If(minutoop = minutoat AND diaop = diaat AND mesop = mesat AND anoop = anoat) Then
inicial = "../index.asp"
Session("flood") = 1
Response.Redirect(inicial)
End if'fim do if de checagem de numero minimo de registros
End if'fim do if que checa a igualdade dos minutos: atual e registro
%>
Percebam o código SQL usado para selecionar. Precisamos selecionar dia e ip, e então ordenar decrescentemente pela hora, para então puxarmos sempre o primeiro registro. Como se o banco fosse uma 'pilha' que no seu topo sempre tivesse o cadastro mais atual.
Obrgado por compartilhar a sua solução
voce cadastrará em um DB? aramzena a data/hora e quando for inserir outro testa se ja passou o prazo minimo