# socketio-auth

> Authentication for socket.io

Latest version **0.1.1** (published 2018-05-14) · ISC license · 0 weekly downloads

## Install

```sh
npm install socketio-auth
pnpm add socketio-auth
yarn add socketio-auth
bun add socketio-auth
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.1 |
| Published | 2018-05-14 |
| First published | 2014-10-16 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 15.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Facundo Olano and Martín Paulucci |
| Maintainers | facundoolano |
| Keywords | socket, socket.io, authentication, auth, invisible.js |

## Links

- npm: https://www.npmjs.com/package/socketio-auth
- Repository: https://github.com/facundoolano/socketio-auth
- Issues: https://github.com/facundoolano/socketio-auth/issues
- npm.io page: https://npm.io/package/socketio-auth

## Dependencies (2)

- [debug](https://npm.io/package/debug.md) ^2.1.3
- [lodash](https://npm.io/package/lodash.md) ^4.17.5

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 0.1.1 (latest) — 2018-05-14
- 0.1.0 — 2016-10-20
- 0.0.5 — 2015-11-04
- 0.0.4 — 2015-08-24
- 0.0.3 — 2015-06-06
- 0.0.2 — 2015-05-09
- 0.0.1 — 2014-10-16

## README

# socketio-auth [![Build Status](https://secure.travis-ci.org/facundoolano/socketio-auth.png)](http://travis-ci.org/facundoolano/socketio-auth)

This module provides hooks to implement authentication in [socket.io](https://github.com/Automattic/socket.io) without using querystrings to send credentials, which is not a good security practice.

Client:
```javascript
var socket = io.connect('http://localhost');
socket.on('connect', function(){
  socket.emit('authentication', {username: "John", password: "secret"});
  socket.on('authenticated', function() {
    // use the socket as usual
  });
});
```

Server:
```javascript
var io = require('socket.io').listen(app);

require('socketio-auth')(io, {
  authenticate: function (socket, data, callback) {
    //get credentials sent by the client
    var username = data.username;
    var password = data.password;

    db.findUser('User', {username:username}, function(err, user) {

      //inform the callback of auth success/failure
      if (err || !user) return callback(new Error("User not found"));
      return callback(null, user.password == password);
    });
  }
});
```

The client should send an `authentication` event right after connecting, including whatever credentials are needed by the server to identify the user (i.e. user/password, auth token, etc.). The `authenticate` function receives those same credentials in 'data', and the actual 'socket' in case header information like the origin domain is important, and uses them to authenticate.

## Configuration

To setup authentication for the socket.io connections, just pass the server socket to socketio-auth with a configuration object:

```javascript
var io = require('socket.io').listen(app);

require('socketio-auth')(io, {
  authenticate: authenticate,
  postAuthenticate: postAuthenticate,
  disconnect: disconnect,
  timeout: 1000
});
```

The supported parameters are:

* `authenticate`: The only required parameter. It's a function that takes the data sent by the client and calls a callback indicating if authentication was successfull:

```javascript
function authenticate(socket, data, callback) {
  var username = data.username;
  var password = data.password;

  db.findUser('User', {username:username}, function(err, user) {
    if (err || !user) return callback(new Error("User not found"));
    return callback(null, user.password == password);
  });
}
```
* `postAuthenticate`: a function to be called after the client is authenticated. It's useful to keep track of the user associated with a client socket:

```javascript
function postAuthenticate(socket, data) {
  var username = data.username;

  db.findUser('User', {username:username}, function(err, user) {
    socket.client.user = user;
  });
}
```
* `disconnect`: a function to be called after the client is disconnected.

```javascript
function disconnect(socket) {
  console.log(socket.id + ' disconnected');
}
```

* `timeout`: The amount of millisenconds to wait for a client to authenticate before disconnecting it. Defaults to 1000. The value 'none' disables the timeout feature.

## Auth error messages

When client authentication fails, the server will emit an `unauthorized` event with the failure reason:

```javascript
socket.emit('authentication', {username: "John", password: "secret"});
socket.on('unauthorized', function(err){
  console.log("There was an error with the authentication:", err.message);
});
```

The value of `err.message` depends on the outcome of the `authenticate` function used in the server: if the callback receives an error its message is used, if the success parameter is false the message is `'Authentication failure'`

```javascript
function authenticate(socket, data, callback) {
  db.findUser('User', {username:data.username}, function(err, user) {
    if (err || !user) {
      //err.message will be "User not found"
      return callback(new Error("User not found"));
    }

    //if wrong password err.message will be "Authentication failure"
    return callback(null, user.password == data.password);
  });
}
```

After receiving the `unauthorized` event, the client is disconnected.

## Implementation details

**socketio-auth** implements two-step authentication: upon connection, the server marks the clients as unauthenticated and listens to an `authentication` event. If a client provides wrong credentials or doesn't authenticate after a timeout period it gets disconnected. While the server waits for a connected client to authenticate, it won't emit any broadcast/namespace events to it. By using this approach the sensitive authentication data, such as user credentials or tokens, travel in the body of a secure request, rather than a querystring that can be logged or cached.

Note that during the window while the server waits for authentication, direct messages emitted to the socket (i.e. `socket.emit(msg)`) *will* be received by the client. To avoid those types of messages reaching unauthorized clients, the emission code should either be defined after the `authenticated` event is triggered by the server or the `socket.auth` flag should be checked to make sure the socket is authenticated.

See [this blog post](https://facundoolano.wordpress.com/2014/10/11/better-authentication-for-socket-io-no-query-strings/) for more details on this authentication method.

---
_Source: https://npm.io/package/socketio-auth · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
