-
-
Save shimondoodkin/8536065 to your computer and use it in GitHub Desktop.
nodejs app - expressjs 3.0 + socket.io v9 + passport + redis (made to work)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require('express'), | |
passport = require('passport'), | |
GoogleStrategy = require('passport-google').Strategy, | |
connect = require('express/node_modules/connect'), | |
http = require('http'), | |
path = require('path'), | |
util = require('util'), | |
fs = require('fs'), | |
redis = require('redis'), | |
cookie = require('cookie'), | |
connectSession = require('express/node_modules/connect/lib/middleware/session/session'), | |
socketRedisStore = require('socket.io/lib/stores/redis') | |
var app = express(), | |
server = http.createServer(app), | |
io = require('socket.io').listen(server), | |
flash = require('connect-flash'), | |
redisPub = redis.createClient(), | |
redisSub = redis.createClient(), | |
redisClient = redis.createClient(), | |
RedisStore = require('connect-redis')(express), | |
sessionStore | |
/* | |
var oauthids = { | |
facebook: { | |
clientID: 'get_your_own', | |
clientSecret: 'get_your_own', | |
callbackURL: 'http://127.0.0.1:1337/auth/facebook/callback' | |
}, | |
twitter: { | |
consumerKey: 'get_your_own', | |
consumerSecret: 'get_your_own', | |
callbackURL: "http://127.0.0.1:1337/auth/twitter/callback" | |
}, | |
github: { | |
clientID: 'get_your_own', | |
clientSecret: 'get_your_own', | |
callbackURL: "http://127.0.0.1:1337/auth/github/callback" | |
}, | |
google: { | |
returnURL: 'http://10.0.0.6:80/auth/google/callback', | |
realm: 'http://10.0.0.6:80' | |
} | |
} | |
*/ | |
passport.serializeUser(function(user, done) { | |
done(null, user); | |
}); | |
passport.deserializeUser(function(user, done) { | |
done(null, user); | |
}); | |
passport.use(new GoogleStrategy({ | |
returnURL: 'http://10.0.0.6:80/auth/google/callback', | |
realm: 'http://10.0.0.6:80/', | |
profile: true, | |
pape: { maxAuthAge : 60*60*24 }, | |
stateless: true | |
}, | |
function(identifier, profile, done) { | |
console.log(identifier, profile) | |
done(null, profile); | |
// User.findByOpenID(identifier, function (err, user) { | |
// done(err, user); | |
// }); | |
} | |
)); | |
/* | |
passport.use(new GoogleStrategy( | |
function(username, password, done) { | |
process.nextTick(function () { | |
console.log(username, password, done); | |
done(null, {username:username, password:password}); | |
/ * | |
User.findByUsername(username, function(err, user) { | |
if (err) { | |
done(err) | |
return | |
} | |
if (!user) { | |
user.checkPassword('$2a$10$va3CGzjy.g/Z8cuEcO844O', 'test', function(err, result) { | |
// ignoring result - just doing this to spend CPU time to throw off high-precision timing attacks | |
done(null, false, { message: 'Invalid username or password'}) | |
}) | |
return | |
} | |
user.checkPassword(password, function(err, result) { | |
if(err) { | |
done(err) | |
return | |
} | |
if(result == false) { | |
done(null, false, { message: 'Invalid username or password'}) | |
return | |
} else { | |
// @todo ban-check | |
// green light | |
done(null, user) | |
} | |
}) | |
}) | |
* / | |
}) | |
} | |
)) | |
*/ | |
function ensureAuthenticated(req, res, next) { | |
if(req.isAuthenticated()) return next() | |
res.redirect('/login') | |
return null | |
} | |
app_cookie_secret='ASDFAHSDfasgkdfgas@#$%^@@!@#$k' | |
app_cookie_key='express_id'; | |
app.configure(function(){ | |
var cookieMaxAge = 24*60*60 | |
sessionStore = new RedisStore({ | |
client: redisClient, | |
}) | |
app.set('port', 80) | |
//app.set('views', __dirname + '/views') | |
//app.set('view engine', 'jade') | |
app.use(express.favicon()) | |
//app.use(express.logger('dev')) | |
app.use(express.cookieParser(app_cookie_secret)) | |
app.use(express.bodyParser()) | |
app.use(express.methodOverride()) | |
app.use(express.session({ | |
key: app_cookie_key, | |
store: sessionStore, | |
secret: app_cookie_secret, | |
cookie: { maxAge: (cookieMaxAge !== 0) ? cookieMaxAge : null } | |
})) | |
app.use(express.csrf()) | |
app.use(flash()) | |
app.use(passport.initialize()) | |
app.use(passport.session()) | |
app.use(app.router) | |
app.use(express.static(__dirname + '/public')) | |
app.use(express.errorHandler()) | |
}) | |
// @note expressjs routes et al here.... | |
app.get('/auth/google', | |
passport.authenticate('google'), | |
function(req, res){ | |
// The request will be redirected to Google for authentication, so | |
// this function will not be called. | |
}); | |
app.get('/auth/google/callback', | |
passport.authenticate('google', { failureRedirect: '/login' }), | |
function(req, res) { | |
// Successful authentication, redirect home. | |
res.redirect('/'); | |
}); | |
app.get('/logout', function(req, res){ | |
req.logout(); | |
res.redirect('/'); | |
}); | |
/* | |
user: | |
{ displayName: 'Shimon Doodkin', | |
emails: [ [Object] ], | |
name: { familyName: 'Doodkin', givenName: 'Shimon' } }, | |
*/ | |
var fs=require('fs'); | |
app.get('/login',function(req,res,next){ | |
var login=req.user? 'Connected as '+req.user.displayName+' <a href="/logout">logout</a>' | |
: '<a href="/auth/google">login using google account</a>'; | |
res.send(login+'<br>login page'); | |
// res.sendfile(__dirname + '/public/index.html'); | |
}); | |
app.get('/',function(req,res,next){ | |
var login=req.user? 'Connected as '+req.user.displayName+' <a href="/logout">logout</a>' | |
: '<a href="/auth/google">login using google account</a>'; | |
//res.send(login+'<br>welcome'); | |
res.sendfile(__dirname + '/public/index.html'); | |
}); | |
/* | |
console.log(socket.handshake) | |
{ headers: | |
{ host: '10.0.0.6', | |
connection: 'keep-alive', | |
'cache-control': 'max-age=0', | |
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36', | |
accept: '* / *', | |
referer: 'http://10.0.0.6/', | |
'accept-encoding': 'gzip,deflate,sdch', | |
'accept-language': 'he-IL,he;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2', | |
cookie: 'express_id=s%3Ah8nGa7eGpRdrEvrZXs8ehtWe.vCX23L1z%2FXRBPeRw9Rcah7B3qM7u0D%2FRHSNST3dhgqI' }, | |
address: { address: '10.0.0.2', port: 7733 }, | |
time: 'Tue Jan 21 2014 06:51:59 GMT+0000 (UTC)', | |
query: { t: '1390287115860' }, | |
url: '/socket.io/1/?t=1390287115860', | |
xdomain: false, | |
secure: undefined, | |
cookie: { express_id: 'h8nGa7eGpRdrEvrZXs8ehtWe' }, | |
sessionID: 'h8nGa7eGpRdrEvrZXs8ehtWe', | |
session: | |
{ cookie: | |
{ path: '/', | |
_expires: Tue Jan 21 2014 06:53:25 GMT+0000 (UTC), | |
originalMaxAge: 86400, | |
httpOnly: true }, | |
_csrfSecret: '4L4qBBgxYLgH7gH3jIEhs86W', | |
passport: {} } } | |
*/ | |
var iofunctions={ | |
login:function(){var socket=this; | |
//console.log(socket.handshake.session) | |
var login=socket.handshake.session | |
&&socket.handshake.session.passport | |
&&socket.handshake.session.passport.user? 'Connected as '+socket.handshake.session.passport.user.displayName+' <a href="/logout">logout</a>' | |
: '<a href="/auth/google">login using google account</a>'; | |
socket.emit('login',login) | |
} | |
}; | |
/** | |
* socket.io stuff. Streaming. | |
*/ | |
// authentication verification | |
io.configure(function () { | |
io.set('log level', 1) | |
io.set('store', new socketRedisStore({ | |
redisPub : redisPub, | |
redisSub : redisSub, | |
redisClient : redisClient | |
})) | |
io.set('authorization', function (data, accept) { | |
if (data.headers.cookie) { | |
data.cookie = cookie.parse(data.headers.cookie) | |
data.cookie = connect.utils.parseSignedCookies(data.cookie, app_cookie_secret) | |
data.cookie = connect.utils.parseJSONCookies(data.cookie) | |
data.sessionID = data.cookie[app_cookie_key] | |
sessionStore.load(data.sessionID, function (err, session) { | |
if (err || !session) { | |
// invalid session identifier. tl;dr gtfo. | |
accept('session error', false) | |
} else { | |
data.session = session | |
accept(null, true) | |
} | |
}) | |
} else { | |
// no auth cookie... | |
accept('session error', false) | |
} | |
}) | |
}) | |
io.sockets.on('connection', function (socket) { | |
var sessionID = socket.handshake.sessionID, | |
session = new connect.middleware.session.Session({ sessionStore: sessionStore }, socket.handshake.session) | |
//console.log('socket: new ' + sessionID) | |
socket.broadcast.emit('userNewConn', session.passport.user) | |
var intervalID = setInterval(function() { | |
socket.handshake.session.reload(function() { | |
socket.handshake.session.touch().save() | |
}) | |
socket.emit('pulse', { heartbeat: new Date().toString(), timestamp: new Date().getTime() }) | |
}, 300 * 1000) // every 300 seconds, pulse to maintain the session (10s for testing) | |
// @note more socket.io stuff here... | |
Object.keys(iofunctions).forEach(function(n){socket.on(n,iofunctions[n])}); | |
socket.on('disconnect', function () { | |
// clear the socket interval to stop refreshing the session | |
//console.log('socket: dump ' + sessionID) | |
socket.broadcast.emit('userLostConn', session.passport.user) | |
clearInterval(intervalID) | |
}) | |
}) | |
/** | |
* start the server | |
*/ | |
server.listen(app.get('port'), function(){ | |
console.log("Express server listening on port " + app.get('port')) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "walletfront", | |
"version": "0.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"express": "~3.4.7", | |
"passport": "~0.1.18", | |
"passport-google": "~0.3.0", | |
"socket.io": "~0.9.16", | |
"connect-flash": "~0.1.1", | |
"connect-redis": "~1.4.6", | |
"cookie": "~0.1.0", | |
"redis": "~0.10.0", | |
"hiredis": "~0.1.16" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!Doctype html5 lang="en"> | |
<html> | |
<head> | |
<title>Welcome</title> | |
<style> | |
* { | |
margin: 0px; | |
padding: 0px; | |
} | |
body { | |
background: #B6B6B4; | |
color: #fff; | |
} | |
.centered { | |
position: fixed; | |
top: 50%; | |
z-index: 100; | |
background: #0072c6; | |
height: 200px; | |
margin-top: -100px; | |
width: 100%; | |
} | |
#Splash { | |
font-family: 'Exo-Bold', sans-serif; | |
font-size: 50px; | |
} | |
.message { | |
font-family: 'ws-ui', sans-serif; | |
font-size: 25px; | |
text-indentation: 50px; | |
} | |
.menu { | |
font-family: 'ws-ui', sans-serif; | |
font-size: 25px; | |
text-indentation: 50px; | |
padding:20px; | |
text-align:left; | |
max-width:800px; | |
min-width:360px; | |
} | |
.menu a { | |
background:#335599 url(../images/bg.png) repeat-x 0 -100px; | |
color:#fff; | |
padding:25px; | |
margin-bottom:10px; | |
display:inline-block; | |
border-radius:10px; /*some css3*/ | |
-moz-border-radius:10px; | |
-webkit-border-radius:10px; | |
text-shadow:0 2px 2px rgba(0,0,0, 0.7); | |
} | |
.menu a:first-child { | |
-moz-border-radius-topleft:10px; /*some css3*/ | |
-moz-border-radius-topright:10px; | |
-webkit-border-top-left-radius:10px; | |
-webkit-border-top-right-radius:10px; | |
} | |
.menu a:last-child { | |
-moz-border-radius-bottomleft:10px; /*some css3*/ | |
-moz-border-radius-bottomright:10px; | |
-webkit-border-bottom-left-radius:10px; | |
-webkit-border-bottom-right-radius:10px; | |
} | |
.menu a { | |
/*background:#aabbcc;*/ | |
border:1px solid #7788aa; | |
border-radius:10px; /*some css3*/ | |
-moz-border-radius:10px; | |
-webkit-border-radius:10px; | |
box-shadow:0 2px 2px rgba(0,0,0, .5); | |
-moz-box-shadow:0 2px 2px rgba(0,0,0, .5); | |
-webkit-box-shadow:0 2px 2px rgba(0,0,0, .5); | |
-moz-transition:opacity .25s linear, visibility .1s linear .1s; | |
-webkit-transition:opacity .25s linear, visibility .1s linear .1s; | |
-o-transition:opacity .25s linear, visibility .1s linear .1s; | |
transition:opacity .25s linear, visibility .1s linear .1s; | |
} | |
.menu a:hover { | |
background:#aabbcc; | |
-moz-transition:background .25s linear, visibility .1s linear .1s; | |
-webkit-transition:background .25s linear, visibility .1s linear .1s; | |
-o-transition:background .25s linear, visibility .1s linear .1s; | |
transition:background .25s linear, visibility .1s linear .1s; | |
} | |
</style> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> | |
<script> | |
var socket = io.connect('http://10.0.0.6'); | |
socket.on('login', function (data) { | |
//console.log("login",arguments) | |
$('#login').html(data); | |
}); | |
socket.emit('login'); | |
</script> | |
</head> | |
<body> | |
<div align="center"><div class="menu"><br/> | |
<a href="/subaction1">subaction1</a> | |
<a href="/subaction2">subaction2</a> | |
<a href="/subaction2">subaction3</a> | |
<a href="/subaction2">subaction4</a> | |
</div></div> | |
<div class="centered"><br/> | |
<center> | |
<p id="Splash">Welcome</p><br/> | |
<p id="login" class="message">:-)</p> | |
</center> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment