Git Product home page Git Product logo

myfavoritebeer.org's Introduction

MyFavoriteBeer.org - A BrowserID example site

This is a simple site that demonstrates how BrowserID can be used to build a better login experience for users.

Overview

BrowserID is a distributed system that allows users to use their email address as login name and password. The cryptography which allows users to prove that they own an email address without site specific passwords is described in depth in the how browserid works blog post. For website owners, there is a three step tutorial that helps you integrate browserid as fast as possible.

This repository goes into greater depth than the tutorial, and provides a full working example of a small but complete website that uses BrowserID for authentication. This code is running at myfavoritebeer.org.

The Implementation

MyFavoriteBeer is a simple site that allows a user to log in and store a single string of information, their favorite beer. The site consists of a static HTML frontend (code under static/), and a simple web services API implemented by a node.js server (code under server/).

The API

The web services api exported by the node.js server consists of the following:

  • /api/whoami - reports whether the current session is authenticated
  • /api/login - accepts a browserid assertion to allow the user to authenticate
  • /api/get - returns the current user's favorite beer
  • /api/set - sets the current user's favorite beer
  • /api/logout - clears the current session

Further documentation of these calls is available in the source code.

Authentication

The most interesting part of this example is how authentication occurs. Client code includes the browserid javascript include file, and upon a user clicking the sign-in button, navigator.id.getVerifiedEmail() is invoked. BrowserID returns a string which contains an assertion. This assertion is passed up to the myfavoritebeer server via the /api/login api. The server verifies this assertion using the free verifier service by POSTing to https://browserid.org/verify. Finally, upon successful verification, the server sets a cookie which represents an authenticated session.

Sessions

For simplicities' sake, "sessions" in this example are implemented using a third party library which encrypts session data using a private key and stores this data in a cookie on the user's browser. This approach makes it so the server doesn't need to store any data to implement sessions and keeps the example simple.

Persistence

We have to store the beer preferences somewhere. mongodb is used for this purpose and a very simple database abstraction layer exists in db.js. The details of interacting with the database aren't important, but if you're curious have a look in db.js.

Run it!

To run the example code locally:

  1. clone this repository
  2. install node (0.6.5+) and npm.
  3. npm install
  4. PORT=8080 npm start

Now open http://127.0.0.1:8080 up in your web browser.

NOTE: You'll see warnings about how no database is configured. Don't worry about it. The code is designed to run with or without a configured database so that it's easier to play with. The only downside of running without a database is that your server won't remember anything. Oh well.

Deployment

The code is designed to run on heroku's node.js hosting services, and the only way this affects the implementation is via environment variable naming choices and the presence of a Procfile which tells heroku how to start the server.

If you'd like to deploy this service to heroku yourself, all you'd have to do is:

  1. set up a heroku account (and run through their tutorial)
  2. create a heroku instance running nodejs 0.6: heroku create --stack cedar --buildpack http://github.com/hakobera/heroku-buildpack-nodejs.git <appname>
  3. add a free mongolab instance (for persistence): heroku addons:add mongolab:starter
  4. set your app to bind to all available ips: heroku config:add IP_ADDRESS=0.0.0.0
  5. set a random string to encrypt cookies: heroku config:add SEKRET=<long random string>
  6. push the code up to heroku: git push heroku master

NOTE: While the sample is targeted at heroku, with minimal code modifications it should run under the hosting environment of your preference.

Credit

Concept + Design(kinda): http://myfavouritesandwich.org/ Art: http://www.flickr.com/photos/bitzi/236037776/

myfavoritebeer.org's People

Contributors

fmarier avatar graingert avatar jaredhirsch avatar jedp avatar lloyd avatar mardak avatar michielbdejong avatar rossbruniges avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

myfavoritebeer.org's Issues

When closing the Signing in dialog from [X] the Sign In button from http://beta.myfavoritebeer.org remains grayed out and unresponsive

OS: Windows 7
Browser: Opera 11.51

