node.jssocket.iofeathersjsfeathers-authentication

Authentication to Featherjs using socket.io-client


How can I authenticate to Feathersjs (https://docs.feathersjs.com/api/client/socketio.html#authentication) using Direct Connection (https://docs.feathersjs.com/api/client/socketio.html#direct-connection)? The following code says that my accessToken is malformed, but I suspect there's more than that to get it working. Where do I fetch an accessToken?

app.js (client):

import express from 'express';

const socket = require('socket.io-client')('http://localhost:3030', {
  transports: ['websocket']
});

socket.emit('authenticate', { 
  strategy: 'jwt',
  accessToken: 'what to enter here'
}, (message: any, data: any) => {
  console.log(message);
  console.log(data);
});

const app = express();

app.get('/', (req, res) => res.send('Up and running!'));

app.listen(4390, () => console.log('Example app listening on port 4390!'));

authentication.js (feathers server)

const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');
const local = require('@feathersjs/authentication-local');

module.exports = function (app) {
  const config = app.get('authentication');

  // Set up authentication with the secret
  app.configure(authentication(config));
  app.configure(jwt());
  app.configure(local());

  app.service('authentication').hooks({
    before: {
      create: [
        authentication.hooks.authenticate(config.strategies),
      ],
      remove: [
        authentication.hooks.authenticate('jwt')
      ]
    }
  });
};

I tried using the secret as an accessToken but it didnt work :) default.json (feathers server config)

"authentication": {
    "secret": "r323r32rada86700f18d82ea1d3e74fb58141dbefcd7460ef71736759265e347151a12d68dff50aa59c05e2f18db88661be8ae91a3f12932fddea8891b5ca9f63b5e4fc650edabc59d0d14e8fe4ea54256e7e386845321ab58a320a9ec99438bd058a3fbbda65dadf97bc9585ea82f72201f932beqwdqwdqwd5761a0d0be3e95474db5b9c8a3f4c7303beed0344a1768ba5dad6a1c916d183ea5dd923587768661ff0b08f25ed85dff4ff4e6b58327fe5914e5e7fb2356ee67754b102434f22686444a35fc38c75bcdd6386240a22e0cf62bdc7f227200868da387174b365af2afa7dec378c4ccf22956b134a3ec961fd1ba8d3dc85a7594ab711",
    "strategies": [
      "jwt",
      "local"
    ],
    "path": "/authentication",
    "service": "users",
    "jwt": {
      "header": {
        "typ": "access"
      },
      "audience": "https://yourdomain.com",
      "subject": "anonymous",
      "issuer": "feathers",
      "algorithm": "HS256",
      "expiresIn": "1d"
    },
    "local": {
      "entity": "user",
      "usernameField": "email",
      "passwordField": "password"
    }
  },
...

Thankful for all replies!


Solution

  • Thank you @mchaffe! I managed to solve it with your help. Here is the code used:

    import dotenv from 'dotenv';
    
    // Load environments
    const config = dotenv.config()
    if (config.error) throw config.error
    
    const io = require('socket.io-client');
    const feathers = require('@feathersjs/client');
    const localStorage = require('localstorage-memory');
    
    const client = feathers();
    
    const socket = io('http://localhost:3030/', {
      transports: ['websocket'],
      forceNew: true
    });
    
    client.configure(feathers.socketio(socket), {
      timeout: 10000
    });
    
    client.configure(feathers.authentication({
      jwtStrategy: 'jwt',
      storage: localStorage,
      storageKey: 'some-token'
    }));
    
    const payload = {
      strategy: 'local',
      email: process.env.FEATHERS_AUTHENTICATION_EMAIL,
      password: process.env.FEATHERS_AUTHENTICATION_PASSWORD
    };
    
    client.authenticate(payload).then((response: any) => {
      // Do stuff to hooray here
      console.log('Access Token: ' + response.accessToken);
    
      // Works!
      socket.emit('get', 'logger', 1, (error: any, log: any) => {
        console.log('Found log: ' + JSON.stringify(log));
      });
    
    }).catch((e: any) =>  {
      console.log('Error: ' + e); 
    });
    
    

    I am all ears if you have suggestion on improvements! :) It seems I can access data from the database using the socket.emit method. Do I need to verify the accessToken returned? Thanks again!