How can a Sails controller get request history - node.js

I am developing a website using Nodejs (with Sails & Passport frameworks). I am wondering how a Sails controller get the request history of a user.
For instance, a user requests for '/', but a controller redirects the user to '/signin'. Then the user requests for '/signin' using res.redirect(). So the request history looks like
'/'
'/signin'.
Now a SignInController handles the request and at the end, it want to redirect the user back to '/'. So the controller should know the history of the user's request. I guess there should be some frameworks which can record request histories and store them using session or something. Could anyone give me some hints about this?

Let me know if I understood well but what you want to do is to redirect the user to whatever URL he was before a login, right?
To do that you can use the policies (which are executed for all requests, only on the methods you want).
What we do here is save the latest position only (Not the entire history)
In api/policies/ensureReturnToUrl:
'use strict';
module.exports = function (req, res, next) {
req.session.returnTo = req.url;
return next();
};
The configuration part look like that in config/policies.js:
'*': ['passport', 'isAuthenticated', 'ensureReturnToUrl'],
AuthController: {
'*': ['passport']
}
You will have to be careful here to put this policy in the right place only. For example, you don't want to have it on you "/signin" methods (That goes against the whole point)
Then, after a successful login, you just have to read the "returnTo" property and redirect the user: (For example in a AuthController)
if (req.session.returnTo) {
res.redirect(req.session.returnTo);
} else {
res.redirect('/');
}
Obviously this need to be adapted for your use case but the policies are definitely what you need.

Related

pass session variables to another domain

