Falando sobre aplicações e conteúdo dinâmico acessível

Aplicações e conteúdo dinâmico acessível
Imagem ilustrativa: Tela de codificação

Conteúdos dinâmicos ainda tinham barreiras sérias de acessibilidade, inclusive porque as tecnologias assistivas não conseguiam acessar modais ou áreas que eram atualizadas sem um “refresh” completo da página. Para tornar esse conteúdo dinâmico acessível na Web o W3C publicou a recomendação WAI-ARIA 1.0, que se tornou uma Recomendação do W3C em março de 2014.

WAI-ARIA (Accessible Rich Internet Applications) define a forma de tornar conteúdo, principalmente aplicações Web, acessíveis para pessoas com deficiências. Essa documentação auxilia especialmente conteúdo dinâmico e interfaces de usuário com controles avançados. WAI-ARIA funciona com as tecnologias já existentes, como HTML e SVG e proporciona uma forma de aplicar os requisitos das WCAG para aplicações ricas na Web.

Aplicações web complexas tornam-se inacessíveis quando as tecnologias assistivas não podem determinar a semântica de partes de um documento ou quando o usuário não é capaz de navegar de forma eficaz em todas as partes do site ou aplicação. WAI-ARIA divide a semântica em roles (papéis), states e properties (estados e propriedades).

Roles servem para identificar o elemento ou a aplicação na interface e estão divididas em quatro tipos:

  •     Abstract Roles: Usadas para ontologias. Não devem ser utilizadas para conteúdo
  •     Widget Roles: Utilizadas para definir interfaces de widgets, como alert, dialog, slider, tab, etc.
  •     Document Structure Roles: descrevem as estruturas que organizam o conteúdo em uma página, por exemplo article, group, img, region, etc. Estruturas de documentos geralmente não são interativos.
  •     Landmark Roles: são regiões da página destinadas a marcação de navegação, por exemplo banner, main, navigation, etc.

A lista completa de roles está neste link.

Cada uma das “roles” pode ser manipulada e definida por diversos “states and properties”, por exemplo, um link definido como item de um checkbox pode ser definido como “true” ou “false” para que o usuário tenha um retorno acessível do resultado da ação.

<li role=”menuitemcheckbox” aria-checked=”true”>Link ativo</li>

A lista completa de states and properties para cada role está aqui.

Uma das principais diferenças entre as WCAG e ARIA é que a primeira utiliza os elementos semânticos do HTML para tornar o conteúdo acessível. Já WAI-ARIA possibilita a mudança da semântica de um elemento para torna-lo acessível. Eu explico.

Neste exemplo, o desenvolvedor precisa criar um cabeçalho que é um botão. Para esse caso a recomendação é:

  •     Não faça isso: <h1 role=button>botão</h1>
  •     Faça isso: <h1><button>botão</button></h1>
  •     Ou então isso: <h1><span role=button>botão</span></h1>

Porque se role=button for colocado dentro do H1, a estrutura de acessibilidade dos objetos tratará esse elemento como <button>botão</button> e perderá sua característica de cabeçalho.

Por esse motivo, WAI-ARIA deve ser utilizado somente onde não for possível utilizar a semântica do HTML para tornar o conteúdo acessível. Sempre dê prioridade para as WCAG.

A Web está em constante evolução e conforme ela evolui, navegadores e tecnologias assistivas devem acompanhar esse processo. Por esse motivo o W3C tem uma preocupação imensa com a acessibilidade. A Web foi criada com o intuito de ser acessível desde sua concepção e esse princípio deve acompanhar sua evolução. E nós, criadores e mantenedores dos códigos que circulam pela Web, temos uma responsabilidade imensa de manter esse legado de uma Web acessível para as atuais e futuras gerações, afinal, dentro de algumas décadas nós poderemos ser os usuários de tecnologias assistivas que vão acessar esse conteúdo na Web. E ele deve ser acessível. Para o nosso próprio bem.

——

Artigo de Reinaldo Ferraz, publicado originalmente no portal iMasters.

SQL Server e o clássico problema dos usuários órfãos

 

SQL Server
SQL Server

Se você já tem alguma experiência com SQL Server, muito provavelmente já teve problemas com uma conta de usuário que deixa de funcionar. Geralmente isso acontece após a execução de uma restauração da base que está recusando a conexão. Este é um problema clássico do SQL Server, conhecido como “usuário órfão”.

Muita coisa já foi publicada sobre este tema. Este artigo discute por quê ainda temos este problema depois de quase 20 anos de existência do SQL Server.

Um pouco de História

Segundo a Wikipedia, a história do SQL Server começa em 1989. Particularmente, eu prefiro dizer que a Microsoft lançou seu produto comercialmente em 1998. Antes disso, o que havia era uma versão do Sybase adaptada para Windows, fruto de uma parceria muito obscura da Microsoft com a empresa Sybase, que naturalmente terminou com um processo judicial.

Em 1998, já encerrada esta estranha parceria, a Microsoft lançou o SQL Server 7.0, que tinha semelhanças enormes com o produto Sybase, se é que você me entende… Muita coisa foi herdada e continua assim até hoje. Já no seu lançamento, o SQL Server 7.0 dispunha do chamado “modo de autenticação mista”. Isso quer dizer que o usuário poderia se logar usando autenticação do próprio SGBD (login + senha) ou então com autenticação pelo Windows (reconhecimento do usuário de Windows logado no domínio).

