saw this example
var sess;
app.get('/',function(req,res){
sess=req.session;
//Session set when user Request our app via URL
if(sess.email)
{
/*
* This line check Session existence.
* If it existed will do some action.
*/
res.redirect('/admin');
}
else{
res.render('index.html');
}
});
app.post('/login',function(req,res){
sess=req.session;
//In this we are assigning email to sess.email variable.
//email comes from HTML page.
sess.email=req.body.email;
res.end('done');
});
my tiny understanding is: when user login, server generates session id to him/her, assuming this is the login for the 1st time.
But in the above login code,
1. sess = req.session,sounds like client creates a session object at first ?
or client is creating a session storage space ?
2. who sets session.id or sessionID ?
3. any better example ?
The original sample is here
https://codeforgeek.com/2014/09/manage-session-using-node-js-express-4/
I am also learning node just like you. If you continue your journey, you will encounter so many similar curiousness because way node works behind the modules.
I also had so many question marks but I couldn't afford to search for right answer everytime. what I suggest is get node-inspector, a node debugger tool, and actually follow through.
That way you will actually understand what each module is doing.
instruction: https://www.youtube.com/watch?v=03qGA-GJXjI
Big tip that this instruction doesnt tell is fact that node breakpoint is bit weird.
I would definitely use "debugger;" code which puts breakpoint, rather than breakpointer that provided by tool.
Related
So, I thought that I could add a new element to the user Session to add some functionality.
I honestly thought I could do this:
SomeFunction(param1, NEWparam)
{
Session("MyNewParam") = NEWparam;
//So this would create a new session element called 'MyNewParam', right..?
...
}
That gets called when the user presses a button and then another webpage loads up.
The result, with this new line of code: The next web page doesn't load. Nothing happens.
Any and all comments are welcomed.
Solutions or helpful comments would be great.
Your syntax is right. However, I've run into an issue before where Classic ASP didn't want to take a session variable if it wasn't explicitly typed though. I'm not sure why this is, but it's worked for me in the past.
Session("MyNewParam") = parseInt(NEWparam);
Obviously, you could use String(), parseFloat()... or whatever. As I said, the syntax is right otherwise, so if the code isn't working you may want to start looking at other parts of the function that might be causing the problem.
case:
When using kohana driven site from 2 different devices I randomly get both session data on each device. I'm using native sessions to store few objects, but they should be private on each device. What am I doing wrong?
for example:
public function load()
{
$session = Session::instance();
$this->dialog = $session->get('dialog');
}
public function save()
{
$session = Session::instance();
$session->set('dialog', $this->dialog);
}
it looks like some kind of caching problem. I tried to regenerate session id every time. I've got 1st id, then 2nd, then 3rd and when i clicked a link a got 1st id again.
Make sure caching is turned off in your bootstrap file. And the cookie variables are set correctly, especially the Cookie::$domain.
Also verify your session config file too. You can find more info here: http://kohanaframework.org/3.2/guide/kohana/sessions
In the last three days I've struggled trying to find a way to accomplish what I though was supposed to be a simple thing. Doing this on my own or searching for a solution in the web, didn't help. Maybe because I'm not even sure what to look for, when I do my researches.
I'll try to explain as much as I can here: maybe someone will be able to help me.
I won't say how I'm doing it, because I've tried to do it in many ways and none of them worked for different reasons: I prefer to see a fresh advice from you.
In most of the pages of web application, I have two links (but they could be more) like that:
Option A
Option B
This is partial view, retured by a controller action.
User can select or both (all) values, but they can't never select none of them: meaning that at least one must be always selected.
These links must che accessible in almost all pages and they are not supposed to redirect to a different page, but only to store this information somewhere, to be reused when action needs to filter returned contents: a place always accessible, regarding the current controller, action or user (including non authenticated users) (session? cookie?).
This information is used to filter displayed contents in the whole web application.
So, the problem is not how to create the business logi of that, but how (and where) to store this information:
without messing with the querystring (means: keeps the querystring as empty/clean as possible)
without redirecting to other pages (user must get the current page, just with different contents)
allow this information to persists between all views, until user click again to change the option(s)
My aim is to have this information stored in a model that will contains all options and their selection status (on/off), so the appropriates PartialView will know how to display them.
Also, I could send this model to the "thing" that will handle option changes.
Thanks.
UPDATE
Following Paul's advice, I've took the Session way:
private List<OptionSelectionModel> _userOptionPreferences;
protected List<OptionSelectionModel> UserOptionPreferences
{
get
{
if (Session["UserOptionPreferences"] == null)
{
_userOptionPreferences= Lib.Options.GetOptionSelectionModelList();
}
else
{
_userOptionPreferences= Session["UserOptionPreferences"].ToString().Deserialize<List<OptionSelectionModel>>();
}
if (_userOptionPreferences.Where(g => g.Selected).Count() == 0)
{
foreach (var userOptionPreferencesin _userOptionPreferences)
{
userOptionPreferences.Selected = true;
}
}
UserOptionPreferences= _userOptionPreferences;
return _userOptionPreferences;
}
private set
{
_userOptionPreferences= value;
Session["UserOptionPreferences"] = _userOptionPreferences.SerializeObject();
}
}
Following this, I've overridden (not sure is the right conjugation of "to override" :) OnActionExecuting():
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
GetOptionSelections();
base.OnActionExecuting(filterContext);
}
GetOptionSelections()...
private void GetOptionSelections()
{
if (String.IsNullOrEmpty(Request["optionCode"])) return;
var newOptionCode = Request["optionCode "];
foreach (var userOptionPreferencesin UserOptionPreferences)
{
if (userOptionPreferences.OptionCode == newOptionCode )
userOptionPreferences.Selected = !userOptionPreferences.Selected;
}
}
This code I think can be better, but right now I just want to make it work and it doesn't.
Maybe there are also other issues there (quite sure, actually), but I believe the main issue is that OnActionExecuting is called by each action in a controller that inherit from BaseController, therefore it keeps toggling userOptionPreferences.Selected on/off, but I don't know how to make GetOptionSelections() being called only once in each View: something like the old Page_Load, but for MVC.
Last update AKA solution
Ok, using the session way, I've managed to store this information.
The other issue wasn't really on topic with this question and I've managed to solve it creating a new action that take cares of handling the option's change, then redirects to the caller URL (using the usual returnUrl parameter, but as action parameter).
This way, the option change is done only once per call.
The only thing I don't really like is that I can't simply work with the UserOptionPreferences property, as it doesn't change the session value, but only the value in memory, so I have to set the property with the new object's status each time: not a big deal, but not nice either.
This is a place to use session.
The session will keep your setting between requests while keeping it out of the url querystring. It seems that you have probably tried this already, but try it again and if you have problems ask again. I think it will be the best way for you to solve this problem.
I recently had a problem with multiple form posting in an ASP.NET MVC application. The situation was basically, if someone intentionally hammered the submit button, they could force data to be posted multiple times despite validation logic (both server and client side) that was intended to prohibit this. This occurred because their posts would go through before the Transaction.Commit() method could run on the initial request (this is all done in nHibernate)
The MVC ActionMethod looked kind of like this..
public ActionResult Create(ViewModelObject model)
{
if(ModelState.IsValid)
{
// ...
var member = membershipRepository.GetMember(User.Identity.Name);
// do stuff with member
// update member
}
}
There were a lot of solutions proposed, but I found the C# lock statement, and gave it a try, so I altered my code to look like this...
public ActionResult Create(ViewModelObject model)
{
if(ModelState.IsValid)
{
// ...
var member = membershipRepository.GetMember(User.Identity.Name);
lock(member) {
// do stuff with member
// update member
}
}
}
It worked! None of my testers can reproduce the bug, anymore! We've been hammering away at it for over a day and no one can find any flaw. But I'm not all that experienced with this keyword. I looked it up again to get clarification...
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock
Okay, that makes sense. Here is my question.
This was too easy
This solution seemed simple, straightforward, clear, efficient, and clean. It was way too simple. I know better than to think something that complicated has that simple a solution. So I wanted to ask more experienced programmers ...
Is there something bad going on I should be aware of?
No it's not that easy. Locking only works if the same instance is used.
This will not work:
public IActionResult Submit(MyModel model)
{
lock (model)
{
//will not block since each post generates it's own instance
}
}
Your example could work. It all depends on if second-level caching is enabled in nhibernate (and thus returning the same user instance). Note that it will not prevent anything from being posted to the database, just that each post will be saved in sequence.
Update
Another solution would be to add return false; to the submit button when it's being pressed. it will prevent the button from submitting the form multiple times.
Here is a jquery script that will fix the problem for you (it will go through all submit buttons and make sure that they will only submit once)
$(document).ready(function(){
$(':submit').click(function() {
var $this = $(this);
if ($this.hasClass('clicked')) {
alert('You have already clicked on submit, please be patient..');
return false;
}
$this.addClass('clicked');
});
});
Add it do you layout or to a javascript file.
Update2
Note that the jquery code works in most cases, but remember that any user with a little bit of programming knowledge can use for instance HttpWebRequest to spam POSTs to your web server. It's not likely, but it could happen. The point I'm making is that you should not rely on client side code to handle problems since they can be circumvented.
Yeah, it's that easy, but - there may be a performance hit. Remember that a Monitor lock restricts that code to be run by only one thread at a time. There is a new thread for each HTTP Request, so that means only one of those requests at any given time can access that code. If it's a long running procedure, or a lot of people are trying to access that part of the site at the same time - you might start to sluggish responses.
It's that easy, but be careful what object you lock on. It should be the same one for all the threads - for example, it could be a static object.
lock is syntactic sugar for a Monitor, so there is quite a bit going on under the cover.
Also, you should keep an eye out for deadlocks - they can happen when you lock on two or more objects.
As above: Is it possible to regenerate Code Igniter sessions manually? I'm looking for something similar to session_regenerate_id in PHP sessions, so that I could call it manually when a user went through privilege escalation.
Thanks,
Lemiant
CI automatically regenerates the session id every x seconds, which you can set in your config.
You could create a new function in Session.php the same as sess_update() but with the following removed from the top & the function renamed to regenerate_id().
// We only update the session every five minutes by default
if (($this->userdata['last_activity']+$this->sess_time_to_update) >= $this->now)
{
return;
}
This will regenerate the session id, update users_activity and keep the users data. Just call it by $this->session->regenerate_id();
I know this is an old post, but I came across it, so others might too.
You could also do the following so you don't have to hack the core files at all (making codeigniter more easily upgradable with future releases):
//Setting this to 0 forces the sess_update method to regenerate on the next call
$this->session->sess_time_to_update=0;
//Call the sess_update method to actually regenerate the session ID
$this->session->sess_update();
Credit to the original answer for leading me down this path though, thank you.