Pergunta

Estou começando na construção de uma API REST para um projeto que estou trabalhando, e isso me levou a fazer uma pequena pesquisa sobre a melhor maneira de construir uma API usando RoR. Eu descobrir muito rapidamente que, por padrão, os modelos estão abertos para o mundo e pode ser chamado via URL, simplesmente colocando um ".xml" no final do URL e passando parâmetros apropriados.

Então a pergunta seguinte veio. Como posso proteger meu aplicativo para evitar alterações não autorizadas? Ao fazer alguma pesquisa eu encontrei um par de artigos que falam sobre attr_accessible e attr_protected e como eles podem ser usados. O URL particular que eu encontrei de falar sobre estes foi publicado em Maio de '07 ( aqui ).

Tal como acontece com todas as coisas Ruby, eu tenho certeza que as coisas evoluíram desde então. Então, minha pergunta é, isso é ainda a melhor maneira de garantir uma API REST dentro RoR?

Se não for o que você sugere em qualquer um "novo projeto" ou um cenário de "existente projeto"?

Foi útil?

Solução

Existem vários esquemas de autenticação de solicitações de API, e eles são diferentes do que a autenticação normal previsto pela plugins como restful_authentication ou acts_as_authenticated. Mais importante, os clientes não serão manter sessões, então não há nenhum conceito de um login.

HTTP Authentication

Você pode usar autenticação básica HTTP. Para isso, os clientes da API usará um nome de usuário e senha regular e basta colocá-lo na URL assim:

http://myusername:mypass@www.someapp.com/

Eu acredito que restful_authentication suporta esta fora da caixa, de modo que você pode ignorar ou não alguém está usando seu aplicativo por meio da API ou através de um navegador.

Uma desvantagem aqui é que você está pedindo aos usuários colocar seu nome de usuário e senha em claro em cada solicitação. Ao fazê-lo através de SSL, você pode fazer este seguro.

Eu não acho que eu já realmente visto uma API que usa isso, porém. Parece um decentemente boa idéia para mim, especialmente uma vez que é apoiado fora da caixa pelos esquemas de autenticação atuais, então eu não sei qual é o problema.

API Key

Outra forma fácil de ativar a autenticação API é a utilização de chaves de API. É essencialmente um nome de usuário para um serviço remoto. Quando alguém se inscrever para usar seu API, você dar-lhes uma chave de API. Isso precisa ser passado a cada solicitação.

Uma desvantagem aqui é que se alguém recebe chave de API de outra pessoa, eles podem fazer pedidos como esse usuário. Eu acho que fazendo todas as suas solicitações de API usam HTTPS (SSL), você pode compensar este risco pouco.

Outra desvantagem é que os usuários usar as mesmas credenciais de autenticação (a chave API) em todos os lugares que vão. Se eles querem revogar o acesso a um cliente de API a sua única opção é mudar a sua chave de API, que irá desativar todos os outros clientes também. Isto pode ser mitigado, permitindo aos usuários gerar várias chaves de API.

API assinatura Key + Chave Secreta

Reprovado (tipo de) - ver OAuth abaixo

Significativamente mais complexo está assinando o pedido com uma chave secreta. Isto é o que a Amazon Web Services (S3, EC2, e tal fazer). Essencialmente, você dar ao usuário 2 chaves: a sua chave de API (. Ie username) e sua chave secreta (ie senha.). A chave API é transmitida a cada solicitação, mas a chave secreta não é. Em vez disso, ele é usado para assinar cada pedido, normalmente adicionando outro parâmetro.

IIRC, a Amazon faz isso tomando todos os parâmetros para o pedido, e ordenando-os pelo nome parâmetro. Então, essa seqüência é hash, utilizando a chave secreta do usuário como a chave de hash. Este novo valor é acrescentado como um novo parâmetro para o pedido antes de ser enviada. No lado da Amazon, eles fazem a mesma coisa. Eles levam todos os parâmetros (exceto a assinatura), encomendá-los, e de hash usando a chave secreta. Se isso corresponde à assinatura, eles sabem o pedido é legítimo.

A desvantagem é a complexidade. Recebendo este esquema funcione corretamente é uma dor, tanto para o desenvolvedor API e os clientes. Esperar muito de chamadas de suporte e e-mails irritados de desenvolvedores de clientes que não podem obter as coisas para o trabalho.

OAuth

Para combater alguns dos problemas de complexidade com chave + assinatura secreta, um padrão emergiu chamado OAuth . No núcleo OAuth é um sabor de chave + assinatura secreta, mas muito do que é padronizado e foi incluída em bibliotecas para vários idiomas .

Em geral, é muito mais fácil, tanto o produtor API e do consumidor de usar OAuth em vez de criar seu próprio sistema de chave / assinatura.

OAuth também inerentemente segmentos de acesso, fornecendo diferentes credenciais de acesso para cada consumidor API. Isso permite aos usuários o acesso seletivamente revogação sem afetar suas outras aplicações de consumo.

especificamente para o Ruby, há uma OAuth gem que fornece suporte fora da caixa para ambos os produtores e consumidores de OAuth. Eu tenho usado essa jóia para construir uma API e também para consumir OAuth APIs e era muito impressionou. Se você acha que seu aplicativo precisa OAuth (em oposição ao esquema de chave API simples), então eu posso facilmente recomendar usando o gem OAuth.

Outras dicas

Como faço para proteger minha app para evitar alterações não autorizadas?

attr_accessible e attr_protected são úteis para controlar a capacidade de executar mass-atribuições em um modelo de ActiveRecord. Você definitivamente quer usar attr_protected para evitar ataques de injeção de forma; consulte Use attr_protected ou vamos cortar-lhe .

Além disso, a fim de impedir ninguém de ser capaz de acessar os controladores na sua aplicação Rails, você está quase certamente vai precisar de algum tipo de sistema de autenticação do usuário e colocar um before_filter em seus controladores para garantir que você tenha um representante autorizado usuário que fez o pedido antes de permitir que a ação do controlador solicitado para executar.

Veja as de Ruby on Rails Guia de Segurança (parte da documentação do projeto Rails) para toneladas informações mais útil.

Eu estou enfrentando questões similares como você neste momento, porque eu também estou construindo uma API REST para uma aplicação Rails.

Eu sugiro certificando-se de que somente os atributos que podem ser usuário editado são marcadas com attr_accessible. Isto irá criar uma lista branca de atributos que podem ser atribuídos usando update_attributes.

O que faço é algo como isto:

   class Model < ActiveRecord::Base  
       attr_accessible nil  
   end

Todos os meus modelos herdar de que, de modo que eles são forçados a definir attr_accessible para quaisquer campos que querem fazer atribuível massa. Pessoalmente, eu gostaria que houvesse uma maneira de permitir que este comportamento por padrão (pode haver, e eu não sei sobre isso).

Só para você saber que alguém em massa pode atribuir uma propriedade não só usando a API REST, mas também usando um post forma regular.

Outra abordagem que salva a construção de um monte de coisas a si mesmo é usar algo como http://www.3scale.net / quais teclas canetas, fichas, etc. quotas para os desenvolvedores individuais. Ele também faz análises e cria um portal do desenvolvedor.

Há um ruby ??/ rails plugin do rubi plugin API que se aplicará às políticas para o tráfego que chega - você pode usá-lo em conjunto com o oAuth gem . Você pode também nos que, largando verniz na frente do aplicativo e usando o lib mod verniz: href="https://github.com/3scale/libvmod-3scale/" rel="nofollow"> Módulo .

scroll top