max-mapper / auth-socket

pluggable authentication API for http, websockets, etc
7 stars 1 forks source link

API for other services #1

Open Raynos opened 10 years ago

Raynos commented 10 years ago

We talked about changing the API up to be more forgiving for other authentication services.

I made a gist ( https://gist.github.com/Raynos/7651349 )

The idea is simple, auth-socket at it's simplest should be

function auth(req, socket, head, callback) {}

and it should do callback(err) or callback(err, user) or callback(err, null) where null means anonymous

As a user you want to do something like

var AuthSocket = require("auth-socket")

var auth = AuthSocket({
  allowAnonymous: true,
  authHandler: function (req, socket, head, cb) {
    // read cookie
    // read session
    // return the user from session store
  },
  // OR
  authHandler: doorKnob.createAuthHandler()
  // OR
  authHandler: githubOAuth.createAuthHandler()
})

With that kind of API you don't have to build a massive switch in auth-socket to support doorknob & github oauth & redsess & level-session & bla bla.

In the gist i also showed this example

var http = require("http")
var WebsocketServer = require("ws").Server
var Router = require("routes-router")
var AuthSocket = require("auth-socket")

var app = Router()
var auth = AuthSocket({
    authHandler: function (req, socket, head, cb) {}
})
var server = http.createServer(app)

var wss = new WebsocketServer({ noSserver: true })
wss.on("connection", function (stream, user) {
  // if `user` is null then it's anonymous
})

server.on("upgrade", auth.handleUpgrade(ws))

server.listen(3000)

Which is the higher level way of using it with auth.handleUpgrade. Note this api means auth-socket does not depend on http or ws and nor does it create servers for you.

We can have an even less lines of code api similar to the current api if wanted

Raynos commented 10 years ago

One benefit of the low level api is that I could create a websocket server that accepts all streams. MuxDemux it and then try authenticate just sub streams.

This means we can have both public and authenticated websocket apis in one server.

We may also want to consider simplifying the authHandler like (req, cb) {}.

There is also an alternative type of authentication you can do which would look like (stream, cb) {} where stream is a websocket connection. i.e. authentication could be a handshake over the websocket connection. This would require handling the upgrade for all websockets and then doing auth.

max-mapper commented 10 years ago

worked on this a little, try cloning and doing npm install and npm start in one tab, and npm run watch in another

then open:

http://localhost:8080/socket.html (user should be null)

and

http://localhost:8080/socket.html?hello=hello (user should be 'bob')

max-mapper commented 10 years ago

also I couldn't get wss.on("connection" to fire when using wss.handleUpgrade, maybe its a bug in ws??

max-mapper commented 10 years ago

ahh they emit it here https://github.com/einaros/ws/blob/master/lib/WebSocketServer.js#L72-L75

but if you use handleUpgrade manually it won't emit a connection event :(

max-mapper commented 10 years ago

ok just published v1.0.0, check it out :D

Raynos commented 10 years ago

@maxogden I had to emit a connection event myself ( https://gist.github.com/Raynos/7651349#file-auth-socket-js-L29 )

Raynos commented 10 years ago

@maxogden nice. the client one looks good. the doorknob / persona one doesn't use auth yet.