Porém, o modelo de segurança foi herdado do Sybase e permanece assim até hoje. Diferentemente de outros SGBDs, SQL Server e Sybase usam duas entidades distintas:

“login”: que autentica o usuário na instância
“user”: que controla os privilégios do usuário dentro de cada banco de dados
E é este modelo de segurança que dá origem ao problema dos usuários órfãos. Por conta disso, SQL Server e Sybase são igualmente afetados por este problema.

Entendendo os usuários órfãos

O problema começa pelo fato dos logins serem gravados na base de sistema Master, enquanto os usuários (ou “users” se preferir) são armazenados em cada base em que eles têm acesso. A visão MASTER.SYS.SYSLOGINS informa detalhes do login: número do identificador de segurança (SID), data de criação, senha (se usar autenticação SQL), autoridades a atribuídas ao nível da instância etc. Já a visão NomeBD.SYS.SYSUSERS informa detalhes do usuário: identificador do usuário (UID), data de criação e, entre vários outros detalhes, o SID associado.

Quando usamos a autenticação do Windows, o SGBD transfere a tarefa de autenticação de usuário para o próprio Windows. Portanto, o SQL Server precisa apenas identificar os logins que estão cadastrados, reaproveitando o SID já usado no domínio para aquele login.

Porém a coisa muda quando usamos autenticação SQL. Ao criarmos um novo login, o SGBD vai gerar um novo SID para este login. Ocorre que as instâncias do SQL Server são independentes, não havendo nenhum tipo de integração entre os SIDs cadastrados em cada instância.

Deste modo, quando criamos o mesmo login em duas ou mais instâncias (por exemplo, as instâncias SQL2012DEV e SQL2012PROD, referentes a desenvolvimento e produção, obviamente), serão gerados SIDs diferentes. Quando fizermos um backup da base BDTESTE de produção e a restaurarmos na instância de desenvolvimento, a visão BDTESTE.SYS.SYSUSERS trará o SID que era usado em produção e que não tem nenhuma correspondência com aquele usado na instância desenvolvimento.

E assim encontramos o famoso usuário órfão. Neste quadro, o login continuará funcionando normalmente e o dono daquele login conseguirá conectar em todas as bases… Exceto na base BDTESTE, que acabou de ser restaurada.

Corrigindo a situação

Este problema foi solucionado desde os primórdios do SQL Server, usando a rotina SP_CHANGE_USERS_LOGIN.

Este é um procedimento em dois passos. No primeiro, identificamos quem são os usuários órfãos da base, rodando o procedimento usando o parâmetro “Report”. Feito isso, podemos escolher entre três caminhos:

  1. Se o login e o “user” tem o mesmo nome, usamos os parâmetros “Autofix” e o nome do usuário.
  2. Se login e “user” forem diferentes, então devemos usar três parâmetros, que são a ação “Update_One”, o nome do “user” e o nome do login correspondente.
  3. Se não existe login adequado, então devemos usar quatro parâmetros, que são a ação “Update_One”, o nome do “user” e o nome do login a ser criado e a senha deste novo login.

 

A listagem 1 mostra este exemplo:

1EXEC sp_change_users_login 'Report'
2--alternativa 1
3EXEC sp_change_users_login 'Auto_Fix', 'NomeUsuario'
4-- alternativa 2
5EXEC sp_change_users_login ' Update_One', 'NomeUsuario', 'LoginDiferente'
6-- alternativa 3
7EXEC sp_change_users_login ' Update_One', 'NomeUsuario', 'NovoLogin’, 'Senha'

 

Como evitar órfãos

Uma forma de evitar os usuários órfãos é usar apenas autenticação pelo Windows. Desta forma, o SQL Server não controla e não autentica nada. Quem faz isso é o sistema operacional. Esta é a estratégia usada pelo DB2, por exemplo.

O modelo de segurança do SQL Server é desenhado para trabalhar com instâncias independentes com múltiplas bases de dados. E isso realmente complica o uso de autenticação SQL.

Se desejássemos usar autenticação SQL e não termos problemas com usuários orfãos, seria necessário haver um repositório central de logins usados em todas as instâncias SQL no domínio, de modo que houvesse um único SID para cada login em todas as instâncias SQL.

Conclusão

Ter usuários órfãos é o preço que se paga para o SQL Server trabalhar ao mesmo tempo com a ideia de instâncias com múltiplas bases e também oferecer dois tipos de autenticação diferentes (Windows ou SQL).

A solução do problema é bem simples, como vimos aqui. E na minha opinião, este é um custo baixo pelas funcionalidades que o SQL Server oferece.

Leituras Sugeridas

NM, Vinoth.  Find Orphan SQL Users and Fix using ALTER USER. TOAD WORLD. 24/10/2013.
BERRY, Glenn. How To Avoid Orphaned Database Users with SQL Server Authentication.  SQLSKILLS. 23/08/2013.
SHEHZAD, Atif. Understanding and dealing with orphaned users in a SQL Server database.  MSSQLTIPS. 24/09/2008.
CAMPBELL, Michael K.  SQL Server 2012 Contained Databases.  SQL SERVER PRO. 20/09/2012. http://sqlmag.com/sql-server-2012/sql-server-2012-contained-databases

—-

Artigo de Wagner Crivelini, publicado originalmente no iMasters.

Como trabalhar regionalização em SEO

