Mozilla Persona integration for Express. express-persona is designed to quickly get Persona authentication working in your Express application, while following Persona security best practices.
Install using npm: npm install express-persona
Include the module inside your Express application:
var express = require("express"),
app = express();
app.use(express.json())
.use(express.urlencoded())
.use(express.cookieParser())
.use(express.session({
secret: "mozillapersona"
}));
require("express-persona")(app, {
audience: "http://localhost:8888" // Must match your browser's address bar
});
Include the Persona library in your web page:
<script src="https://login.persona.org/include.js"></script>
Add login and logout functionality to your buttons:
document.querySelector("#login").addEventListener("click", function() {
navigator.id.request();
}, false);
document.querySelector("#logout").addEventListener("click", function() {
navigator.id.logout();
}, false);
Watch for login and logout actions:
navigator.id.watch({
onlogin: function(assertion) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/persona/verify", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.addEventListener("loadend", function(e) {
var data = JSON.parse(this.responseText);
if (data && data.status === "okay") {
console.log("You have been logged in as: " + data.email);
}
}, false);
xhr.send(JSON.stringify({
assertion: assertion
}));
},
onlogout: function() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/persona/logout", true);
xhr.addEventListener("loadend", function(e) {
console.log("You have been logged out");
});
xhr.send();
}
});
By default, express-persona adds the users email address to req.session.email
when their
email is validated.
This library will handle 3 of 4 essential practices for [Persona security considerations] (https://developer.mozilla.org/en-US/docs/Persona/Security_Considerations) but you should implement CSRF protection as well. I recommend the built-in express csrf middleware.
You can view and run complete examples in the examples directory.
require('express-persona')
returnsfunction(express, options)
express
is an instance of the express server that you want to add routes tooptions
is an object. It has one required parameter,audience
.
audience
- The URL of your express app when viewed in a browser. Must include the protocol, hostname, and port.- Example:
http://example.org:80
,https://example.org:443
- Example:
verifyPath
- The URL that clients use to verify credentials.- Default:
/persona/verify
- Examples:
/browserid/verify
,/api/verify
- Default:
logoutPath
- The URL that clients use to logout.- Default:
/persona/logout
- Examples:
/browserid/logout
,/api/logout
- Default:
sessionKey
- The session key to store the validated email in.- Default:
email
- Example:
user
,username
- Default:
verifierURI
- The URI of the Persona Remote Verification API- Default:
https://verifier.login.persona.org/verify
- You probably don't want to touch this unless you have a good reason, like testing.
- Default:
verifyResponse(error, req, res, email)
- Function to generate response for verify route- Default: see Verify route, below, for successess and failure responses
error
will be a string suitable for display (the "reason" attribute in the default implementation), if an error occursreq, res
are the request and response objectsemail
is a string containing the email, and will exist if there is not an error
logoutResponse(error, req, res)
- Function to generate response for logout route- Default: see Logout route, below, for response
error
will be a string suitable for display, if an error occursreq, res
are the request and response objects
middleware(req, res, next)
- Custom middleware for logout/login routes- Default: none
req, res
are the request and response objectsnext
points to the next middleware function in the chain
- On success:
{
"status": "okay"
"email": "jon@example.org"
}
- On failure
{
"status": "failure"
"reason": "request failed"
}
- Always returns:
{
"status": "okay"
}
Run tests using npm test
from the root of the repository.