It seems this cannot be easily done...if at all.
Suppose I have 2 domains, www.mydomain.com and www.mydomain.org. Each domain uses a Node.js/Express back-end and in addition both use the "express-session" module to create session information. I wish to be able to have a user 'log in' while on one domain and have that session information pass to the other when navigation is made to the second domain.
Each domain has a 'catch-all' route that displays a 'splash' page. This is signified by the following route:
app.get('/', function (req, res) {
//do stuff and display 'splash' page...
}
I thought to pass the session information using a route that has a parameter containing the 'session' variable, and using that to set the 'logged in' user on the second domain. For example:
app.get('/user/:client', function (req, res) {
req.session.subscriber = req.params.client; //set the 'logged in' user on the second domain
//do stuff and display 'splash' page...
}
The problem is that BOTH routes seem to be called when using the route with the parameter...I suppose this makes sense since the initial route is activated using a backslash ("/")...Is there some way to correct this?
Any help about cross-domain express-session variable 'sharing' would be greatly appreciated. Thank you in advance.

In node.js with express, is there a way of changing the url of a link on the fly?

I have a link on a page:
Back
which of course takes the user to '/application-reference'. However, if the session has timed out, I want the user to taken to '/session-ended' instead. Session timed out is detected by the absence of request.session.
I've tried changing the href to send the user back to the same page (i.e. the link is in 'security-code' and takes the user to 'security-code') with the idea that the handling code can look for request.session and decide which page to redirect to, only I can find no way for the code to detect that the page has been called by itself via the back button.
I think the answer is to put something in my express module so that the router.get call that redirects to '/application-reference' will under the right circumstances redirect to '/session-ended'. But I have no idea how to go about this.
I suppose the ideal would be for the '/session-ended' screen to be invoked any time the user clicks on any screen once the session has timed out.
Any suggestions?
Inside your /application-reference-handler you could check if the session on the req-object is still valid. If not redirect the request to /session-ended:
app.get('/application-reference', (req, res) => {
if(!req.session) { // or a more detailed check for the session's validity
return res.redirect("/session-ended");
}
// rest of the handler-code ...
});
An better way to do this is to define a separate middleware to check the user's session - this allows you to reuse this middleware and not having to duplicate the check in your handlers:
function validateSession(req,res,next) {
if(!req.session) { // or a more detailed check for the session's validity
return res.redirect("/session-ended");
}
// all is good, go to the next middleware
next();
});
app.get('/application-reference', validateSession, (req, res) => { ... });

how to give user specific file access in express js

I'm using express js and passport js as authentication system also using view engine. I'm looking for a solution that would give access to user and let users see their file, not the other one's file. for example, in the image folder, the user would access to their files and after that, I want to pass these files to view engine. If I use the public folder, anyone is able to see every file in there. what solution do you recommend?
You should create a directory for each users.
then, for example, your URL is /show/files
the inside your logic, filter the directory by user info.
app.get('/show/files', (req,res)=>{
// filter resources by user info
})
don't forget to create a secure URL for your resources.
Bad Idea: /images/amin/profile.png
Good Idea:
create a route to serve your resources.
app.get('/resources', (req,res)=>{
// add query parameter for resource for example profile.png
// then check user directory and send it
})
your url converts into
/resousrce?file=profile.png
I assume you already have a login system in place, so all you have to do, is create a middleware that checks if the user is logged in, and checks if the image is his image.
app.use("/user/:user/**",function(req,res){
if (req.params.user == thisuser){
//serve the file
} else {
res.status(403); //access denied
res.end();
}
//check based on cookies whether the user has the permission to view this image
});
I would suggest you to use Passport.Js local authentication. You can look into the official docs - http://www.passportjs.org/docs/authenticate/ I personally have used this in the same scenario you're in.
Here is a litte code snippet of the custom middleware function I wrote using passport -
module.exports = {
ensureAuthenticated : function(req, res, next){
if(req.isAuthenticated()){
return next();
}
req.flash('error_msg', 'Please login to view this resource.')
res.redirect('/users/login');
}
}
Feel free to check the entire solution on my github repo -
https://github.com/StechAnurag/loginsys

Sails.js - use login instead of id for REST api

I'm using Sails.js framework, and I have User model with login field.
I also have User controller that allows me to send request like
http://localhost:1337/user/:id
And it returns given user data. However I'd prefer to use user login instead of user id so I could use /user/mylogin instead of /user/564a0aacecf0e8fb20c38a4e. Is there any way to do it without creating routes myself (I like how sails handle all default routes including relations like /user/:id/comments and I dont want to rebuild all of those just to use login instead of id)
You could do /user?login=username. This is handled by sails's blueprint api: http://sailsjs.org/documentation/reference/blueprint-api/find-where
If you really want it you can have it. But you have to get your hands a bit dirty. There are a few possibe ways. But I am pointing you out the easiest way seemed to me.
Add a route like following in your config/routes.js.
'/user/:myLogin': {
controller: 'user',
action:'getUserByUserLogin'
}
Add an action named getUserByUserLogin in your
api/controller/UserController.js. You can access the myLogin
value from request object from the controller action with
req.param("myLogin").
module.exports = {
getUserByUserLogin: function(req, res){
var myLogin = req.param("myLogin");
/* Do whatever you want */
}
};

Authenticate before calling route controller

I'm working on an API using restify. There will be a dozen or more endpoints and each one requires authentication. The API will be stateless, so each API request, regardless of endpoint, will pass credentials.
What I'd like to do, if possible, is to authenticate before negotiating the route. Otherwise, if I have a route:
server.get('/activities', activities.index);
Then, within activities.index (and every other routing method), I have to duplicate the following:
var user = require('../models/user')(server);
user.authenticate(req.authorization, function(err, user) {
...
// Do the real activities-related stuff.
});
This is one of those things where it feels like there must be a better way of doing it, but I don't know what it is.
Anyone have any thoughts?
So you can register handlers to be ran before every route is ran.
http://mcavage.me/node-restify/#Common-handlers:-server.use()
server.use(function(req, res, next){
//do authentication here
if(authenticated){
return next();
}
else{
res.send({auth:false});
})
So when you use server.use when the user asks for /activites it will run all of the server.use you created in the order you created them before running the code for the route.

Resources