how to use both express.io and passport.socketio authentication features globally - express

socket.io supports a single global authorization method with no middleware feature. Both express.io and passport.socketio depend on this feature as an injection point for their logic.
express.io attaches the express session to the request, and passport.socketio attaches the inflated user object. how do I combine the two features elegantly?

The only way I found is grabbing the authorization callback of express.io from socket.io and wiring it to be passport.socketio's success callback:
app.io.configure(function() {
var expressAuth = app.io.get('authorization');
var sessionConfig = {
...
success : expressAuth // callback on success
};
app.io.set('authorization', passportSocketIo.authorize(sessionConfig));
});
This works for me, but It's coupled with the order of the 'authorization' registrations. Any better ideas?

Related

Blazor - Circular references - serialization and deserialization default options

In a Blazor WebAssembly app I have one single server side method that returns results with circular references.
I found out that I can handle this situation on the server side by adding the following:
builder.Services.AddControllersWithViews()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
});
and on the client side:
var options = new JsonSerializerOptions() { ReferenceHandler = ReferenceHandler.Preserve };
var r = await _http.GetFromJsonAsync<MyObject>>($"api/mycontroller/mymethod", options);
Unfortunately this way reference handling is enabled for every method on server. This introduces "$id" keys in almost all my methods results.
This would force me to change every client call to introduce ReferenceHandler.Preserve option.
Is there a way to specify ReferenceHandler.Preserve for some methods only (server side) or alternatively an option to force ReferenceHandler.Preserve for every GetFromJsonAsync (client side)?
You can use custom middleware in your sever . In custom middleware , you can put the method in it and do judge the URL passed by blazor. If the url meets the requirements, execute the method in the middleware, If not ,Just ignore this method.

JWT authentication with gundb

Can i use JWT authentication with gundb? And if so, would it dramatically slow down my sync speed? I was going to try and implement a test using the tutorial here but wanted to see if there were any 'gotchas' I should be aware of.
The API has changed to use a middleware system. The SEA (Security, Encryption, Authorization) framework will be published to handle stuff like this. However, you can roll your own by doing something like this on the server:
Gun.on('opt', function(ctx){
if(ctx.once){ return }
ctx.on('in', function(msg){
var to = this.to;
// process message.
to.next(msg); // pass to next middleware
});
});
Registering the in listener via the opt hook lets this middleware become 1st in line (before even gun core), that way you can filter all inputs and reject them if necessary (by not calling to.next(msg)).
Likewise to add headers on the client you would want to register an out listener (similarly to how we did for the in) and modify the outgoing message to have msg.headers = {token: data} and then pass it forward to the next middleware layers (which will probably be websocket/transport hooks) by doing to.next(msg) as well. More docs to come on this as it stabilizes.
Old Answer:
A very late answer, sorry this was not addressed sooner:
The default websocket/ajax adapter allows you to update a headers property that gets passed on every networked message:
gun.opt({
headers: { token: JWT },
});
On the server you can then intercept and reject/authorize requests based on the token:
gun.wsp(server, function(req, res, next){
if('get' === req.method){
return next(req, res);
}
if('put' === req.method){
return res({body: {err: "Permission denied!"}});
}
});
The above example rejects all writes and authorizes all reads, but you would replace this logic with your own rules.

Ember authentication with Oauth server/client

