How to make faye client on server side in rails app? - ruby-on-rails

I have been working on Faye gem for couple of days. I have created Faye client at client-side using below code:
var client = new Faye.Client('http://localhost:9292/faye');
$.get("/chatroom", function (data)
{
var UserId = data.user
client.subscribe("/message/"+UserId+"", function(data)
{
//rest of the code
});
})
but I want this activity to be done on server side how to achieve this? Whenever a user gets login he should be subscribed to push server.

Related

How to integrate OAuth2.0 login in electron

I am newbie to electron and I am currently trying to implement an OAuth2.0 API which requires a callback URI. Url callback requires valid URL (https://myserver.com/sucess). so i tried this code snippet but does not work.
// Your GitHub Applications Credentials
var options = {
client_id: 'your_client_id',
client_secret: 'your_client_secret',
scopes: ["user:email", "notifications"] // Scopes limit access for OAuth tokens.
};
app.on('ready', () => {
// Build the OAuth consent page URL
var authWindow = new BrowserWindow({ width: 800, height: 600, show: false, 'node-integration': false });
var githubUrl = 'https://github.com/login/oauth/authorize?';
var authUrl = githubUrl + 'client_id=' + options.client_id + '&scope=' + options.scopes;
authWindow.loadURL(authUrl);
authWindow.show();
function handleCallback (url) {
console.log(url);
}
// Handle the response from GitHub - See Update from 4/12/2015
authWindow.webContents.on('will-navigate', function (event, url) {
handleCallback(url);
});
authWindow.webContents.on('did-get-redirect-request', function (event, oldUrl, newUrl) {
handleCallback(newUrl);
});
// Reset the authWindow on close
authWindow.on('close', function() {
authWindow = null;
}, false);
});
also, i used angular js route but does not work either.
so I'm wondering if there is a way to run server inside electron app to serve app from URL (https://localhost:3000) and if so how this will affect app behavior at packaging and distributing time, i means does the app will run from the same port
... any suggestions will help about how i can approach this problem. thank you
I had the same issue last week, i needed to integrate my electron app with vkontakte api which uses form of OAuth protocol. What you can do:
1) You launch local node http server, probably in separate process as i did.
2) You request code through oauth link and set redirect uri as http://127.0.0.1:8000/, for some reason https://localhost didn't work for me.
3) In main process you wait for message with code from server, on server implemented corresponding logic (when you receive request and code in it send through process.send back to parent message with code)
4)You request access token from main process, you shouldn't change redirect_uri. You again catch response from your server.
5) You get access_token, you kill server...
But when i did all this i read their docs till end and there was stated that standalone apps, like mine for desktop could receive token in easier way through "implicit flow", and you can get your token with only one call. Hope my experience could be extrapolated on your issue. Good luck!

Twitter authentication with Ember.js and Rails