Imagem ilustrativa
Imagem ilustrativa

Segmentação é um dos conceitos mais aplicados nas táticas de marketing e publicidade tradicionais. O foco dessa ideia pode ser resumido no seguinte: migrar do ambiente massificado para parcelas de clientes em potencial.

Na prática, a segmentação pode ser definida como a seleção de grupos de consumidores com perfis que estejam alinhados ao que você tem a oferecer.  Ou, mais precisamente, trata-se de escolher os clientes certos. E dentro do SEO esse conceito está relacionado, intimamente, à regionalização, ou seja, em aplicar as estratégias on- page e off- page para melhorar o posicionamento de acordo com a localização geográfica do internauta que está em busca do seus produtos e/ou serviços.

Dessa forma, o objetivo será aumentar a visibilidade da marca não só na web como um todo, mas nas regiões em que a empresa atende. Essa abordagem pode ser a mais certeira para marcas que são capazes de atuar dentro de um determinado raio de sua localização física.

Utilize uma extensão de domínio local

O primeiro passo para começar a trabalhar a regionalização no SEO de um site ou e-commerce é escolher um domínio com extensão local. Ok, pode parecer uma dica boba, mas o fato é que muitos empreendedores ignoram a importância do .br ao final do endereço do site.

Como muitas marcas utilizam expressões ou nomes estrangeiros, a ausência do .br pode “confundir” os motores de busca e excluir o site do devido posicionamento em seu país de atuação.

Indo além: segmentando por estado ou cidade

Já temos uma extensão com domínio local. Mas isso é só início. Para aplicar, de fato, a regionalização no SEO é preciso fazer a segmentação por estado ou cidade, por meio de palavras-chave.

A melhor forma de se fazer isso é implementando conteúdo otimizado com termos como “seguro de carro rj”, para uma seguradora, por exemplo. Além disso, é importante trabalhar focado em outros termos que o internauta pode utilizar para a busca de um determinado produto ou serviço. Seguindo o exemplo acima mencionado, poderíamos trabalhar também com “seguro automóvel rj” ou mesmo “seguro automóvel Parati” – segmentando por cidade.

A importância das ferramentas de geolocalização

De nada adianta trabalhar com termos locais se a sua empresa não estiver visível no Google Maps. Quando se trata de SEO regional a melhoria do ranqueamento também depende da presença no Maps e no Google Meu Negócio.  Por isso, não esqueça de fazer a sua página nesse último!

É essa integração que irá gerar possibilidades de alcançar ótimas colocações na primeira página, já que o buscador também prioriza o fornecimento do endereço completo da loja ou empresa que o internauta procura.

Ainda dentro dessa tática é importante incluir sua empresa em listas de endereços como Guia Mais, TeleListas, iLocal para aumentar as possibilidades de angariar comentários e avaliações de internautas em buscas regionais.

Mobile SEO

Segundo pesquisa do Google, 40% das buscas móveis são com intenção local. Tal estatística só demonstra a importância de trabalhar a otimização para dispositivos móveis com o objetivo de aplicar uma estratégia realmente eficaz de SEO Regional.

E nesse cenário surgiu um jogo de sílabas curioso, que tem se tornado quase um mantra para os especialistas de SEO: SoLoMo. O significado? Social+Local+Móvel. Trata-se de uma fusão de conceitos que visa otimizar a experiência do usuário de tablets, celulares, smartphones e outros dispositivos móveis.

Mas, por onde começar? O primeiro passo é tornar o site responsivo, ou seja, adequado para visualização em celulares, tablets e smartphones. Também é aconselhável usar detecção de User Agent de forma dinâmica, inserindo sumário para o conteúdo e redesenhando o layout do site para telas de aparelhos mobile.

Pode-se dizer, portanto, que os resultados no SEO Regional podem ser observados em um curto período de tempo, já que a concorrência de termos chave é, na maioria das vezes, menor.  Isso porque você não estará competindo com as outras marcas do país, mas somente com os concorrentes diretos do seu estado ou cidade. Em uma analogia simples: é bem mais fácil se tornar o peixe maior em uma lagoa pequena, do que no mar. Comece agora a pensar nas suas estratégias de regionalização.

—–

Artigo de Hidelbrando Tannin, publicado originalmente no iMasters.

Review: Apiary – Fazendo muito mais que apenas documentar

apiary
Página do Apiary

Há algum tempo, venho trabalhando diretamente com APIs de diversos tipos. Tanto APIs públicas abertas, quanto fechadas. Em partes, meu trabalho está na criação de documentações, SDKs e artigos técnicos para utilização e consumo.

Uma das maiores dificuldades na criação de documentação de API, além, claro, da manutenção, é a ilustração de sua utilização para o desenvolvedor que está tento o primeiro contato com ela. Ao iniciar a integração, é natural que o desenvolvedor precise, por exemplo, saber como suas requisições HTTP estão sendo recebidas pela API e qual está sendo a resposta da API, para aquela requisição específica.

Ilustrar o recebimento da requisição e a resposta para essa requisição, em uma documentação, não é uma tarefa simples. E é justamente nesse ponto que o Apiary mostra sua força.

Primeiro contato

Eu já tinha uma conta no Apiary há algum tempo, mas apenas recentemente fui realmente utilizá-lo para um caso de uso em produção. A interface do Apiary é bastante simples e a organização facilita sua utilização:

