-
Node
- Express
- Nodemon
- Cors
- Formidable
- Dotenv
- Bcryptjs
- JSON Web Token
-
Gestionar usuarios en el servidor
- Rutas para control de usuarios.
- Oauth2 (Pendiente)
- JWT
- Guardar credencial en cliente
-
Persistencia de datos
- MongoDB
- Express + Moongose
-
API REST
- Especificación de la API
- Subir rutas
- Subir ficheros
- Editar rutas
- Descargar actividades
- Paginación de la descarga
- Eliminar rutas.
- Listar usuarios 6.1 Hacer/Eliminar seguidores
-
Cliente REACT
- Pantallas y navegación de la interfaz.
- Gestión de credenciales y login.
- Subida de actividades
- Gestíon de seguidores
- Timeline
Node.js es el software elegido para desarrollar la parte servidor. Los módulos disponibles desde NPM permiten añadir funcionalidad sobre la base de Node, conviertiéndolo en una herramienta perfecta para desarrollos seguros y rápidos.
Para instalar Express:
npm i express
Express nos permite:
- Emplear middlewares: Se ejecutan entre que se recibe la petición y se da una respuesta. Nos permite ir añadiendo capas intermedias en este procesamiento como middlewares. Se usan para:
- Convertir el cuerpo de la petición a un objeto JSON:
app.use(express.json());
. - Emplear Router de Express para procesar peticiones y organizar nuestras rutas de manera modular.
- Convertir el cuerpo de la petición a un objeto JSON:
El servidor escucha por defecto en el puerto 3000.
Nodemon es una herramienta que permite reiniciar una aplicación de node cada vez que se detecta un cambio en cualquier fichero del directorio donde se ejecuta.
Para ejecutar el servidor se ha creado el script start en package.json para lanzar el index.js cada vez que haya cambios:
nodemon index.js
El paquete cors de NPM permite gestionar el cors de manera casi transparente como un middleware de Express.
Formidable NPM es un middleware de Node que convierte las peticiones de un formulario que se forma con un Formdata para que se encuentren disponibles en la petición dentro de: req.fields
y req.files
. Es fundamental para manejar muchas de las peticiones que vienen desde el cliente mediante un formulario.
Dotenv permine incluir variables de estado para guardar información de manera segura sin que se encuentre en el código JS.
Bcryptjs es un paquete de NPM que se emplea para encriptar las contraseñas en las bases de datos.
JSON Web Token es una implementación de la tecnología de Web Tokens. Permite generar tokens a partir de un secreto que guarda el servidor. Sólo el servidor puede generar los tokens.
toGeoJeson es una librería que permite convertir ficheros KML y GPS a GeoJSON. Al realizar la conversión devuelve un objeto con la representación en GeoJSON .
Se diferencian dos servicios principales. La API para gestionar el login y la API para gestionar las peticiones de los usuarios en la ejecución de la web.
Para las rutas de gestión de usuarios se empleará el siguiente prefijo: /api/auth/. Con las siguientes subrutas:
- /signin: Crea una cuenta nueva de usuario. Un usuario es un objeto con las siguientes características:
let usuario = {
_id: 1, //Auto generado - Obligatorio - Automático
nombre: "Jesús", //Mínimo 3 caracteres. - Obligatorio
apellidos: "Redondo García", //Mínimo 3 caracteres - Obligatorio
email: "redondogarciajesus@gmail.com", //Bien formado - Obligatorio
password: "2134skjd2345kbsdf", //Encriptada - Obligatorio
imagen: "https://....", //Url de la imagen
createdAt: 2020-10-13T17:54:42.911+00:00, //Fecha creación - Automático
updatedAt: 2020-10-13T17:54:42.911+00:00, //Fecha modificación - Automático
__v: 0 //Versión - Automático
}
- /login: Permite autentificar a un usuario. Un usuario se autentifica enviando un objeto como el siguiente:
let objLogin = {
email: "redondogarciajesus@gmail.com", //Bien formado - Obligatorio
password: "2134skjd2345kbsdf", //Encriptada - Obligatorio
}
La respuesta ante un login tiene la siguiente forma:
let objLoginDevuelto = {
_id: 1,
nombre: "Jesús",
apellidos: "Redondo García",
email: "redondogarciajesus@gmail.com",
imagen: "https://....",
}
Además en la respuesta se incluirá la siguiente cabecera HTTP, siguiendo la expecificación propuesta por la documentación de JWT y Bearer Token.
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"mF_9.B5f-4.1JqM",
"token_type":"Bearer"
}
De esta manera el usuario termina el proceso de autenticación, obteniendo el Token JWT. Cada futura petición que necesite autorización irá acompañada de la siguiente cabecera, tal y como especifica la documentación anteriormente mencionada:
GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer mF_9.B5f-4.1JqM
Este modelo de autorización permite que cliente y servidor no tengan que guardar estado sobre la sesión. Perfecto para emplear en conjunción con las API REST.
La comunicación entre el servidor y el cliente se realiza a través de una API REST. De este modo nos aseguramos desacoplar totalmente las dos partes que conforman la aplicación, permitiendo:
- Cambiar o substituir el servidor sin tener que modificar el cliente y viceversa.
- Asegurarnos de que todas las peticiones no necesitan guardar sesión o estado, lo que hace mucho más simple la comunicación.
- Utilizar estándars web de comunicación. Empleo de HTTP + JSON + peticiones asíncronas por los clientes.
Toda la gestión de la api colgará de la ruta /api
Dependiendo de la tarea en concreto, se gestionará en un Router diferente.
Todas las rutas de la API están protegidas con autentificación de usuario.
Veremos esas subrutas en cada uno de los siguientes puntos.
Las rutas para subir datos parten de /api/upload/
, son las siguientes:
-
Subida de fotos para el usuario:
-
Subida de ficheros de rutas:
/api/upload/routeGPX
POST: Sube un fichero GPX directamente. Convertirá el fichero a GeoJSON.. la conversión tiene la siguiente estructura:
{ type: 'FeatureCollection',
features:
[ { type: 'Feature', //Aquí empieza un objeto feature, que es lo que almaceno.
properties:
{ name: 'Tempo ride 🔥',
type: '1',
time: '2020-11-21T08:42:15Z',
_gpxType: 'trk',
coordTimes:
['2020-11-21T08:42:15Z',
'2020-11-21T08:42:16Z', ...
],
heartRates:
[ 68,
68,...
],
geometry:
{ type: 'LineString',
coordinates:
[ [ -6.375398, 39.468687, 548 ],
[ -6.375277, 39.468732, 548.4 ],...
]
}
}
}
]
}
- La subida comprueba que no exista otra actividad con esa misma fecha para dicho usuario. Si no existe, entonces la sube.
Las rutas para consultar los usuarios parten de /api/usuarios/
, son las siguientes:
-
De usuarios:
-
/api/usuarios/
GET: Devuelve todos los usuarios del sistema. -
/api/usuarios/yo
GET: Devuelve mi usuario de vuelta. -
/api/usuarios/follow
GET: Devuelve todos los usuarios a los que sigo en el sistema. -
/api/usuarios/followers
GET: Devuelve todos los usuariosque me siguen. -
/api/usuarios/follow/[_id_usuario]
POST: El usuario que realiza la llamada comienza a seguir al usuario con id _id. -
/api/usuarios/unfollow/[_id_usuario]
POST: El usuario que realiza la llamada deja de seguir al usuario con id _id.
-
Las rutas de las actividades parten de /api/actividades/
. Son las siguientes:
- De actividades:
-
/api/actividades/
GET: Devuelve todas las actividades del usuario que realiza la petición. TODO: Debería poder filtrarse por campos las actividades. -
/api/actividades/[_id_actividad]
GET: Devuelve la actividad con _id = '_id'. -
/api/actividades/usuario/[_id_usuario]
POST: Devuelve las actividades del usuario con id = '_id' -
/api/actividades/follow/
GET: Devuelve las actividades de los usuarios que sigo.
-
Las rutas de los mensajes parten de /api/comentarios/
. Son las siguientes:
- De mensajes:
-
/api/comentarios/[_id_actividad]
GET: .Devuelve todos los comentarios de una actividad. -
/api/comentarios/[_id_actividad]
POST: .Introduce el comentario que viene en el cuerpo del post en el campo comentario.
-
4. Descargar actividades
1. Paginación de la descarga
5. Eliminar rutas.
6. Listar usuarios
6.1 Hacer/Eliminar seguidores
La documentación que se ha empleado como base para este proyecto es esta web.
Capacitor Storage Plugin:
ROUTING:
-
IntroGuard: Checkea si el usuario ya ha visto la intro. La muestra si no la hubiese visto. Se usa para el Splash screen.
-
AutoLoginGuard: Automáticamente loguea un usuario al inicio de la aplicación si ya se hubiese logueado anteriormente.
-
AuthGuard: Asegura el acceso de las páginas internas de la APP.
NOTAS: Podemos usar varias guardas para una página, podemos usar canLoad en lugar de canActivate ya que esto protejerá todo el "lazy loading", incluso no cargará el fichero si el usuario no tiene esa ruta permitida.
Al asegurar la ruta /tabs al nivel superior ya estaremos asegurando cada otra ruta o página que podríamos añadir después a nuestro routind de tabs, ya que la guarda siempre se aplicaría en este caso.
PÁGINA DE INTRODUCCIÓN: Podríamos hacer que siempre se mostrase la página de introducción al usuario, pero podría a ser molesto con el uso contínuo de la app. Por eso, hacemos una guarda que nos comprueba si ya hemos visto la página de inicio, en cuyo caso nos redirecciona a la página que queremos ver en lugar de a la introducción.
NOTAS: PARA EJERCUTAR EN ANDROID: https://ionicframework.com/docs/cli/commands/capacitor-run
COMPONENTES DE IONIC: https://ionicframework.com/docs/components
AÑADIR MAPA DE LEAFLET: https://edupala.com/how-to-add-leaflet-map-in-ionic/