I'm using Torii and ember-simple-auth to manage authentication on my front-side, and Knock and Omniauth-twitter on my server. I had no problem with Facebook, but Twitter using Oauth1.0, I have troubles to figure out the flow.
Here is my Torii config :
# environment.js
ENV['torii'] = {
sessionServiceName: 'sessiontorii',
providers: {
'facebook-oauth2': {
apiKey: 'API_KEY',
redirectUri: 'http://localhost:4200/'
},
'twitter': {
requestTokenUri: 'http://127.0.0.1:3000/auth/twitter'
}
}
My route or controller :
# route.js
twitterLogin() {
var self = this;
this.get('sessiontorii').open('twitter').then(function(response) {
console.log(response);
self.transitionTo('index');
}, function() {
console.log('auth failed');
});
},
A new window is opening and I can login with my Twitter account. My server does the authentication/registration, but I can't figure out how to close this new window and send the token to my front.
Is my flow completely wrong ? Or do I miss something ?
I followed this tutorial, but I wonder if it's not a bit outdated
The issue was that I was sending a wrong type of data from my server. So I updated my torii-provider and the code I was sending. Torii does the job and close the new window when it gets the data. Then, I'm sending the data to my authenticator and confirm the authentication with the JWT code.

Bridging a simple Node.js & Socket.io chat app with a Rails app (on Heroku)

I have a basic Node.js & Socket.io chat application running on Heroku that I want to integrate into my main rails website. I understand the way to do this is to have two separate Heroku apps - one for rails, one for Node.js.
It doesn't appear to be as simple as moving the client html from the node app to the rails app (giving it the other app's url in 'io.connect();').
The chat app server seems to automatically call the client index.html its own application, and not allow an external source to connect to it. Removing the code that does this (marked below) does not make it work.
I'm painfully new to Node.js & Socket.io and am hoping that this might be a relatively simple fix for a pro.
I believe the functionality I'm after here works in Liam Kaufman's excellent rails/node.js/socket.io example - his node.js server code is here: https://github.com/liamks/Chatty-Node-Server/blob/master/chat-server.js
I've tried mocking my app's code up to be like his, but haven't yet been able to make it work. He e.g. appears to use an 'http' server, whereas mine uses an 'express' server - I wondered if this might be relevant.
Any help would be greatly appreciated.
UPDATE: Ok, so a bizarre turn of events, thanks to redhotvengeance's reply below I've got this working - server is up on heroku and my client html and javascript connects to it. Great - code below. The problem is, however, that the client html file only connects when it's outside of the Rails app!! i.e. on my desktop!! The moment I put it in the rails application's public/ folder or in a view on my localhost, I get nothing! This makes no sense. I checked it wasn't because of any other random erroneous javascript in my asset pipeline conflicting by just creating a new rails app and dropping the html file in the public/ folder - again nothing - just a dead html page that doesn't connect. Does anyone have any idea what might be going on here? Does Rails have some security feature in place that stops connections to external servers or something??
UPDATE 2: I'm told this has something to do with the 'same origin policy', and I'm in trouble. Is there any way around it? Seems Liam didn't have this problem.
Client:
<script src="http://calm-sands-3826.herokuapp.com/socket.io/socket.io.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
var socket = io.connect('http://calm-sands-3826.herokuapp.com');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatelog', function (username, data) {
$('#log').append('<b>'+username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updateusers', this updates the username list
socket.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('<div>' + key + '</div>');
});
});
</script>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
<b>USERS</b>
<div id="users"></div>
</div>
<div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;">
<div id="log"></div>
</div>
Server:
var port = process.env.PORT || 5001;
var io = require('socket.io').listen(parseInt(port));
io.configure(function(){
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
io.set("close timeout", 10);
io.set("log level", 1);
})
// usernames which are currently connected to the chat
var usernames = {};
io.sockets.on('connection', function (socket) {
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// we store the username in the socket session for this client
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
// echo to client they've connected
socket.emit('updatelog', 'SERVER', 'you have connected');
// echo globally (all clients) that a person has connected
socket.broadcast.emit('updatelog', 'SERVER', username + ' has connected');
// update the list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
});
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
delete usernames[socket.username];
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatelog', 'SERVER', socket.username + ' has disconnected');
});
});
If what you're trying to do is connect pages in your Rails app to your seperate Node.js app running socket.io, then skip setting up Express entirely. You're not looking to actually serve pages from your Node app, just connect users to the socket.io server.
Let's say your Node.js app on Heroku is called: my-awesome-socket-app.
my-awesome-socket-app:
var io = require('socket.io').listen(parseInt(process.env.PORT));
io.configure(function () {
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
});
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
io.sockets.emit('user disconnected');
});
});
Then, in the Rails pages you want to connect to the socket.io server:
<script src="http://my-awesome-socket-app.herokuapp.com/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://my-awesome-socket-app.herokuapp.com');
socket.on('connect', function (data) {
console.log('connected!');
});
</script>

