Sinatra - API-Autenticación


Vamos a desarrollar una pequeña aplicación API en Sinatra. ¿Cuáles son las opciones de autenticación disponibles para proteger las llamadas a la API?

Author: chills42, 2010-08-13

2 answers

Sinatra no tiene soporte de autenticación incorporado. Hay algunas gemas disponibles, pero la mayoría están diseñadas para la autenticación de usuarios (es decir, para un sitio web). Para una API, parecen exageraciones. Es bastante fácil hacer el tuyo. Simplemente verifique los parámetros de solicitud en cada una de sus rutas para ver si contienen una clave API válida y, si no, devuelva un error 401.

helpers do
  def valid_key? (key)
    false
  end
end

get "/" do
  error 401 unless valid_key?(params[:key])

  "Hello, world."
end

#  $ irb -r open-uri
#  >> open("http://yourapp.com/api/?key=123")
#  OpenURI::HTTPError: 401 Unauthorized

No sucederá nada después de la llamada a error si su método valid_key? devuelve false - error llama a halt internamente, lo que detiene la solicitud de continuar.

Por supuesto, no es ideal repetir la comprobación al principio de cada ruta. En su lugar, puede crear una pequeña extensión que agregue condiciones a sus rutas:

class App < Sinatra::Base
  register do
    def check (name)
      condition do
        error 401 unless send(name) == true
      end
    end
  end

  helpers do
    def valid_key?
      params[:key].to_i % 2 > 0
    end
  end

  get "/", :check => :valid_key? do
    [1, 2, 3].to_json
  end
end

Si solo desea autenticación en todas sus rutas, use un controlador before:

before do
  error 401 unless params[:key] =~ /^xyz/
end

get "/" do
  {"e" => mc**2}.to_json
end
 88
Author: Todd Yandell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-14 08:41:27

Http://www.secondforge.com/blog/2014/11/05/simple-api-authentication-in-sinatra / tiene una respuesta un poco más detallada que utiliza tokens de usuario.

Este es un paso más complicado que una clave de API, pero es necesario si su API necesita autenticación para iniciar sesión en un usuario para hacer cosas como editar un nombre/correo electrónico/contraseña, o acceder a la información por usuario. (es decir, acciones API" privadas"). También puede revocar / caducar tokens de usuario para permitir a las personas cerrar sesión, etc.

class App < Sinatra::Base

  before do
    begin
      if request.body.read(1)
        request.body.rewind
        @request_payload = JSON.parse request.body.read, { symbolize_names: true }
      end
    rescue JSON::ParserError => e
      request.body.rewind
      puts "The body #{request.body.read} was not JSON"
    end
  end

  post '/login' do
    params = @request_payload[:user]

    user = User.find(email: params[:email])
    if user.password == params[:password] #compare the hash to the string; magic
      #log the user in
    else
      #tell the user they aren't logged in
    end
  end
end

(Es vale la pena señalar que es más común leer credenciales de un encabezado HTTP en lugar del cuerpo JSON, pero el autor lo menciona.)

 2
Author: chug2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-15 22:55:09