STR:

  1. Launch Opera.
  2. Load http://beta.myfavoritebeer.org in an Opera tab.
  3. Click on the Sign In button.
  4. Close the opened dialog from the [X] button.

When closing the Signing in dialog from [X] in Opera, the Sign In button from http://beta.myfavoritebeer.org remains grayed out and unresponsive. A simple reloading of the page solves the issue.

This issue doesn't reproduce on Firefox and Chrome (same OS).

Add CSP support

It would be really good to have one of our test RPs use CSP. That way we could more easily find out when/if we break CSP.

Android/Browser: Cancelling sign-in on beer site does not refresh Sign In

Originally reported by @jbonacci at mozilla/persona#492

Found this while testing Android compatibility (old firmware).

Using the stock browser (Browser)
Bring up beta.myfavoritebeer.org
Click on Sign In
This should open a "pop up" window with the Email field.
Click the X button in the upper right corner to cancel and close this pop-up.
Note that clicking on the Sign In button again does not open the pop-up
The beer site must be refreshed in order to make the button active again.

Mobile: Beer name is not sticking

Originally reported by @jbonacci at mozilla/persona#495

This may or may not be an Android + firmware issue (I will verify).

But, I notice that the beer name I type in does not "stick".
Next time I log in the beer name is gone.

Verified on Android 2.2 with Stock Browser, Opera, and Firefox 7.

Beer name does not show up on any other device either.

If a set a beer name on a desktop browser, the Android browser will display.
But, I am unable to blank it out or reset it from the Android side...

Tablet check:
Same result.

So, it looks like there is no obvious way to "set" or "Enter" to save the current beer name.

For example, on the tablet, when the field is selected, the default keyboard has a Next button, but no Go or Enter button.

Won't show my fav beer in private modes.

The sample works perfect in "normal" mode. If I switch to Private (ffox) or Incognito (chorme), after getting authenticated the site doesn't show any beer preference!

Multiple calls to getVerifiedEmail after canceling sign-in

Every additional time "sign in" is clicked after canceling (and callback(null) is triggered), one more getVerifiedEmail() call is made each time.

First click results in one navigator.id.getVerifiedEmail(gotVerifiedEmail);
Second click (after canceling) makes 2 immediate calls of navigator.id.getVerifiedEmail(gotVerifiedEmail);

Seems like the click handler is being added each time loggedOut() is called.

Why not use OpenID?

I'm not sure where to ask this, but Why not use OpenID instead? Is not it better to ask to webmasters give support for OpenID, which already exists? What is the difference?

If there exists a difference, perhaps you should allow associate an OpenID as an alternative to e-mail.

iOS4: Sign In is not selectable if user leaves beer site then returns to sign in

Originally reported by @jbonacci at mozilla/persona#516

I know, sounds a bit confusing.
But, I discovered that the Sign In button is no longer selectable if I leave the beer site through one of the links at the bottom of the page, then hit the "back" button (left arrow) to return to the beer site.
At this point the Sign In button appears as if it was already clicked, but there is no new window with the Email and Password fields available.
Refreshing the beer site, "re-activates" the Sign In button and I can proceed as expected.

Open the beer site (beta.myfavoritebeer.org)
Click on the one of the links at the bottom of the page.
This should open within the current page.
Click the left arrow button to return the beer site
Note that the Sign In button appears to be unselectable.
Click the Sign In button
No new page is opened
Refresh the beer site
Now select the Sign In button

Android/FF7: Beer site layout does not fit correctly on screen

Originally reported by @jbonacci at mozilla/persona#493

Found this while testing Android compatibility (old firmware).

The page layout/content of the beer site is not fitting in the portrait or landscape view.
The user has to scroll left/right and up/down to see the Sign In button on the right and the links at the bottom.
Zooming in/out does work, but the default layout should fit into the screen size.

Now, the diresworb page does fit nicely by default left to right with just a bit of scrolling or zooming needed to get to the bottom links.

This was not an issue with the stock browser.

logout link is really hard to find / see

