Skip to content

binocarlos/gandalf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gandalf

node.js oauth login wizard with leveldb session storage

Travis

gandalf gif

install

$ npm install gandalf

usage

var http = require('http')
var Router = require('routes-router')
var mount = require('routes-router-mount')
var level    = require('level-test')()
var Gandalf = require('gandalf')
var ecstatic = require('ecstatic')
var db = level('gandalf-examples--simple', {encoding: 'json'})

var gandalf = Gandalf(db, {
  providers:{
    facebook:{
      id:process.env.FACEBOOK_ID,
      secret:process.env.FACEBOOK_SECRET
    },
    twitter:{
      id:process.env.TWITTER_ID,
      secret:process.env.TWITTER_SECRET
    }
  }
})

var router = mount(Router())

// mount the OAuth login handlers
router.mount('/auth', gandalf.handler())

// get the current session data
router.addRoute('/status', {
	// add session handler to this method
	'GET':gandalf.session(function(req, res){
		req.session.get('userid', function(err, id){

			// load the user from the userid in the session
			gandalf.loadUser(id, function(err, user){
				res.end(JSON.stringify(user))	
			})
		})
	})
})

// only logged in people can see this route
router.addRoute('/private', gandalf.protect())

// these are served without hitting the session
router.addRoute('/*', ecstatic(__dirname + '/www'))

var server = http.createServer(router)

server.listen(80, function(){
  console.log('server listening');
})

api

var gandalf = Gandalf(db, options)

create a new authentication handler by passing in an existing leveldb - this can also be a sub-level

Pass a providers config to activate external OAUTH providers:

var gandalf = Gandalf(db, {
  providers:{
    facebook:{
      id:process.env.FACEBOOK_ID,
      secret:process.env.FACEBOOK_SECRET
    },
    twitter:{
      id:process.env.TWITTER_ID,
      secret:process.env.TWITTER_SECRET
    }
  }
})

The supported types are:

  • google
  • facebook
  • github
  • dropbox
  • twitter

Password mode (/register and /login) are activated automatically.

One user can connect multiple external providers and link them to the same user id.

gandalf.session()

Return a function that will create a session property of the request:

var session = gandalf.session()

router.addRoute('/api', function(req, res){
	session(req, res, function(){

		// we now have a session for the request
		req.session.get('userid', function(err, userid){

		})
	})
})

You can also pass a function to gandalf.session and it will be wrapped:

router.addRoute('/api', gandalf.session(function(req, res){
	//req.session is populated
}))

gandalf.handler()

Mount the authentication handler onto an endpoint of your application (for example on /auth).

You can then link to /auth/github to perform a github login or POST to /auth/register to register new accounts.

router.addRoute('/api', gandalf.handler())

The following are the routes that are mounted:

GET /PROVIDER

e.g. /google - this triggers the OAuth login loop for a provider

POST /register

post username and password and other fields to register a new user

{
	"username":"bob",
	"password":"123",
	"email":"bob@bob.com",
	"likes":"porridge"
}
POST /login

post username and password fields to login using the password method

{
	"username":"bob",
	"password":"123"
}
POST /claim

post a username to use for a connected user - use this when a user connects using an external service but you still need a username (as opposed to just an id)

{
	"username":"bob"
}
GET /logout

clear the session and redirect to '/'

GET /check?username=

check if the given username exists

GET /status

return a JSON representation of the current session - this includes OAuth tokens

gandalf.protect(function(req, appid, userid, done){})

Return a 403 error if the user is not logged in:

router.addRoute('/private', gandalf.protect(function(req, res){
	// the user is logged in
	// we also have req.session and req.userid
}))

If you do not pass a function then there just needs to be a user for access to be granted.

gandalf.delete(id, function(){})

Delete a user and all their details

gandalf.disconnect(id, provider, function(){})

Remove the connection details for 'provider' in the given user

events

gandalf.on('storage:put', function(key, value){})

When a value has been put to the database

gandalf.on('storage:batch', function(key, value){})

When a batch has been sent to the database

gandalf.on('request', function(req){})

A HTTP request has hit the handler

gandalf.on('provider', function(name, req){})

A HTTP request has hit a provider handler

gandalf.on('protect', function(req){})

A resource has been denied in a protect handler

gandalf.on('login', function(username){})

A login request

gandalf.on('register', function(username, body){})

A register request

gandalf.on('connect', function(provider, profile){})

A connect request

gandalf.on('save', function(id, provider, profile){})

A user profile has been created by provider

gandalf.on('claim', function(username){})

A claim request

gandalf.on('logout', function(req){})

A logout request

gandalf.on('log', function(type, message){})

gandalf.on('log:error', function(type, message){})

license

MIT

About

node.js and leveldb OAUTH user login manager - you shall not pass!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published