ri01
De um lado, temos o conteúdo da API. A separação por recurso/verbo HTTP simplifica tanto a criação da documentação para aquele recurso/verbo, quanto o entendimento daquilo que está sendo documentado. Algumas documentações podem ter diversos recursos e o ToC no lado direito facilita a navegação entre os recursos.

Documentação facilitada

A ferramenta já seria excelente, por cumprir muito bem seu propósito de documentar. Mas como manter a documentação é uma tarefa, talvez, ainda mais complexa que escrever a documentação, o Apiary oferece a integração com um repositório no Github.

Isso significa que podemos escrever toda a documentação em Markdown e, ao fazer push para o repositório, a documentação no Apiary é atualizada automaticamente.

Ambiente de testes

Pronto, escrevi a documentação da minha API. E agora?

Apesar de o Apiary ter a documentação como foco, o ponto mais forte, na minha opinião, é o Mock Server. Ao definir os recursos da API e os verbos, podemos também definir o que é esperado para determinada requisição HTTP e qual será a resposta, se a requisição for feita corretamente.

O Mock Server é composto por dois ambientes distintos:

  • O próprio Mock Server, para onde devemos enviar as requisições de teste.
  • O Traffic Inspector, que monitora as requisições feitas para o Mock Server.

 

Para localizar a URL do Mock Server, basta observar a coluna da direita, logo abaixo a tabela de conteúdo. Será alguma coisa como: netojoaobatista.apiary-mock.com.

Uma vez localizada a URL do Mock Server, basta fazer uma requisição HTTP como documentado na sua API. Assim que a requisição for feita, basta verificar o Traffic Inspector, para ver como ela chegou na API e qual foi a resposta dada pela API:

ri01

Prós

  • A interface é simples e intuitiva. Muito fácil de utilizar.
  • Permite a utilização de Markdown para a documentação.
  • É possível documentar cada verbo HTTP de cada recurso.
  • É possível descrever como serão as requisições e respostas HTTP.
  • O Mock Server e Traffic Inspector facilitam a integração, ao ilustrar como a requisição foi recebida e o que foi retornado. Permite, ainda, mostrar se a requisição foi bem sucedida ou se houve algum erro.
  • Permite integração com Github, tanto com repositórios públicos, quanto privados.

 

 

Contras

  • O Mock Server é bastante rígido com o que foi especificado. Se você colocou 3 espaços na documentação, então a requisição deve ser feita com 3 espaços.

 

Conclusão

Se você está desenvolvendo uma API e precisa documentá-la, o Apiary é, certamente, uma excelente ferramenta. A facilidade de escrever e manter a documentação, já seriam argumentos o suficiente para sua utilização. Mas o Mock Server + Traffic Inspector são o algo mais. Documentação de API é algo feito para o desenvolvedor. O que melhor, então, para o desenvolvedor, que oferecer um ambiente para ele “brincar” com sua API, enquanto lê a documentação?

——–

Artigo de João Batista Neto, publicado originalmente no iMasters.

Server-side routes vs. Client-side routes

Algoritmos
Imagem ilustrativa

Lá no SOPT, o usuário Rod fez a seguinte pergunta:

Qual a vantagem e desvantagem das rotas serem feitas por server(php,asp.net, etc) ou serem por client(angularjs,emberjs,backbone…)? Em relação performance, qual tem maior? Segurança, mobile, usabilidade?

Achei um assunto bem relevante e resolvi responder.

As rotas são desencadeadores de comportamentos. Quando você acessa http://seusite.com/contato/, a ideia é que seja exibida uma página destinada a contatos. O roteador, neste caso, é o responsável por “explicar” para a aplicação que algum usuário está tentando acessar /contato/ e então algo deve ser feito – neste caso fantasia, o objetivo é exibir a página contato.html, por exemplo.

No caso do JavaScript, independente da plataforma, a ideia é que sejam invocados comportamentos específicos para cada página que o usuário acessar. No nosso exemplo (/contato/), considere que exista um formulário para que o usuário entre com o seus dados. Este formulário, por sua vez, possui uma validação que, no caso do Backbone.js, pode ser resolvido com Backbone.Validation.

Dada a situação, pensamos: seria válido invocarmos o Backbone.Validation para qualquer página, visto que apenas /contato/ possui um formulário? Negativo. Isso é conceitualmente ruim. O roteamento faz justamente isso: desencadeia uma entidade específica para que ela seja responsável por maestrar o que vai ou não acontecer na página solicitada.

Para reforçar, existem dois princípios que se aplicam para este caso: KISS e DRY.

O que são essas “entidades”?

As entidades são os “controllers”, no caso de Angular.js ou Marionette.js; Para Backbone.js, temos as “views” que fazem o serviço.

E a concorrência de cliente com servidor?

Na verdade, a concorrência é relativa. Você pode possuir rotas de cliente e servidor se assim quiser: no cliente você lida com o que a devida rota vai trabalhar em termos de JavaScript; no servidor você lida com o que vai acontecer com o cliente quando tal rota for executada.

Mas, o que isso significa? Se você tiver uma SPA (aplicação de página única), as rotas em cliente são suficiente; se você possuir várias páginas, você (provavelmente) irá trabalhar com roteamento em ambos os lados, tanto cliente quanto servidor, porque indicar o que de JavaScript deve ser executado não será suficiente.

Em relação a performance, qual tem maior? E quanto a segurança, mobile, usabilidade?

