Kelver Merlotti apresenta sobre segurança, performance e responsividade em sistemas robustos com Datasnap Avançado. Ele discute autenticação, autorização e filtros de transporte para segurança, caching, filtros REST e callbacks para melhorar performance e responsividade.
2. Kelver Merlotti
• Embarcadero MVP
• Coordenador editorial da Active Delphi
• Consultor independente
• Especialista em N-Tier e Mobile
• Trabalha com Delphi há +15 anos
• Contatos
• Email: kmerlotti@gmail.com
• Twitter: @kmerlotti
• Facebook: http://fb.com/kmerlotti2
3. Vamos falar sobre…
• Segurança com
Authentication;
Authorization; e
Transport Filters
• Performance com
Caching;
Rest Filters; e
• Responsidivade with
Callbacks
3
5. Diferença
• Authentication acontece quando “alguém” tenta acessar o servidor,
enquanto Authorization acontece quando “alguém” já logado em seu
servidor tenta usar algo dele. Dito isso:
• Não há como autorizar alguém ainda não autenticado
• Se está autenticado, ainda poderá não estar autorizado a fazer algo
5
6. Como autenticar
• TDSAuthenticationManager.onAuthenticate, que nos dá informações
como:
• O Protocolo sendo utilizado: http, https ou tcp
• O contexto sendo utilizado (http://server:port/context/something)
• O Usuário e Senha sendo utilizados
• Após testar as credenciais você pode decidir se a operação é válida ou não
e adicionar alguns papéis (roles) ao usuário que está se autenticando.
• Este papéis serão úteis logo mais, quando precisar decidir o que este
usuário pode ou não fazer.
6
7. Como autorizar
• Existem 3 formas de aprovar/rejeitar uma tentativa de executar algo em
seu servidor:
• Usando o atributo TRoleAuth em classes e métodos
• Menos flexível, mas requer praticamente nenhum código
• Usando a coleção TDSAuthenticationManager.Roles
• Útil com DataSetProvider’s e com muitas roles/profiles
• Pode requerer mais código
• Usando o evento TDSAuthenticationManager.onAuthorize
• Mais flexível, 100% codificado
• Importante: TDSAuthManager.Roles sobrescreverá qualquer atributo TRoleAuth!7
9. Mais sobre Authentication e Authorization
• Authentication and Authorization (DocWiki)
• http://docwiki.embarcadero.com/RADStudio/Seattle/en/Authentication_and_Authorization
• Secure DataSnap Development (CodeRage 8 Session Replay)
• http://www.youtube.com/watch?v=X1CW9A1bCzk
• Delphi Labs: DataSnap XE - Authentication and Authorization
• http://edn.embarcadero.com/article/41267
• Authentication and Authorization with DataSnap and REST
• https://mathewdelong.wordpress.com/2010/09/12/authentication-and-authorization-with-datasnap-and-rest/9
12. Que filtro é esse?
• É um código a ser executado sobre os bytes que serão enviados e
recebidos pelas aplicações servidora e cliente.
• Delphi traz 3 filtros prontos para uso:
• 1 Filtro de Compactação, baseado em Zlib; e
• 2 Filtros de Criptografia, baseado em RSA e PC1
• Todos estes filtros tem efeito sobre TCP/IP e devem ser declarados em
ambos os lados, cliente e servidor.
• Filtros podem ser customizados, estendendo a classe
Data.DBXTransport.TTransportFilter
12
16. Nada é mais rápido para processar do que
o que não precisa ser processado!
16
17. DataSnap REST Parameter Cache
• Em um servidor REST, quando um método retorna um ou mais tipos complexos
como Streams, ele pode responder ao cliente que estes dados estão em cache,
possibilitando este cliente requisitar os dados em cache. Tudo que você precisa é
definir o cabeçalho “Accept” da requisição como “application/rest”.
• Então o servidor responderá com algo como:
• {"result":["0/0/0"],"cacheId":0,"cmdIndex":0}
• Isto significa que agora você tem um Parâmetro com este cacheId armazenado em
sua sessão. Basta fazer uma nova requisição com o mesmo “dssession” para obter o
conteúdo. A URL é mais ou menos assim:
• http://host:port/datasnap/cache/0/0/017
18. “Cacheando” dados
• Fazer cache de dados é (quase) sempre uma boa ideia!
• Não é tão simples fazer, mas é muito valioso no ambiente de produção.
• Pode ser feito do lado servidor ou do lado cliente, que é preferível.
• Dados que não mudam com frequência são ótimos candidatos a estarem em cache,
como:
• Países, Estados, Cidades, Unidades de Medida, etc.
• É essencial ter um mecanismo de invalidação de cache, que depende do contexto,
mas normalmente é feito por:
• Tempo de vida, definindo a data e hora a expirar
• Mudança nos dados
• Usando um hash dos dados; ou
• Usando um controle de versão dos dados (InterBase Change Views é O CARA nisso!)18
19. Cache do lado cliente
• Sempre que possível, armazene dados do lado cliente!
• Evitará tráfego desnecessário com o Servidor de Aplicação e
consequentemente com Servidor de Banco de Dados
• Requer mais cuidado com a invalidação
• Considere utilizar:
• ClientDataSet’s;
• FDMemTable’s
• FireDAC LocalSQL
• Lembre-se: em muitos casos tentar sincronizar o cache pode ser perda de
tempo. Jogue-o fora e crie novamente.19
20. Cache do lado servidor
• Usado para evitar acesso desnecessário ao banco de dados
• Pode ser um cache único para todos os clientes ou um cache por cliente
• Pode-se usar a propriedade TDSServerClass.LifeCycle para gerenciar isso
• Server: Um único cache (que faz mais sentido, mas nem sempre possível)
• Session: Cada cliente terá seu próprio cache
20
25. REST Request Filters
• Mais relacionado a REST do que Datasnap em si
Se não está familiarizado com REST, pode começar aqui: http://www.restapitutorial.com/
• Em resumo, servidores REST geralmente oferecem uma forma de “selecionar” do
resultado somente o pedaço que o cliente solicitou, ao invés de todo o conteúdo.
Isto é chamado REST Request Filters.
• São usados no final da URL, como:
…/metodo/parametro?filter.function=params
• Datasnap possui 2 filtros REST embutidos: SubString (ss) e Table (t).25
26. Filtro SubString
• Pode operar sobre Strings e seus caracteres ou sobre Streams e seus bytes
• Possui 3 funções:
• Count(c): único parâmetro, para definir os primeiros N caracteres desejados
• …?ss.c=1 retornará o primeiro caractere ou byte
• Offset(o): único parâmetro, para definir os primeiros N caracteres que deseja ignorar
• …?ss.o=10 retornará todo o conteúdo após o 10º caractere ou byte
• Range(r): dois parâmeteros, para definir o offset e o count
• …?ss.r=10,20 retornará o conteúdo a partir do 11º ao 30º caractere ou byte (Ignora 10, retorna 20)
26
27. Filtro Table
• Opera sobre Datasets, com as mesmas 3 funções do SubString, mas
filtrando registros ao invés de caracteres ou bytes
• Count(c): único parâmetro, para definir os primeiros N registros desejados
• …?t.c=1 retornará o primeiro registro
• Offset(o): único parâmetro, para definir os primeiros N registros que deseja ignorar
• …?t.o=10 retornará todos os registros após o 10º
• Range(r): dois parâmetros, para definir o offset e o count
• …?t.r=10,20 retornará os registros do 11º ao 30º (ignora 10, retorna 20)
27
31. Callback: o que é?
Quando você liga para alguém, ele/ela pode te ligar de volta, certo?
E é isso que o servidor faz!
Se um cliente “liga” pra um servidor, este servidor pode
“ligar de voltar” para este cliente!
31
32. Ok, mas para que?
• Para dar ao servidor a possibilidade de “falar” com o cliente de forma
proativa!
• Quando um cliente solicita algo ao servidor, não sabe o que está acontecendo
lá até que recebe a resposta.
• Do outro lado, o servidor não sabe como dizer ao cliente o que está
acontecendo.
• Usar um callback permite ao servidor fazer isso!
32
35. Mais sobre Callback
• Using Callbacks
• http://docwiki.embarcadero.com/RADStudio/Seattle/en/Using_Callbacks
• REST Heavyweight Callbacks
• http://docwiki.embarcadero.com/RADStudio/Seattle/en/REST_Heavyweight_Callbacks
• Delphi Labs: DataSnap XE - Callbacks - Artigo e vídeos (parte 1, 2 e 3)
• http://edn.embarcadero.com/article/41374
• https://youtu.be/5zO3_g9Z-wc
• https://youtu.be/geEzwg8XX8k
• https://youtu.be/Hwode7a8O5k
• Heavyweight Callbacks (HTTP) with DataSnap - Artigo e vídeos (parte 1 e 2)
• https://mathewdelong.wordpress.com/2011/05/30/heavyweight-callbacks/
• https://youtu.be/IrweqUlENHU
• https://youtu.be/xVUAisxqW0U35
36. Para terminar…
• Explore os recursos do Datasnap! Eles estão lá para serem usados! E funcionam :)
• Veja os exemplos, leia a documentação. Estude!
• Wizards nunca darão os melhores resultados. Vá além!
• Sempre planeje seu servidor levando em consideração seu ambiente de produção. Até a
qualidade da rede deve ser considerada.
• Leia sobre pool de conexões de banco de dados e use-o!
• Leveza nunca é suficiente já que nosso objetivo é ser o mais rápido possível! Mas só
trabalho pesado pode trazer resultados leves! ;)36