Permalink
Browse files

Adds new Mozilla Persona Strategy

  • Loading branch information...
1 parent ea07a1c commit e11fba96c7e5b6e513f232b14ee5086cefd81b9c @ciaranj committed Apr 11, 2013
View
@@ -58,8 +58,18 @@ var example_auth_middleware= function() {
// The authentication strategy requires some more browser interaction, suggest you do nothing here!
}
else {
- // We've either failed to authenticate, or succeeded (req.isAuthenticated() will confirm, as will the value of the received argument)
- next();
+ if( urlp.query.login_with == "persona" && authenticated === false ) {
+ // persona behaves differently to the other strategies as it is async-to-the-page POST.
+ res.writeHead(401, "" );
+ res.end()
+ }
+ else {
+ if( authenticated == true ) {
+ req.getAuthDetails().activeStrategy= urlp.query.login_with;
+ }
+ // We've either failed to authenticate, or succeeded (req.isAuthenticated() will confirm, as will the value of the received argument)
+ next();
+ }
}
}});
}
@@ -87,6 +97,7 @@ app.use(connect.static(__dirname + '/public'))
, auth.Twitter({consumerKey: twitterConsumerKey, consumerSecret: twitterConsumerSecret})
, auth.Skyrock({consumerKey: skyrockConsumerKey, consumerSecret: skyrockConsumerSecret, callback: skyrockCallbackAddress})
, auth.Facebook({appId : fbId, appSecret: fbSecret, scope: "email", callback: fbCallbackAddress})
+ , auth.Persona({audience: personaAudience})
, auth.Github({appId : ghId, appSecret: ghSecret, callback: ghCallbackAddress})
, auth.Yahoo({consumerKey: yahooConsumerKey, consumerSecret: yahooConsumerSecret, callback: yahooCallbackAddress})
, auth.Google({consumerKey: googleConsumerKey, consumerSecret: googleConsumerSecret, scope: "", callback: googleCallbackAddress})
@@ -106,10 +117,18 @@ app.use(connect.static(__dirname + '/public'))
.use("/", function(req, res, params) {
res.writeHead(200, {'Content-Type': 'text/html'})
if( req.isAuthenticated() ) {
- res.end( authenticatedContent.replace("#USER#", JSON.stringify( req.getAuthDetails().user ) ) );
+ var logoutApproach= "";
+ if( req.getAuthDetails().activeStrategy == "persona" ) {
+ logoutApproach= "<a href='#' onclick='navigator.id.logout();'>Logout</a>";
+ }
+ else {
+ logoutApproach= "<a href='/logout'>Logout</a>";
+ }
+ res.end( authenticatedContent.replace("#USER#", JSON.stringify( req.getAuthDetails().user ) )
+ .replace("#LOGOUTAPPROACH#", logoutApproach) );
}
else {
- res.end( unAuthenticatedContent.replace("#PAGE#", req.originalUrl) );
+ res.end( unAuthenticatedContent.replace("#PAGE#", req.originalUrl));
}
})
.listen(80);
@@ -31,6 +31,7 @@ exports.openIdCallback= "http://yourtesthost.com/verify";
exports.linkedinConsumerKey= "";
exports.linkedinConsumerSecret= "";
exports.linkedinCallback= "http://localhost/auth/linkedin_callback";
+exports.personaAudience="yourtesthost.com";
exports.yammerConsumerKey= "";
exports.yammerConsumerSecret= "";
exports.yammerCallback= "http://localhost/auth/yammer_callback";
@@ -1,12 +1,35 @@
<html>
<head>
<title>Connect Auth -- Authenticated</title>
+ <script src="https://login.persona.org/include.js"></script>
+ <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
<div id="wrapper">
<h1>Authenticated</h1>
<div id="user">#USER#</div>
- <h2><a href="/logout">Logout</a></h2>
+ <h2>#LOGOUTAPPROACH#</h2>
</div>
- </body>
+ <script type="text/javascript">
+ $(function(){ // on DOM Ready
+ navigator.id.watch({
+ loggedInUser: null,
+ onlogin: function(assertion) {
+ },
+ onlogout: function() {
+ // A user has logged out! Here you need to:
+ // Tear down the user's session by redirecting the user or making a call to your backend.
+ // Also, make sure loggedInUser will get set to null on the next page load.
+ // (That's a literal JavaScript null. Not false, 0, or undefined. null.)
+ $.ajax({
+ type: 'POST',
+ url: '/logout', // This is a URL on your website.
+ success: function(res, status, xhr) { window.location.reload(); },
+ error: function(xhr, status, err) { alert("Logout failure: " + err); }
+ });
+ }
+ });
+ })
+ </script>
+</body>
</html>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -8,6 +8,9 @@
}
</style>
<script src="http://static.ak.fbcdn.net/connect/en_US/core.js"></script>
+ <script src="https://login.persona.org/include.js"></script>
+ <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
+
</head>
<body>
@@ -58,6 +61,10 @@ <h2 id="slogan"></h2>
</form>
</td>
</tr>
+ <tr class="row-b">
+ <td class="first">Mozilla Persona</td>
+ <td><a id="personasignin" href="#" onclick="navigator.id.request();"><img src="persona_sign_in_blue.png"/></a></td>
+ </tr>
</table>
</div>
<div class="section">
@@ -199,4 +206,30 @@ <h2 id="slogan"></h2>
<!-- footer ends-->
</div>
</body>
+ <script type="text/javascript">
+ $(function(){ // on DOM Ready
+ navigator.id.watch({
+ loggedInUser: null,
+ onlogin: function(assertion) {
+ // A user has logged in! Here you need to:
+ // 1. Send the assertion to your backend for verification and to create a session.
+ // 2. Update your UI.
+ $.ajax({
+ type: 'POST',
+ url: '?login_with=persona', // This is a URL on your website.
+ data: {assertion: assertion},
+ success: function(res, status, xhr) {
+ window.location.reload();
+ },
+ error: function(xhr, status, err) {
+ navigator.id.logout();
+ alert("Login failure: " + err);
+ }
+ });
+ },
+ onlogout: function() {
+ }
+ });
+ })
+ </script>
</html>
@@ -0,0 +1,63 @@
+var https= require('https')
+ , querystring= require('querystring');
+/*
+ * Copyright(c) 2010 Ciaran Jessup <ciaranj@gmail.com>
+ * MIT Licensed
+ *
+ * Verification routines for mozilla persona.
+ */
+module.exports= function(options) {
+ var that= {}
+ var my= {};
+ options= options || {};
+ that.name= options.name || "persona";
+ my.audience= options.audience || "";
+ that.authenticate= function(request, response, callback) {
+ var self= this;
+ if(!request.body || !request.body.assertion) {
+ this.trace( "No persona Assertion supplied." );
+ this.fail(callback);
+ } else {
+ this.trace( "Verifying Assertion." );
+ if( my.audience == "" ) {
+ this.trace( "No persona audience configured." );
+ this.fail(callback);
+ }
+ else {
+ var vreq = https.request({host: "verifier.login.persona.org", path: "/verify", method: "POST"}, function(vres) {
+ var body = "";
+ vres.on('data', function(chunk) { body+=chunk; } )
+ .on('end', function() {
+ try {
+ var verifierResp = JSON.parse(body);
+ var valid = verifierResp && verifierResp.status === "okay";
+ var email = valid ? verifierResp.email : null;
+ if (valid) {
+ self.trace("assertion verified successfully for email:", email);
+ self.success({"email":email}, callback);
+ } else {
+ self.trace("failed to verify assertion:", verifierResp.reason);
+ self.fail()
+ }
+ } catch(e) {
+ // bogus response from verifier!
+ self.trace("non-JSON response from verifier: " + body);
+ self.fail( callback );
+ }
+ });
+ });
+ vreq.setHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+ var data = querystring.stringify({
+ assertion: request.body.assertion,
+ audience: my.audience
+ });
+
+ vreq.setHeader('Content-Length', data.length);
+ vreq.write(data);
+ vreq.end();
+ }
+ }
+ }
+ return that;
+};

0 comments on commit e11fba9

Please sign in to comment.