O ideal é não comparar a performance das rotas do cliente contra as do servidor – as propostas são diferentes e você tem que optar por aquela que satisfaz (melhor) a sua necessidade.

Você pode controlar todo o roteamento pelo servidor e não utilizar o oferecido pelo cliente: isso, por hora, vai te dar um bootstrap mais produtivo, principalmente se o seu nível de conhecimento sobre as frameworks front-end não for alto; entretanto, por outro lado, vai te gerar um maior número de requisições e a facilidade de escalabilidade do seu aplicativo pode estar comprometida no futuro pela perda de controle e capacidade de manutenção que esse roteamento singular trará.

Como exemplo da empregabilidade paralela dos dois roteamentos, vejamos o GitHub:

  1. Acesse o repositório oficial do Backbone;
  2. Abre o console do seu navegador com, provavelmente, Ctrl + Shift + I ou F12;
  3. Volte o seu foco para o repositório do Backbone;
  4. Clique na pasta “docs“.

Percebeu que foi feita uma requisição do tipo GET e outra do tipo POST e nada foi recarregado? Pois é, o Backbone, por exemplo, traz um conjunto que torna esse mecanismo possível. Começando pelo Backbone.Router, indo até o window.history.

Agora, vou lhe pedir outra coisa: acesse a pasta /docs/ diretamente, emitindo uma requisição síncrona do tipo GET.

Esperando você fazer…

Então, você foi direcionado exatamente para o mesmo lugar que antes, quando você primeiro acessou o repositório e através de um click acabou na pasta /docs/. O que aconteceu é que o roteamento do servidor acabou de cumprir o seu papel — papel esse que um roteador de cliente não assumiria.

Para trabalhar com pushState, eu obrigatoriamente preciso de um roteador no cliente? Roteador é nomenclatura, não algo sólido. A lógica dos roteadores em geral é que você tem que observar uma alteração na URL; se houver uma alteração, então faça algo. Salientando que “se houver uma alteração”, faz parte de roteadores de cliente – roteamento do servidor não tem capacidade de perceber “alterações” em tempo real (como eu disse, coisas diferentes!).

Para ilustrar melhor um roteador, veja o seguinte:

pOAnD

Esse “diagrama” representa o modelo mais comum de roteamento. A princípio, tudo são apenas nomes – o que significa que você pode ter uma estrutura exatamente igual a essa e nunca antes se deu conta. Além disso, obviamente, podem existir outros dispositivos entre os laços dessa trilha – como models, helpers, etc –, mas a diáspora de requisições se move nesse fluxo; nesse sentido.

E quanto a segurança?

Falando de segurança, a premissa é trivial: proteja realmente a sua aplicação no servidor. O cliente é para lidar com informações que as pessoas precisam ver e interagir com elas. Ele jamais deve executar processos lógicos de qualquer porte. De antemão, o cliente deve servir para você mostrar mensagens de erros – o critério por trás dessas mensagens é que deve ser de responsabilidade do servidor: isso é roboticamente imburlável.

Como segurança nunca é demais, você pode juntar o útil ao agradável: faça validações duplex. Tente assegurar o máximo possível no navegador – se caso algo passar em branco ou for burlado, tenha certeza de que o servidor estará à prova de balas. Efeito da ação e reação: validações no cliente exigem mais recursos por parte do usuário. Jamais se esqueça disso.

Ok, e onde entram as rotas + segurança? Ei, calma! A responsabilidade delas é encaminhar pessoas para lugares. A higienização das pessoas que vão passar pelas portas é da responsabilidade de outrem.

… Mobile?

As regras para aplicativos (web) mobile são as mesmas, mas sempre lembrando que as requisições devem ser na menor quantidade possível para garantir uma velocidade de navegação mais satisfatória.

Se você se refere à aplicativos nativos: isso é assunto para um outro artigo!

Para acessar a resposta, eis o link.

——

Artigo de Guilherme Oderdenge, publicado originalmente no iMasters.

Password Hashing – API nativa para gerenciamento de senhas

 

Imagem ilustrativa
Imagem ilustrativa

A segurança de dados sensíveis dos usuários é sempre um fator determinante para a integridade de qualquer aplicação. Dada essa premissa, esforços são constantes nessa área para prover os sistemas computacionais de formatos criptografados cada vez mais seguros.

Senhas geralmente são armazenadas em hash, que nada mais é do que um símbolo derivado de um algoritmo que o torna incapaz de, à luz da teoria, obter seu estado original. Apesar do nível de complexidade de algoritmos que geram hashes, temos hoje diversas formas que tentam recuperar dados originais “escondidos” através de dicionários, rainbow tables ou força bruta.

Pensando nisso, desenvolvedores da linguagem PHP, preocupados não só com a integridade de senhas mas também com a facilidade de programação oferecida pela linguagem, optaram por criar uma API nativa capaz de somar ao mesmo tempo segurança e simplicidade para armazenamento de credenciais. Criaram então uma extensão de criptografia chamada Password Hashing, disponível desde a versão 5.5.0. Essa extensão utiliza o algoritmo bcrypt, o mais forte suportado pelo PHP atualmente.

Recursos oferecidos

A API oferece um pequeno e poderoso conjunto de funções capazes de auxiliar o programador a criar hashes seguros, realizando todo o trabalho braçal de forma segura e com alto grau de confiabilidade. A seguir, suas respectivas funções:

password_hash

