Skip to content

Instantly share code, notes, and snippets.

@nelix
Created March 13, 2014 05:23
Show Gist options
  • Select an option

  • Save nelix/9522280 to your computer and use it in GitHub Desktop.

Select an option

Save nelix/9522280 to your computer and use it in GitHub Desktop.
Little faye server with hmac authentication
def hmac_token(channel)
ident = {
user: current_user.id,
timestamp: Time.now.to_i,
channel: channel
}
puts "#{ident[:user]}:#{ident[:timestamp]}:#{ident[:channel]}"
digest = OpenSSL::HMAC.new(ENV['FAYE_SECRET_KEY'] || 'whocares?', 'SHA512')
digest << "#{ident[:user]}:#{ident[:timestamp]}:#{ident[:channel]}"
ident[:token] = digest.hexdigest
raw ident.to_json
end
var ident = <%= hmac_token '/channel' %>
var Logger = {
incoming: function(message, callback) {
console.log('incoming', message);
callback(message);
},
outgoing: function(message, callback) {
console.log('outgoing', message);
if (message.channel !== '/meta/subscribe') return callback(message);
message.ext = message.ext || {};
message.ext.ident = ident;
callback(message);
}
};
var client = new Faye.Client('http://localhost:8080/');
client.addExtension(Logger);
client.subscribe('/channel',
function(message) {
console.log(message)
}
).then(
function() {
console.log('connected')
}
);
require 'faye'
require 'openssl'
module Rack #disable rack:lint which crashes when using faye
class Lint
def call(env = nil)
@app.call(env)
end
end
end
Faye::WebSocket.load_adapter('thin') #TODO resolve issue with rainbows
class HMACAuth
def incoming(message, callback)
unless message['channel'] == '/meta/subscribe'
return callback.call(message)
end
begin
subscription = message['subscription']
ident = message['ext'] && message['ext']['ident']
if ident['timestamp'] + 86400 < Time.now.to_i
message['error'] = 'Invalid timestap, to old'
end
if ident['channel'] != subscription
message['error'] = 'Invalid channel for given token'
end
if token(ident) != ident['token']
message['error'] = 'Invalid subscription auth token'
end
rescue Exception => e
message['error'] = e.to_s
end
callback.call(message)
end
private
def token(ident, secret=ENV['FAYE_SECRET_KEY'] || 'whocares?')
digest = OpenSSL::HMAC.new(secret, 'SHA512')
digest << "#{ident['user']}:#{ident['timestamp']}:#{ident['channel']}"
digest.hexdigest
end
end
server = Faye::RackAdapter.new(mount: '/', timeout: 25, extensions:[HMACAuth.new])
run server
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment