Feathers: Autenticación siguiente

Creado en 6 oct. 2018  ·  10Comentarios  ·  Fuente: feathersjs/feathers

Ya escribí un poco sobre esto en la actualización de la hoja de ruta de Feathers Crow . Este problema está destinado a recopilar todos los problemas relacionados que cubrirá la próxima versión de autenticación de Feathers.

Marco independiente

Con la versión actual (Buzzard), el núcleo de Feathers se volvió completamente independiente del marco, sin embargo, el complemento de autenticación todavía está registrando algunos middleware Express. En la próxima versión, el middleware se moverá a @ feathersjs / express y hará que el núcleo de autenticación también sea independiente del marco. Esto permitirá nuevos transportes como Koa o MQTT.

Autenticación de socket mejorada

Actualmente, los websockets se autentican y se desconectan a través de un mecanismo de eventos personalizado. Esto estaba causando algunos problemas (por ejemplo, errores infrecuentes de "No auth token"), especialmente en torno a la reconexión confiable en ambos lados, el servidor y el cliente.

Cliente de autenticación mejorado

Esto eliminará la dependencia del token de acceso con estado y manejará elegantemente la reautenticación del socket.

No más cookies, oAuth mejorado

Feathers es una biblioteca para crear API utilizando JWT para la autenticación. El único caso en el que una configuración de Plumas normal utiliza cookies es para pasar el JWT al navegador después de un flujo de autenticación de oAuth (Facebook, Google, etc.). El nuevo cliente de autenticación y oAuth ya no utilizará cookies y dividirá el flujo de oAuth en dos partes en lugar de intentar hacer todo a la vez. El token de acceso de oAuth se configurará en un hash de URL compatible con todos los dominios (solo accesible localmente) que luego se puede intercambiar por un JWT utilizando el mecanismo de autenticación estándar de Feathers.

Mejor manejo de opciones

Todas las configuraciones de autenticación ahora se evaluarán en tiempo de ejecución, por lo que es posible configurarlas dinámicamente y no habrá errores para las opciones que no son necesarias. También permitirá pasar un servicio de autenticación personalizado.

Actualizar tokens y listas negras

En lugar de permitir la actualización con el JWT existente, el servicio de autenticación estándar ahora también devolverá un token de actualización de mayor duración. La lista negra de tokens aún debe implementarse manualmente, pero será más fácil de integrar a través de los métodos en el nuevo servicio de autenticación.

Authentication Breaking Change

Comentario más útil

Puede ver el progreso actual en la rama maestra y publicaré una publicación de blog cuando los probadores beta puedan probarlo. El estado es:

| Módulo | Código | Docs | CLI
| --- |: ---: |: ---: | ---: |
| @ feathersjs / autenticación | ✅ | 100% | ❌ |
| @ feathersjs / authentication-local | ✅ | 80% | ❌ |
| @ featherjs / authentication-oauth | ✅ | 90% | ❌ |
| @ feathersjs / authentication-client | ✅ | 80% | ❌ |

Todos 10 comentarios

Dar de baja el pasaporte

Esta discusión comenzó en el n. ° 844 y en https://github.com/feathersjs/feathers/issues/844#issuecomment -390123148 ​​resume los puntos por los que sucede esto. En resumen, no ha habido mucho desarrollo en PassportJS, especialmente en lo que respecta a los marcos de soporte que no sean Express y la mayoría de los otros marcos HTTP como Koa o Hapi pasaron a usar bibliotecas de autenticación más flexibles y minimalistas (como https://github.com/simov/grant para oAuth). También resultó que solo hay cuatro tipos de estrategias que son realmente necesarias:

  • Local (nombre de usuario / contraseña)
  • JWT
  • oAuth (+ token de acceso oAuth)
  • Clave API

Sin tener que trabajar con Passport, Feathers puede ubicarse fácilmente sobre cualquier biblioteca HTTP y cualquier otro mecanismo de transporte (como MQTT o incluso conexiones P2P) con una clara separación de preocupaciones y proporcionar un mecanismo de autenticación que es mucho más fácil de entender y personalizar.

Usando params.authentication

En el lado de Feathers, configurar params.authentication en una llamada de servicio será la _ única_ forma de proporcionar información de autenticación. params.authentication contendrá la información necesaria para autenticar la llamada de servicio y estará en el formato de, por ejemplo, { strategy: 'local', email: 'email', password: 'password' } que ya se está utilizando:

// Call `find` with a given JWT
app.service('messages').find({
  authentication: {
    strategy: 'jwt',
    accessToken: 'someJWT'
  }
});

La persona que llama (como un transporte REST o websocket, un gancho o una prueba unitaria) será responsable de pasar params.authentication . Esto significa que no habrá más confusión si el authenticate ejecuta para llamadas internas o no o de dónde proviene realmente la información de autenticación.

El gancho authenticate

El gancho authenticate seguirá existiendo. Tomará una lista de nombres de estrategias y

  • Continúe con el siguiente gancho con la primera estrategia que no arrojó un error y combine su valor de retorno (ver más abajo) en params
  • O lanzar el error de la primera estrategia que falló si todas las estrategias fallaron

    Si params.authentication contiene un strategy nombre, solo se llamará a esa estrategia. De lo contrario, se llamarán todas las estrategias. Si params.authentication no se establece en absoluto, el gancho

  • Lanzar un error para llamadas externas

  • Continúe como de costumbre para las llamadas internas (por ejemplo, al configurar params.user manualmente)
app.service('messages').hooks({
  before: authenticate('jwt', 'local', 'anonymous')
});

Estrategias de autenticación

Una estrategia de autenticación básica es un objeto con un método authenticate que obtiene los datos de params.authentication y devuelve un objeto de éxito o arroja un error si no tuvo éxito:

const { Forbidden } = require('@feathersjs/errors');

const daveStrategy = {
  async authenticate (authParams) {
    const { username, password } = authParams;

    if (username === 'david' && password === 'secret') {
      return {
        user: {
          name: 'Dave',
          admin: true
        }
      };
    }

    throw new Forbidden('Not super Dave');
  }
};

app.authentication.registerStrategy('superdave', daveStrategy);

En el gancho authenticate , el objeto devuelto se fusionará con la llamada de servicio params por lo que este ejemplo establecería params.user .

Ampliación de estrategias

Las estrategias de autenticación pueden contener y llamar a métodos adicionales internamente. Las estrategias de Feathers se implementarán como clases que se pueden personalizar a través de la extensión (esto reemplazará a los Verificadores y básicamente combina la estrategia y el verificador en una sola clase):

class LocalStrategy {
  constructor(app);
  async findUser(authParams);
  async comparePassword(user, password);
  async authenticate (authParams);
}

class MyLocalStrategy extends LocalStrategy {
  async findUser(authParams);
}

app.authentication.registerStrategy('local', new MyLocalStrategy(app));

Análisis de HTTP

Una estrategia también puede proporcionar un método parse que obtendrá una solicitud y respuesta HTTP de nodo básico y debería devolver el valor de params.authentication (o null ):

const daveStrategy = {
  async authenticate (authParams) {
    throw new Forbidden('Not super Dave');
  }

  async parse (req, res) {
    const apiKey = req.headers['x-super-dave'];

    if (apiKey) {
      return {
        strategy: 'superdave',
        apiKey
      }
    }

    return null;
  }
};

Las bibliotecas HTTP pueden decidir si usan esos métodos y cómo lo hacen para configurar params.authentication o autenticar su propio middleware.

app.authenticate

app.authenticate(authParams, [ strategies ]) ejecutará las estrategias dadas con los parámetros de autenticación dados:

// Will return the user for a JWT (on the server)
const { user } = app.authenticate({ accessToken }, 'jwt');

configurar params.authentication en una llamada de servicio será la _única_ forma de proporcionar información de autenticación.

¿Podría explicar los puntos de diseño sobre por qué era necesario proporcionar accessToken en cada llamada service() ?

Esto solo se aplica al servidor y es lo que ya ocurre implícitamente a través de params.provider y params.headers (en el caso de websockets, estos son solo encabezados falsos) que se establecen para cada llamada de servicio una vez configurada la autenticación. Esto rompió la separación de Feathers entre los servicios y ganchos independientes del protocolo de transporte y el mecanismo de transporte real (como HTTP con Express o Socket.io) y lo hizo realmente confuso cuando, por ejemplo, un gancho authenticate('jwt') realmente se ejecuta y para qué se usa su información de autenticación.

En cuanto a la usabilidad, nada cambiará realmente para las llamadas externas o internas, pero si ahora desea activar el gancho authenticate explícitamente en el servidor, siempre puede configurar params.authentication . Esto es especialmente importante para los nuevos complementos de marco que no sean Express (por ejemplo, Koa, HTTP2 o una cola de mensajería) que ahora tienen una forma estandarizada de pasar su información de autenticación al mecanismo de autenticación de Feathers.

El cliente de autenticación seguirá realizando solicitudes autenticadas una vez que haya iniciado sesión llamando a app.authenticate() .

Gracias por aclararlo. Tengo muchas ganas de probar con v3, particularmente con los clientes de socket.io React Native.

Definitivamente pondré la información sobre los prelanzamientos aquí. Simplemente cerrando el cliente de autenticación que debería manejar websockets autenticados de manera mucho más confiable. Una vez hecho esto, sería genial tener ayuda para probar la nueva autenticación core + local y jwt. oAuth debería seguir pronto después de eso.

cuando salga la versión 3?

¿Alguna respuesta a mi pregunta?

Puede ver el progreso actual en la rama maestra y publicaré una publicación de blog cuando los probadores beta puedan probarlo. El estado es:

| Módulo | Código | Docs | CLI
| --- |: ---: |: ---: | ---: |
| @ feathersjs / autenticación | ✅ | 100% | ❌ |
| @ feathersjs / authentication-local | ✅ | 80% | ❌ |
| @ featherjs / authentication-oauth | ✅ | 90% | ❌ |
| @ feathersjs / authentication-client | ✅ | 80% | ❌ |

¡Hola, esto es genial!

La flexibilidad futura es genial, pero todavía no tengo confianza con la autenticación en mi proyecto FeathersJS y estoy pasando por un proceso confuso para crearlo.

Tener una implementación de autenticación completa, probada y segura significa que puedo pasar con confianza a las funciones. Una de las mejores razones para usar MeteorJS fue su excelente integración de cuentas hasta el cliente.

Al analizar los problemas de FeatherJS, muchos se refieren a la autenticación, ¡así que estoy emocionado de que llegue este trabajo!

¿Dónde se encuentra la mejor documentación (o implementación de referencia) para un sistema de autenticación seguro completo (autenticación local, control de acceso, correos electrónicos, etc.) en FeathersJS hoy?

Esto es lo que tengo hasta ahora, ¿hay algo mejor?

2018/02 - Configuración de la verificación de correo electrónico en FeathersJS (refrito del artículo de 2017)
2018/02 - Repo del artículo anterior
2017/01 - Cómo configurar la verificación de correo electrónico en FeathersJS (roto)
2018/06 - Autenticación de Vue con Feathersjs

¡Gracias por adelantado!

Todos los problemas relacionados ahora se han cerrado y la versión preliminar de Feathers v4 con todos los cambios propuestos implementados está disponible para probar. Consulte la guía de migración para obtener más información.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

rstegg picture rstegg  ·  3Comentarios

perminder-klair picture perminder-klair  ·  3Comentarios

arkenstan picture arkenstan  ·  3Comentarios

arve0 picture arve0  ·  4Comentarios

codeus-de picture codeus-de  ·  4Comentarios