Cria um novo hash de senha usando um algoritmo de hashing. O caso geral para esta função é atribuir um custo (potência matemática) razoável para o algoritmo e deixá-lo criar um salt (parâmetro que gera aleatoriedade da saída) qualquer. O uso de bcrypt sempre retornará uma string de 60 caracteres.

1<?php
2echo password_hash("imasters",
3PASSWORD_BCRYPT,
4[
5"cost" => 12, // Se omitido, custo 10
6'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM) // Você pode omitir este parâmetro para geração de salt aleatório também.
7]
8);
9// Resultado $2y$12$syPYpcHYHWfyraREZ5BCc./OiKezWghwO/5HsbvNv0U4G1xqjsguW

password_verify

Verifica se uma senha corresponde a um hash.

1<?php
2
3if(password_verify('imasters', '$2y$12$sy...'))
4echo 'Senha válida!';
5else
6echo 'Senha inválida!';

password_get_info

Retorna informações sobre o hash dado como algoritmo usado e custo.

1<?php
2var_dump(password_get_info('$2y$12$sy...'));

password_needs_rehash

Verifica se um determinado hash corresponde a informações fornecidas. Caso não seja, assume-se que ele precisa sofrer o processo de hash novamente. Como a função retorna apenas um valor booleano, seu real uso pode ser observado abaixo, quando troco as configurações de geração de hash, ou seja, a senha é válida para aquele algoritmo, mas não para o novo custo que inseri, então gero o hash novamente para a nova configuração.

1<?php
2$senha = 'imasters';
3$hash = '$2y$12$sy...';
4if(password_verify('imasters', $hash)) {
5echo "A senha é válida\n";
6if(password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 11])) { // Mudei o custo para 11
7echo "Senha precisa de novo hash\n";
8$hash = password_hash($senha, PASSWORD_BCRYPT, ['cost' => 11]); // Gerei o novo hash
9echo $hash; // Basta salvar no banco de dados agora
10}
11else
12echo "Senha não precisa de novo hash";
13}
14else
15echo "Senha não verificada";

 

Conclusões

Neste artigo, mostramos a facilidade e a simplicidade do gerenciamento de senhas com a API Password Hashing, acompanhadas de um poderoso algoritmo, o bcrypt. O grande objetivo desse recurso é fazer com que você se preocupe mais com as funcionalidades da sua aplicação ao usuário e menos com a complexidade da segurança de senhas.

Referências:

 

Dicas para aprender mais com testes A/B

imagem ilustrativa
imagem ilustrativa

Decifrar o comportamento do consumidor, suas preferências e escolhas, certamente é uma tarefa extremamente difícil. Embora existam diversos estudos acadêmicos sobre o assunto, além de inúmeros cases de sucesso na área de comunicação e marketing para usarmos como referência, na maioria dos casos a eficácia de uma campanha nessas duas áreas só pode ser avaliada com precisão a partir do feedback do próprio público. Isso não significa dizer, no entanto, que a empresa deva assumir uma postura passiva.

Uma das estratégias mais recomendadas para aprimorar a eficácia das ações de comunicação e marketing de uma organização, aumentando, assim, as taxas de conversão, é a realização de testes A/B. Cores dos botões de compra, palavras-chave utilizadas, Layouts, CTAs (Call to Action), enfim, é possível avaliar, através de experimentos, quais são os elementos que mais atraem o consumidor nas peças enviadas pela empresa. Nesse artigo, você conhecerá quatro dicas para aprimorar o seu aprendizado durante a realização desses testes. Confira!

1. Faça testes minuciosos

Quando uma campanha não rende o esperado, é muito comum que seja feita uma renovação completa na peça enviada para o público. No entanto, nem sempre essa é a melhor alternativa, e por isso a importância de se realizar testes A/B. Em muitos dos casos, trocar apenas uma palavra, como “promoção” no lugar de “desconto”, pode mudar bastante o número de conversões realizadas com a estratégia.

Por isso, antes de repaginar o material enviado, opte por fazer pequenas mudanças e acompanhar a reação do público à elas. É possível se surpreender bastante com os resultados, e o aprendizado pode ser repassado para as campanhas seguintes.

2. Siga um roteiro bem definido

Da mesma forma que os testes devem ser feitos de maneira minuciosa, é preciso estabelecer um roteiro para fazer as mudanças. Cada nova opção feita merece um acompanhamento especial, até que sejam realizadas mais alterações. É preciso avaliar item por item e as mais variadas combinações possíveis, para saber qual será a versão definitiva que será usada para ser enviada aos clientes.

3. Dê tempo ao tempo

O tempo é um critério importante por dois motivos: em primeiro lugar, para avaliar quantas conversões foram efetuadas no período em que a peça esteve disponível ao público. Em segundo, pois devemos considerar as sazonalidades durante a exibição do material. Por isso, leve em consideração um prazo de 30 dias para avaliar a verdadeira eficácia de uma campanha, e evite, ao máximo, fazer testes em datas comemorativas ou sazonalidades, para não “adulterar” os testes.

4. Equipe especializada

Por fim, e não menos importante, é fundamental que os testes sejam realizados por uma equipe fixa e especializada. Todos os resultados devem ser controlados por esses profissionais, que devem sempre oferecer relatórios para a gestão apontando os resultados. Mais importante ainda é evitar a rotatividade de funcionários até que os testes estejam finalizados, o que certamente vai diminuir o retrabalho.