I am trying to design the authentication flow of an Ember application with a Rails backend. I basically want to authenticate users via Google/Facebook/etc., I do not want to provide an 'independent' authentication service. I do want to maintain a list of users of course on the server side, potentially merging different authentications from different sources into the same user. I will not interact on behalf of the user on Google/Facebook from the client side, but I will do that on the server side.
For the above reason I was planning to do the following:
I will use torii to fetch an auth_token on the client side and I will pass that onto the server side, where I will validate it, convert it into an access token.
I will generate a custom token on the server side which I will send back to the client and require all further API calls to be accompanied by that token. I will not share the access token with the client at all.
Would you say that this is an optimal flow?
In terms of implementation, I have been able to get auth_tokens from the different providers using the example here. I am completely unsure however:
if I need ember-simple-auth or only torii (how do these two complement each other?)
how do I pass the auth token to the server side? With the code below I can get the auth token, but is this the proper place to implement the call to the API?
export default Ember.Route.extend({
actions: {
googleLogin: function() {
var _this = this;
this.get('session').authenticate('simple-auth-authenticator:torii', 'google-oauth2').then(
function() {console.log(_this.get('session.secure.authorizationCode'));}
);
return;
},
facebookLogin: function() {
this.get('session').authenticate('simple-auth-authenticator:torii', 'facebook-oauth2');
return;
}
}
});
how do I make all further requests to the API to be accompanied by a specific token?
should I use devise on the server side to make it easier or not?
I have been implemented exactly the same kind of workflow.
I used ember-simple-auth with ember-simple-auth-torii and implemented a custom authenticator to achieve this goal.
Ember-simple-auth provides an example of a custom authenticator here .
Your custom authenticator implementation will look like the following
First get auth_token using torii
Then valid this auth_token against your backend in order to get your custom token
Your authenticate callback in your custom authenticator will basically look like the following :
authenticate: function(provider, options) {
var self = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
self.torii.open(provider, options || {}).then(function(data) {
var endpoint = '/token'; // Your API endpoint used to get your cutom token
var dataToSend = { // Data sent to your endpoint
grant_type: 'authorization_code',
code: data.accessToken,
access_token: data.accessToken
};
$.post(endpoint, dataToSend).done(function(response) {
response.provider = provider;
resolve(data);
}).fail(function(response) {
response.provider = provider;
reject(data);
})
}, reject)
})
}
Once you have the custom authenticator initilized you can use it this way on your controllers :
this.get('session').authenticate(
'authenticator:customauthenticator', // Or wathever name you gave
'facebook-connect' // Any compatible torii provider
).then(function(user) {
console.log(user); // Will display ajax response from your endpoint
})
Finally, if you want your custom token to be automatically sent with all ajax request, you can use the ember-simple-auth oauth2-bearer authorizer.

How to call an express.js handler from another handler

I'm building an isomorphic React application which is using express.js on the server. The client app makes a number of AJAX requests to other express handler which currently entails them making multiple HTTP requests to itself.
As an optimisation I'd like to intercept requests I know the server handles and call them directly (thus avoiding the cost of leaving the application bounds). I've got as far as accessing the apps router to know which routes it handlers however I'm struggling to find the best way to start a new request. So my question is:
How do I get express to handle an HTTP request that comes from a programatic source rather than the network?
I would suggest create a common service and require it in both the handlers. What I do is break the business logic in the service and create controllers which handles the request and call specific services in this way u can use multiple services in same controller eg.
router.js
var clientController = require('../controllers/client-controller.js');
module.exports = function(router) {
router.get('/clients', clientController.getAll);
};
client-controller.js
var clientService = require('../services/client-service.js');
function getAll(req, res) {
clientService.getAll().then(function(data) {
res.json(data);
}, function(err) {
res.json(err);
});
}
module.exports.getAll = getAll;
client-service.js
function getAll() {
// implementation
}
module.exports.getAll = getAll;
u can also use something like http://visionmedia.github.io/superagent/ to make http calls from controllers and make use of them.

How to configure Stormpath as middleware in Sails.js

What is the best way to implement the following code in sails.js v0.10.5? Should I be handling this with a policy, and if so, how? The init() function required by Stormpath requires Express (app) as an argument. Currently, I am using the following code in sails.config.http.js as custom middleware.
customMiddleware: function(app) {
var stormpathMiddleware = require('express-stormpath').init(app, {
apiKeyFile: '',
application: '',
secretKey: ''
});
app.use(stormpathMiddleware);
}
Yes, this is the preferred way of enabling custom Express middleware with Sails if it does more than just handling a request (as in your case, where .init requires app). For simpler cases where you want to implement custom middleware that just handles requests, you can add the handler to sails.config.http.middleware and also add the handler name to the sails.config.http.middleware.order array. See the commented out defaults in config/http.js for an example using myRequestLogger.
Also note that the $custom key in the sails.config.http.middleware.order array indicates where the customMiddleware code will be executed, so you can change the order if necessary.