Visão geral
Estou procurando criar uma API (REST) para meu aplicativo. O objetivo inicial / principal será o consumo por aplicativos móveis (iPhone, Android, Symbian etc.). Estive estudando diferentes mecanismos de autenticação e autorização para APIs baseadas na Web (estudando outras implementações). Eu tenho minha cabeça envolvida na maioria dos conceitos fundamentais, mas ainda estou procurando orientação em algumas áreas. A última coisa que quero fazer é reinventar a roda, mas não estou encontrando soluções padrão que atendam aos meus critérios (no entanto, meus critérios podem ser equivocados, fique à vontade para criticar isso também). Além disso, quero que a API seja a mesma para todas as plataformas / aplicativos que a consomem.
oAuth
Vou seguir em frente e rejeitar minha objeção ao oAuth, pois sei que essa provavelmente será a primeira solução oferecida. Para aplicativos móveis (ou mais especificamente não relacionados à Web), parece errado deixar o aplicativo (acessar um navegador da Web) para autenticação. Além disso, não há como o navegador retornar o retorno de chamada ao aplicativo (especialmente entre plataformas). Conheço alguns aplicativos que fazem isso, mas parece errado e dá uma pausa no aplicativo UX.
Exigências
- O usuário insere o nome de usuário / senha no aplicativo.
- Toda chamada de API é identificada pelo aplicativo de chamada.
- As despesas gerais são reduzidas ao mínimo e o aspecto de autenticação é intuitivo para os desenvolvedores.
- O mecanismo é seguro para o usuário final (suas credenciais de logon não são expostas) e também para o desenvolvedor (suas credenciais de aplicativos não são expostas).
- Se possível, não exija https (de maneira alguma um requisito rígido).
Meus pensamentos atuais sobre implementação
Um desenvolvedor externo solicitará uma conta da API. Eles receberão um apikey e um sigilo. Toda solicitação exigirá no mínimo três parâmetros.
- apikey - dado ao desenvolvedor na inscrição
- timestamp - funciona como um identificador exclusivo para cada mensagem de um determinado apikey
- hash - um hash do timestamp + o apisecret
O apikey é necessário para identificar o aplicativo que emite a solicitação. O registro de data e hora age de maneira semelhante ao oauth_nonce e evita / mitiga ataques de repetição. O hash garante que a solicitação foi realmente emitida pelo proprietário do apikey fornecido.
Para solicitações autenticadas (feitas em nome de um usuário), ainda estou indeciso entre escolher uma rota access_token ou uma combinação de hash de nome de usuário e senha. De qualquer forma, em algum momento, será necessária uma combinação de nome de usuário / senha. Portanto, quando isso acontecer, um hash de várias informações (apikey, apisecret, timestamp) + a senha será usada. Eu adoraria comentários sobre esse aspecto. Para sua informação, eles teriam que fazer o hash da senha primeiro, já que eu não armazeno as senhas no meu sistema sem o hash.
Conclusão
Para sua informação, este não é um pedido de como criar / estruturar a API em geral, apenas como lidar com a autenticação e autorização somente dentro de um aplicativo.
Perguntas aleatórias sobre pensamentos / bônus
Para APIs que exigem apenas um apikey como parte da solicitação, como você evita que alguém que não seja o proprietário do apikey consiga ver o apikey (desde que foi enviado de forma clara) e faz solicitações excessivas para empurrá-los além dos limites de uso? Talvez eu esteja pensando demais sobre isso, mas não deveria haver algo para autenticar que uma solicitação foi verificada para o proprietário do apikey? No meu caso, esse era o objetivo do apisecret, ele nunca é mostrado / transmitido sem ser hash.
Falando em hashes, e o MD5 vs hmac-sha1? Realmente importa quando todos os valores são misturados com dados suficientemente longos (isto é, apisecret)?
Antes, eu estava pensando em adicionar um sal por usuário / linha ao hash de senha dos meus usuários. Se eu fizesse isso, como o aplicativo poderia criar um hash correspondente sem conhecer o sal usado?