Você costuma fazer testes A/B no material disponibilizado ao público? Não perca mais tempo e comece os experimentos. Para mais dicas, assine a nossa newsletter e receba conteúdo de primeira para otimizar as suas campanhas de e-mail marketing!

——-

Artigo de André Metzen publicado originalmente no portal iMasters.

Encontre erros de JavaScript com o Google Analytics

Google Analytics
Google Analytics

O Google Analytics é bem mais que um contador de acessos ou ferramenta demográfica – você pode construir toda a sua carreira por ser um analista de Google Analytics. Você pode medir a efetividade de uma campanha, o fluxo de visita de um site (como do anúncio até o carrinho de compras) e definir ações como suporte de navegador com base nas informações de seus usuários.

Mas essas são todas funções que não atingem os devs. O que nós, desenvolvedores, podemos fazer com o Google Analytics, no entanto, é rastrear erros através de eventos personalizados.

Este é um pequeno exemplo de como implementei a checagem de erros no analytics:

1// Track basic JavaScript errors
2window.addEventListener('error', function(e) {
3    _gaq.push([
4        '_trackEvent',
5        'JavaScript Error',
6        e.message,
7        e.filename + ':  ' + e.lineno,
8        true
9    ]);
10});
11
12// Track AJAX errors (jQuery API)
13$(document).ajaxError(function(e, request, settings) {
14    _gaq.push([
15        '_trackEvent',
16        'Ajax error',
17        settings.url,
18        e.result,
19        true
20    ]);
21});

Agora, quando você abrir o Google Analytics, vai poder visualizar informações de eventos personalizados (custom event) com outros status do site. Claro que você terá que dizer ao pessoal do marketing que aquilo não é um erro, mas features, mas essa é outra história.

Considere usar o Google Analytics para encontrar erros no seu site. Você me agradece depois.

—–

Texto de David Walsh, publicado originalmente no iMasters.

Trabalhando com propriedades customizadas e variáveis no CSS

Web Quellcode
Imagem ilustrativa

O Módulo das CSS3, denominado CSS Custom Properties for Cascading Variables Module Level 1 (em tradução livre: Propriedades customizáveis para variáveis CSS Módulo 1), encontra-se no estágio de última chamada para Rascunho de Trabalho do W3C. Portanto, trata-se de uma especificação em estágio anterior ao de Rascunho de Trabalho e assim sendo, convém alertar que este artigo tem caráter meramente informativo e será atualizado quando julgado necessário. Consulte a especificação no site do W3C para informações atualizadas.

Para futura referência, informo que este artigo foi baseado na versão de 06 de maio de 2014, vigente à época em que o artigo foi escrito e publicado.

A finalidade da especificação é a de apresentar um novo valor CSS primitivo, denominado variável CSS aplicável a todas as propriedades CSS, bem como a customização de propriedades CSS destinadas a definir o valor das variáveis.

Propriedades CSS customizadas ou variáveis CSS

A sintaxe da regra CSS é conforme mostrada na figura a seguir:

sintaxe

Notar que a declaração CSS compreende uma propriedade e um valor. Propriedades CSS são as características de um elemento da marcação que podem ser estilizadas, por exemplo: cor, borda, margem, posição inicial da imagem de fundo etc, que são as nossas conhecidas propriedades color, border, margin, background-position etc.

Valores CSS são grandezas ou aspectos que definem quantidades ou características de uma propriedade, por exemplo: red, 2px solid blue, 2.5em, left top, etc.

Observe a seguir alguns exemplos de declaração CSS.

1{
2    color: red;
3    border: 2px solid blue;
4    margin: 2.5em;
5    background-position: left top;
6}

A sintaxe para se criar uma variável CSS (as especificações as denominam de propriedade CSS customizada) tem o formato geral –*, onde o sinal asterisco (*) é um nome de livre escolha do autor, ou seja, o nome da variável, e no qual alguns caracteres não são permitidos, como por exemplo: ; # } ] ) etc.

Observe a seguir alguns exemplos para definição de valores de variáveis CSS. Os valores válidos para as variáveis CSS (ou propriedades CSS customizadas como são denominadas nas especificações) são todos os valores CSS válidos.

1{
2 --cor-um: red;
3 --bordaLegal: 2px solid blue;
4 --margemBlz: 2.5em;
5 --POSICAOFUNDO: left top;
6 --maujor: uppercase;
7 --maria: bold;
8}

Uma propriedade CSS customizada nada mais é do que uma variável para ser usada como argumento de uma função CSS var() cujo valor de retorno é o valor CSS da variável. O exemplo a seguir esclarece a sintaxe para definição de varáveis CSS e para o uso da funcão var().

1:root {
2 --minha-cor-fundo: black;
3 --minha-cor: red;
4 --minha-largura: 40%;
5}

No código mostrado, definimos duas variáveis CSS denominadas minha-cor-defundo, minha-cor e minha-largura cujos valores são black, red e 40% respectivamente.

As variáveis CSS se aplicam (ou surtem efeito) somente dentro do ESCOPO para o qual foram definidas. No caso do nosso exemplo, o escopo das duas variáveis é o elemento raiz do documento :root, ou seja as variáveis são válidas para qualquer elemento da marcação constante da página (ou documento).

É possível definir um container qualquer da página como escopo para variáveis. Por exemplo: o autor define variáveis para serem usadas somente nos rodapés da página. Neste caso, o escopo será o elemento footer.

