foxhound87
8/30/2017 - 1:16 AM

Authenticate on feathers-socketio connection with header

Authenticate on feathers-socketio connection with header

Authenticate on connection with feathers-socketio

This gist is an example of how you can coordinate between the socket client, socket server, and the feathers-authentication plugin to authenticate the socket.io connection using a request header. This saves you from having to call app.authenticate() in order to authenticate the socket. Instead, the socket connection will be ready to make authenticated requests, assuming the stored JWT accessToken is still valid.

const feathers = require('feathers/client')
const io = require('socket.io-client')
const axios = require('axios')
const socketio = require('feathers-socketio/client')
const auth = require('feathers-authentication-client')
const hooks = require('feathers-hooks')

const host = 'http://localhost:3030'
var socket = io(host, {
  transports: ['websocket'],
  // Send the authorization header in the initial connection request
  extraHeaders: {
    Authorization: window.localStorage.getItem('feathers-jwt')
  }
})

const feathersClient = feathers()
  .configure(socketio(socket, { timeout: 60000 }))
  .configure(hooks())
  .configure(auth())

// Listen to authentication events and set the new token on the feathersClient
feathersClient.service('authentication').on('created', response => {
  feathersClient.passport.setJWT(response)
})

return feathersClient
const jwt = require('jsonwebtoken')

module.exports = function ({ app, socket, userService = 'users' }) {
  const accessToken = socket.handshake.headers.authorization
  if (accessToken) {
    // Verify the JWT that was passed in
    jwt.verify(accessToken, app.get('authentication').secret, function (err, payload) {
      if (err) {
        console.log('invalid token', err)
      }

      // The JWT was valid, so request the user object
      app.service(userService).get(payload.userId)
        .then(user => {
        
          // This makes the user available at hook.params.user
          socket.feathers.user = user
        
          // Now create a new JWT
          return app.service('authentication').create({strategy: 'jwt', accessToken}, socket.feathers)
        })
        .then(response => {
        
          // And finally initiate a socket message to the client with response of `{accessToken}`
          socket.emit('authentication created', response)
        })
      
        // Yeah, yeah. This only handles the happy path. I said it was a hack. ;)
        .catch(error => {
          console.log(error)
        })
    })
  }
}
const socketio = require('feathers-socketio')
const authOnSocketConnect = require('./authenticate-on-socket-connect')

// ... Setup your Feathers app code or use the generator then replace the socketio registration with this

// When you register the feathers-socketio plugin, use the utility
app.configure(socketio(function (io) {
  // Get Socket.io headers
  io.on('connection', function (socket) {
    authOnSocketConnect({ app, socket })
  })
}, { timeout: app.get('socketTimeout') }))