STR:

  1. Log in at http://myfavoritebeer.org/
  2. Try to look for a logout link

EXPECTED RESULTS: Easy to find "logout" link. (After all -- it's a demo of BrowserID, which lets you log in with multiple email addresses, and I want to test logging in, logging out, and logging in again with a different address!)

ACTUAL RESULTS: logout link is nearly impossible to see. For me at least, it's very small text, directly below my username, superimposed on top of the beer-bubbles, in nearly the same color of text as the bubbles behind it. (making it near-invisible)

javascript error on myfavoritebeer.org for new user signing in with no beer entered yet

Just a minor cosmetic/noise fix.

Steps to reproduce:

  1. Go to http://myfavoritebeer.org/ (or beta.myfavoritebeer.org)
  2. click sign in
  3. click 'use a different email' and add an email not used before
  4. check email, and click on the confirmation link when it arrives
  5. sign_in dialog closes itself and myfavoritebeer.org loads the user's favoritebeer

Expected:
No JS error when the user is new and has not yet entered a fav beer.

Actual:
Error: no element found
Source File: http://dev.myfavoritebeer.org/api/get
Line: 1

The actual HTTP response code for /api/get is 500, which happens because the mongodb collection is an empty list (?)

Startup error: Cannot find module 'cookies'

I followed the installation instructions in README.md ("Run it!") - but I receive the following error:

inactivist@inactivist-VirtualBox:~/src/myfavoritebeer.org$ PORT=8080 npm start

> [email protected] start /home/inactivist/src/myfavoritebeer.org
> node server/main.js


node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: Cannot find module 'cookies'
    at Function._resolveFilename (module.js:332:11)
    at Function._load (module.js:279:25)
    at Module.require (module.js:354:17)
    at require (module.js:370:17)
    at Object.<anonymous> (/home/inactivist/src/myfavoritebeer.org/node_modules/client-sessions/lib/client-sessions.js:2:15)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Module.require (module.js:354:17)

npm ERR! [email protected] start: `node server/main.js`
npm ERR! `sh "-c" "node server/main.js"` failed with 1
npm ERR! 
npm ERR! Failed at the [email protected] start script.
npm ERR! This is most likely a problem with the myfavoritebeer package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node server/main.js
npm ERR! You can get their info via:
npm ERR!     npm owner ls myfavoritebeer
npm ERR! There is likely additional logging output above.
npm ERR! 
npm ERR! System Linux 2.6.38-13-generic
npm ERR! command "node" "/usr/local/bin/npm" "start"
npm ERR! cwd /home/inactivist/src/myfavoritebeer.org
npm ERR! node -v v0.6.14
npm ERR! npm -v 1.1.12
npm ERR! code ELIFECYCLE
npm ERR! message [email protected] start: `node server/main.js`
npm ERR! message `sh "-c" "node server/main.js"` failed with 1
npm ERR! errno {}
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/inactivist/src/myfavoritebeer.org/npm-debug.log
npm not ok

Version info:

~/src/myfavoritebeer.org$ git branch -v
* master 094eb6a update deployment documentation with 0.6 requirement
~/src/myfavoritebeer.org$ node -v
v0.6.14
~/src/myfavoritebeer.org$ npm -v
1.1.12
~/src/myfavoritebeer.org$ cat /etc/issue
Ubuntu 11.04

Purely Client Side?... or do implementers still need a server?

I noticed the following comment in:

https://github.com/lloyd/myfavoritebeer.org/blob/master/static/js/main.js

"WARNING: This is only an example. In real apps, this verification step must be done from server-side code. "

Can BrowserID securely support a purely client side login system?... i.e. no server at all for developers implementing it. This is what I was hoping for ^_^

If I recall correctly, Twitter @anywhere seems to have a system that is just clientside javascript. https://dev.twitter.com/docs/anywhere/welcome ... not sure if that's relevant :-P

Cheers,
Chris

setting BROWSERID_URL to an IP address causes error

PORT=3000 BROWSERID_URL=http://64.9.237.87:10002 node server/main.js
Using BrowserID at: http://64.9.237.87:10002
listening on 127.0.0.1:3000
GET / 304 2ms
GET /js/less.js 304 1ms
GET /js/main.js 304 2ms
GET /js/jquery.js 304 1ms
GET /style.less 304 0ms
GET /i/browserid_logo_sm.png 304 0ms
GET /i/236037776_f8b7e0564d_o.jpg 304 1ms
GET /api/whoami 200 0ms
GET /i/sign_in_blue.png 304 1ms
GET / 304 1ms
GET /js/less.js 304 0ms
GET /js/jquery.js 304 0ms
GET /js/main.js 304 0ms
GET /style.less 304 1ms
GET /i/browserid_logo_sm.png 304 0ms
GET /i/236037776_f8b7e0564d_o.jpg 304 0ms
GET /api/whoami 200 0ms
GET /i/sign_in_blue.png 304 1ms
verifying with: 64.9.237.87:10002

node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: ENOTFOUND, Domain name not found
at IOWatcher.callback (dns.js:74:15)

Selected version of express not compatible with current node.js

Preface: I'm a complete newbie wrt to node.js, et al., but I am under the impression that this project is intended to be a turnkey demo that should just work out of the box (clone). So I think that any issues that prevent this for the average user are worth considering, if this project is still relevant. Also, I'm running on Mac OS 10.7.3 (Lion).

So when I follow the README instructions, I download the current default version of node.js from nodejs.org, which is 0.6.10. I then try to run "npm install", and it fails, apparently because the version of express named in this project's package.json (2.4.6) is reporting that it is compatible only with node 4.1-4.x.

Shell log follows:

$ npm install
npm http GET https://registry.npmjs.org/express/2.4.6
npm http GET https://registry.npmjs.org/postprocess/0.0.2
npm http GET https://registry.npmjs.org/connect-cookie-session/0.0.2
npm http GET https://registry.npmjs.org/mongodb/0.9.6-16
npm http 200 https://registry.npmjs.org/connect-cookie-session/0.0.2
npm http GET https://registry.npmjs.org/connect-cookie-session/-/connect-cookie-session-0.0.2.tgz
npm http 200 https://registry.npmjs.org/postprocess/0.0.2
npm http GET https://registry.npmjs.org/postprocess/-/postprocess-0.0.2.tgz
npm http 200 https://registry.npmjs.org/express/2.4.6
npm http GET https://registry.npmjs.org/express/-/express-2.4.6.tgz
npm http 200 https://registry.npmjs.org/connect-cookie-session/-/connect-cookie-session-0.0.2.tgz
npm http 200 https://registry.npmjs.org/postprocess/-/postprocess-0.0.2.tgz
npm http 200 https://registry.npmjs.org/mongodb/0.9.6-16
npm http GET https://registry.npmjs.org/mongodb/-/mongodb-0.9.6-16.tgz
npm http 200 https://registry.npmjs.org/express/-/express-2.4.6.tgz
npm http 200 https://registry.npmjs.org/mongodb/-/mongodb-0.9.6-16.tgz
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']

npm ERR! Unsupported
npm ERR! Not compatible with your version of node/npm: [email protected]
npm ERR! Required: {"node":">= 0.4.1 < 0.5.0"}
npm ERR! Actual:   {"npm":"1.1.0-3","node":"0.6.10"}
npm ERR! 
npm ERR! System Darwin 11.3.0
npm ERR! command "node" "/usr/local/bin/npm" "install"
npm ERR! cwd .../myfavoritebeer.org
npm ERR! node -v v0.6.10
npm ERR! npm -v 1.1.0-3
npm ERR! code ENOTSUP
npm ERR! message Unsupported
npm ERR! errno {}
npm not ok

Changing the requested version of express to 2.5.4 (what seems to be the current 2.x branch version) allows "npm install" to complete, however, I am now getting failure when trying to execute "npm start" (Cannot find module 'connect'), which I'm just starting to investigate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.