1div {
2 width: var(--minha-largura);
3 height: 200px;
4 background-color: var(--minha-cor-fundo);
5 color: var(--minha-cor);
6}

No código mostrado, usamos as duas variáveis CSS (o valor das variáveis) para definir a largura e a cor de fundo e de frente de todos os elementos div da página. Alterando o valor da variável, altera-se a largura e a cor de fundo e de frente de todos os elementos div da página.

Exemplo interativo

O exemplo interativo para os códigos mostrados anteriormente está hospedado no JSFiddle e funciona em navegadores que suportam variáveis CSS (até julho de 2014, somente o Firefox 31, lançado em 16/07/2014).

Você identifica alguma semelhança com pré-processadores CSS? Só isso? Nãooooooo! A especificação prevê outras funcionalidades mais complexas e flexíveis do que simplesmente definir o valor das variáveis, como por exemplo realizar cálculos, manipular, definir valores fallback para variávies CSS etc.

Nesse primeiro momento não vou mostrar todas as funcionalidades constantes das especificações, já que o objetivo deste artigo é o de informar aos meus leitores da existência das variáveis CSS.

Nota: Não me senti confortável com o fato de a especificação ter usado o termo propriedade CSS customizada para se referir às variáveis CSS, pois estas são valores CSS e não propriedades CSS. Ou, existe uma razão que eu não percebi e estou equivocado?

———

Texto de Maurício Maujor, publicado originalmente no iMasters.

Depurando requisições HTTP via CLI

Imagem ilustrativa
Imagem ilustrativa

Você é administrador de sistema. Você ama CLI. Você usa PHP. É claro que você consegue solucionar problemas de aplicativos PHP que normalmente são executados por meio de um servidor HTTP via CLI, certo? Bem, tenho boas notícias: você consegue – com algumas ressalvas. Este artigo é a continuação de outro que escrevi para um blog em 2012 intitulado “Executando scripts php-cgi via CLI como um servidor web faria (falsificando-os)”. Se você consegue executar seus aplicativos PHP via CLI, pode usar ferramentas como strace para depurar comportamento do aplicativo PHP.

TL;DR: pode-se falsificar praticamente qualquer solicitação HTTP, definindo as variáveis de ambiente corretas antes de chamar o binário PHP.

Primeiro, as ressalvas.

  • Suas configurações de PHP podem ser alteradas de sobrescritos no servidor web (Apache/PHP-FPM daemon) e o binário PHP que você executar via CLI pode não tem uma representação correta como binário PHP(-FPM) usado através desse servidor HTTP – então verifique suas configurações de PHP;
  • Você não usará o cache APC enquanto estiver executando o PHP através de CLI, nem o opcode, nem o cache de chave/valor de APC;
  • Suas variáveis de ambiente $_SERVER serão diferentes do que via um servidor web HTTP. Lembre-se disso se seu aplicativo depende dele.

Agora, mãos à obra.

Aplicativo da web básico

Se você tiver um aplicativo PHP simples, provavelmente conseguirá executá-lo simplesmente via CLI.

1$ cd /path/to/your/docroot
2$ php index.php

A saída pode ser (mas não necessariamente) a mesma que seria se ele fosse chamado via web.

Usando variáveis de ambiente para determinar dev/staging/prod

Assim como você pode especificar variáveis de ambiente no Nginx ou no Apache para permitir que seu código use configurações/usuários/senhas diferentes, elas também podem ser utilizadas via CLI. Se seu aplicativo depende de uma variável de ambiente chamada “APPLICATION_ENV” para distinguir os ambientes, você pode adicioná-la à sua requisição.

1$ cd /path/to/your/docroot
2$ APPLICATION_ENV=development php index.php

Framework que usa rotas

Se estiver usando um framework com controlador de roteamento para mapear o URI diretamente para o arquivo index.php, você pode adicionar variáveis de ambiente para fazer o aplicativo PHP pensar que você está solicitando um URI específico.

1$ cd /path/to/your/docroot
2$ REQUEST_URI=/your-test-page php index.php

 

Aplicativo PHP multidomínio

Se estiver executando seu aplicativo de PHP como aplicativo multisite, ou seja, se seu conteúdo e comportamento de código variam de acordo o hostname utilizado na solicitação, você também pode passá-los para frente como variáveis de ambiente.

1$ cd /path/to/your/docroot
2$ SERVER_NAME=www.yoursite.tld HTTP_HOST=www.yoursite.tld REQUEST_URI=/your-test-page php index.php

Enviando solicitações POST em CLI

O método HTTP é apenas uma variável de ambiente – por isso é mutável.

1$ cd /path/to/your/docroot
2$ REQUEST_METHOD=POST CONTENT_TYPE=application/www-form-urlencoded REQUEST_URI=/your-test-page php index.php

Conclusão

A execução desses comandos PHP via CLI lhe permite solucionar problemas de aplicativos mais facilmente, já que agora você consegue reproduzir solicitações HTTP específicas sob demanda. O principal benefício é a capacidade de anexar um depurador (como gdb ou strace) para esse processo. Você pode ver todas as chamadas de sistema de nível inferior, bem como todo o tráfego de rede (como consultas ao MySQL, solicitações de memcached, tráfego MongoDB, …) à medida que seu aplicativo as envia e recebe.

 

Artigo de Mattias Geniar, publicado originalmente no iMasters.