Tema 3, Programación en el cliente con Javascript Parte IV: Acceso a APIs REST Tema 3. Programación en el cliente con Javascript Parte IV: Acceso a APIs REST 1. Peticiones REST con Javascript Remember REST • Las llamadas al API se implementan como peticiones HTTP, en las que: • La URL representa el recurso http://muevete.com/api/peticiones/1 • El método HTTP representa la operación GET http://muevete.com/api/peticiones/1 • El código de estado HTTP representa el resultado 200 OK HTTP/1.1 404 NOT FOUND HTTP/1.1 • Como formato de intercambio de datos usaremos un estándar • Preferentemente JSON por su facilidad de manejo desde Javascript Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Creación de recursos • Por ejemplo, firmar una petición • En general, la URL estará “abierta” (el recurso todavía no existe y por tanto no tiene id) http://muevete.com/api/peticiones/3/firmas • El método debe ser POST • Excepción: si sabemos qué id queremos darle, usaremos PUT • El cliente debe enviar al servidor una representación del recurso a crear, se puede hacer • En los parámetros de la petición (al ser POST irán físicamente al final de la petición, o sea, se envían en el send del XMLHttpRequest) email=adi%40ua.es&fecha=2013-10-10&comentario=Creo%20que... • En el cuerpo de la petición en formato JSON {“email”=”[email protected]”, “fecha”=”2013-10-10”, ... } Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Implementación con AJAX • Versión con JSON xhr.open('POST', 'api/peticiones/' + idPeticion + "/firmas" , true) xhr.onreadystatechange = function() { ... } xhr.setRequestHeader("Content-type", "application/json") var firma = {}; firma.email = document.getElementById("email").value; firma.comentario = document.getElementById("comentario").value ... firma.publica = document.getElementById("publica").checked; xhr.send(JSON.stringify(firma)) Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Crear recurso: resultado • Resultados posibles: • 403 (Acceso prohibido) • 400 (petición incorrecta, p.ej. falta un campo o su valor no es válido) • 500 (Error del lado del servidor al intentar crear el recurso, p.ej. se ha caído la BD) • 201 (Recurso creado correctamente) • ¿Qué URL tiene el recurso recién creado? • La convención en REST es devolverla en la respuesta como valor de la cabecera HTTP Location xhr.open('POST', 'api/peticiones/' + idPeticion + "/firmas" , true) xhr.onreadystatechange = function() { if (this.readyState==4) if (this.status==201) var url = this.getResponseHeader(“Location”) } ... Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Actualizar recurso • Método PUT • Según la ortodoxia REST, actualizar significaría cambiar TODOS los datos • PATCH es un nuevo método estándar HTTP (2010) pensado para cambiar solo ciertos datos. Muchos frameworks de programación REST todavía no lo soportan • Resultados posibles • Errores ya vistos con POST • 201 (Recurso creado, cuando le pasamos el id deseado al servidor) • 200 (Recurso modificado correctamente) Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Eliminar recurso • Método DELETE • Algunos resultados posibles • 200 OK • 404 Not found • 500 Server error • Tras ejecutar el DELETE con éxito, las siguientes peticiones GET a la URL del recurso deberían devolver 404 Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Tema 3. Programación en el cliente con Javascript Parte IV: Acceso a APIs REST 2. Seguridad: autentificación y autorización Sesiones • Recordemos que HTTP es un protocolo “sin estado” • De un ciclo petición/respuesta al siguiente ni cliente ni servidor recuerdan nada (Hi, I’m a server!!) • Pero en la mayoría de aplicaciones web del MundoReal™ existe el concepto de “sesión” • Sí se recuerdan ciertos datos mientras vamos navegando entre páginas (usuario autentificado, carro de la compra, ...) • Cookies: extensión al protocolo HTTP que permite a cliente y servidor almacenar datos “persistentes” entre ciclos petición/ respuesta Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Cookies • Pares nombre=valor. A partir del momento en que se crean, el navegador las envía con cada petición HTTP al servidor desde el que se crearon Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Mantenimiento de sesiones • La mayor parte de frameworks de programación en el lado del servidor generan automáticamente cookies pseudoaleatorias lo suficientemente largas para ser usadas como “id de sesión” • Esto permite almacenar datos en el servidor exclusivos de cada usuario • El “id de sesión” sirve como “clave” para recuperar los datos Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante Autentificación con sesiones • Tras hacer login correctamente, el servidor guarda en la sesión un flag indicando que el cliente se ha autentificado correctamente use Rack::Session::Pool, :expire_after => 60*60 get '/entrar' do if (params[:login] ... #aquí habría que comprobar si el login es correcto session[:usuario] = params[:login] end get '/ver' do if (session[:usuario].nil?) status 403 else "hola #{session[:usuario]}" end end get '/salir' do session.clear "adios" end Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante ¡Pero esto no es RESTful! • Según REST no debe haber estado • Otra posibilidad: enviar las credenciales en cada petición restringida • Precisamente eso hace HTTP Basic, dentro del estándar HTTP. • Si el cliente sabe que un recurso está protegido puede enviar en la cabecera Authorization el login y el password con codificación Base64 • No es un mecanismo de cifrado, es solo para poder enviar correctamente cualquier carácter por HTTP • En HTTP Digest se hace un hash MD5 de login y password, lo que mejora bastante la seguridad • Si el cliente intenta inadvertidamente acceder a un recurso protegido con HTTP Basic el servidor respondería con un código de estado 401. Si no es con AJAX el navegador mostraría el típico cuadro de diálogo de login Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante OAuth • Nació para que aplicaciones pudieran acceder a servicios de terceros sin que el usuario tuviera que proporcionarle a la app sus credenciales del servicio • Ejemplo: una app que permite publicar en tu muro de FB, pero en la que no confías lo suficiente como para meter tu login y password de FB • Es el estándar en APIs REST abiertos a terceros • Algunos también lo usan para acceso a APIs propios • Se basa en el uso de un token de sesión Aplicaciones Distribuídas en Internet 2013-14 / Univ. Alicante