Backbone Model from Hub in SignalR

How can i create/convert this script into model in Backbone that can use SignaR Hubs? For example:
<script type="text/javascript">
$(function () {
// Proxy created on the fly
var chat = $.connection.chat;
// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) {
alert("message");
};
// Start the connection
$.connection.hub.start();
});
</script>
EDIT
I did come up with this:
window.Message = Backbone.Model.extend({
hub: undefined,
initialize: function () {
this.hub = $.connection.message;
},
addMessage: function (message) {
alert(message);
},
connect: function () {
$.connection.hub.start();
var messages = this.hub.getAll();//get messages
}
});
but this is not working due to the following error:
this error: :55885 Unexpected response code: 200
If you use default settings SignalR will first try to send a websockets poll to the server. The :55885 is simply the port number of your server. Websockets protocol expects a response status code of 101 (see http://dev.w3.org/html5/websockets/).
If running IIS, unless you run Windows 8 with ASP.NET 4.5 your webserver, it will not recognize a web sockets request and (begin speculation) treat it as a normal get request and return status code 200 (OK) (end speculation) which is an unexpected response in the eyes of the websockets initiator. When this happens SignalR falls back to longpolling instead.
This might not answer your question but it will help you understand the error you get (which is likely not the reason why your code doesn't work)
Also, check out http://srtsolutions.github.com/backbone.signalr/ which is a Backbone.js/SignalR integration Nuget package.

How use token authentication with Rails, Devise and Backbone.js?

I'm trying to build a mobile application with PhoneGap, jQuery Mobile and Backbone.js on the client-side - with a Rails 3 JSON API running server-side.
I know how to fetch the token from the server after being authenticated, but I don't know how to append the "token_auth" key/value to all the AJAX-requests Backbone.js will make to my server.
Here's my flow at the moment:
User types in some form fields and hits "Log in"
Backbone creates a new Player object with the email and password info.
I run a Player.authenticate that sets the token to AUTHENTICATION_TOKEN
All requests after this should append "auth_token=" + AUTHENTICATION_TOKEN
I've looked at http://documentcloud.github.com/backbone/#Sync for maybe overriding the AJAX calls - but that seems quite extreme for this simple task.
Does anyone have any experience with running Devise token_authentication and Backbone.js?
The key is to introduce it in the Backbone.sync method.
Take a look at this implementation: https://github.com/codebrew/backbone-rails/blob/master/vendor/assets/javascripts/backbone_rails_sync.js
You can add it yourself this way:
Backbone.old_sync = Backbone.sync
Backbone.sync = function(method, model, options) {
var new_options = _.extend({
beforeSend: function(xhr) {
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
}
}, options)
return Backbone.old_sync(method, model, new_options);
};
Check out this fiddle: http://jsfiddle.net/dira/ZcY3D/14/
Why don't append it to all of your jquery ajax requests. It will add the auth_token to all of your ajax calls over jQuery. That might be useful when working directly with jQuery ajax (or libs that do so). But this might be a security issue as well (when you have ajax calls to other sites...).
// this is untested
$.ajaxSetup({ beforeSend : function(xhr, settings){
// just because the auth_token is a private information
if(!settings.crossDomain) {
// parse data object
var dataobj = JSON.parse(xhr.data);
// add authentication token to the data object
dataobj.auth_token = AUTHENTICATION_TOKEN;
// save the dataobject into the jqXHR object
xhr.data = JSON.stringify(dataobj);
}
}});
Another approach may be to write that token into the header and process it on the server side:
// thats not beautiful
$.ajaxSetup({ headers : { "auth_token" : AUTHENTICATION_TOKEN } });
Create a function like this that will send it any time an ajax request is sent to the server
$(function(){
$(document).ajaxSend(function(e, xhr, options) {
var token = $("meta[name='csrf-token']").attr("content");
xhr.setRequestHeader("X-CSRF-Token", token);
});
})

Resources