It is not clear from documentation what this operation does.
Closing the session store
To cleanly close the session store:
sessionStore.close();
What does actually close the session store mean?
I need to sign out a user. I merely need to delete a session record from a DB. Do I need close the session store in order to achieve it?
In order to destroy a session
router.route('/logout')
.get((req, res, next) => {
req.session.destroy(function(err) {
return res.redirect(302, '/login');
})
});
From the source, calling sessionStore.close() ends the db connection.
To logout the user, you can either
destroy the session by calling req.session.destroy()
or, if you are using passport.js, call req.logOut()
Related
I use CodeIgniter 3 and MariaDB 5.0 on my dev environment (but MySQL 5.6 in the prod environment).
I created a web app, and implemented a validation chain to accept the user requests.
For example:
User A asked for something
The manager validate
The deputy validate
The commission validate
The accounting department validate
The request is accepted
Those validations are registered in the database, in several tables.
I uses the SQL transaction to update/insert the data correctly with
CodeIgniter's functions and CRUD models, example:
$this->db->trans_start();
$this->my_model->create($data);
$another_data = $this->second_model->read($second_data);
$this->another_model->create($another_data);
$this->db->trans_complete();
But now, I have to implement a new rule for the General Manager. He has the capacity to validate anytime, and this validation breaks the validation chain because it count as everyone had validated.
This case could be an example:
User A asked for something
The manager validate
The general manager validate
The request is accepted
I'm not sure how to implement this, because I realised that 2 users (the general manager and the deputy for example) could consult the same request, one refuses, the other validate, and the data are not consistent anymore.
Is the transaction good enough ? Like:
// User A asked for something
// The manager validate
// The deputy consult the request
// The manager consult the request
// The deputy validate:
$this->db->trans_start();
// check if already validated by the general manager
if ($this->model->read($data)) {
$this->db->trans_complete();
// redirection to a warning page
}
else {
$this->my_model->create($my_data);
}
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
// redirection to another warning page
// The general manager wants to refuse at the same time but the deputy's transaction started first, so he's redirected to a warning page
$this->db->trans_start();
// check if already validated by anyone
if ($this->model->read($data)) {
$this->db->trans_complete();
// redirection to a warning page
}
else {
$this->my_model->create($my_data);
}
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
// redirection to another warning page
// The validation chain continues after the deputy's validation
I thought about the LOCK TABLE to forbid a user to reach the validation page while someone else is consulting the same request. But TRANSACTION and LOCK TABLE are hard to implement because it can trigger implicit commits, and I'm not used enough to do this right.
I read about START TRANSACTION READ WRITE that could be a better solution, but I didn't understood the all thing, and I'm not sure how to implement this correctly.
Could anyone help me to implement the good strategy, and if possible the way to use these SQL functions if needed ?
I found the solution, I used the FOR UPDATE just after my query, here it is:
// the query for my results
private model_function_for_query() {
$this->db->select('my_select');
$this->db->from('my_table');
$this->db->where('my_where_clause');
return $this->db->get_compiled_select();
}
// the function to apply the FOR UPDATE on the query
public model_function() {
$query = $this->model_function_for_query();
$result = $this->db->query($query.' FOR UPDATE');
return $result->row();
}
And in my controller:
// start the transaction
$this->db->trans_start();
// do the query, locking tables
$data = $this->my_model->model_function();
// check if the data has not changed
...
// if not, do the data treatment, else redirect to the warning page
...
// close the transaction
$this->db->trans_complete();
// check if the transaction failed, and do the stuff
if ($this->db->trans_status() === FALSE)
...
else
...
I would like to know what the correct place to close a connection to the database is.
Let's say that I have the following piece of code:
function addItem(dbName, versionNumber, storeName, element, callback){
var requestOpenDB = indexedDB.open(dbName, versionNumber); //IDBRequest
requestOpenDB.onsuccess = function(event){
//console.log ("requestOpenDB.onsuccess ");
var db = event.target.result;
var trans = db.transaction(storeName, "readwrite");
var store = trans.objectStore(storeName);
var requestAdd = store.add(element);
requestAdd.onsuccess = function(event) {
callback("Success");
};
requestAdd.onerror = function(event) {
callback("Error");
};
};
requestOpenDB.onerror = function(event) {
console.log ("Error:" + event.srcElement.error.message);/* handle error */
callback("Error");
};
}
addItem basically adds a new element into the database. As per my understanding, when the requestAdd event is triggered that doesn't mean necessarily that the transaction has finished. Therefore I am wondering what the best place to call db.close() is. I was closing the connection inside of requestAdd.onsucess, but if an error happens and requestAdd.onerror is triggered instead, the connection might still be opened. I am thinking about adding trans.oncomplete just under request.onerror and close the db connection here which might be a better option. Any inputs will be more than welcome. Thank you.
You may wish to explicitly close a connection if you anticipate upgrading your database schema. Here's the scenario:
A user opens your site in one tab (tab #1), and leaves it open.
You push an update to your site, which includes code to upgrade the database schema, increasing the version number.
The same user opens a second tab to your site (tab #2) and it attempts to connect to the database.
If the connection is held open by tab #1, the connection/upgrade attempt by tab #2 will be blocked. Tab #1 will see a "versionchange" event (so it could close on demand); if it doesn't close its connection then tab #2 will see a "blocked" event.
If the connection is not held open by tab #1, then tab #2 will be able to connect and upgrade. If tab #1 then tries (based on user action, etc) to open the database (with an explicit version number) it will fail since it will be using an old version number (since it still has the old code).
You generally never need to close a connection. You are not creating memory leaks or anything like that. Leaving the connection open does not result in a material performance hit.
I would suggest not worrying about it.
Also, whether you add trans.oncomplete before or after request.onerror is not important. I understand how it can be confusing, but the order in which you bind the listeners is irrelevant (qualified: from within the same function scope).
You can call db.close() immediately after creating the transaction
var trans = db.transaction(storeName, "readwrite");
db.close();
and it will close the connection only after the transaction has completed.
https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/close says
The connection is not actually closed until all transactions created using this connection are complete. No new transactions can be created for this connection once this method is called.
If you want to run multiple versions of your app and both access the same database, you might think it's possible to keep connections open to both. This is not possible. You must close the database on one before opening it on another. But one problem is that there is currently no way to know when the database actually closes.
I have used YII's session_id's to track user activity across a website with the following code snippet:
Yii::app()->getSession()->getSessionId()
How do I get same sessionid in Yii2? I tried quite possible way, but its all vain.
Please share the exact code snippet for Yii2.
You can try with
Yii::$app->session->getId();
this guide could be useful to you http://www.yiiframework.com/doc-2.0/guide-runtime-sessions-cookies.html
try checking if a session is already active before and ifnot use session open() .
session = Yii::$app->session;
// check if a session is already open
if ($session->isActive) ...
// open a session
$session->open();
// close a session
$session->close();
// destroys all data registered to a session.
$session->destroy();
$session = Yii::$app->session;
// if session is not open, open session
if ( !$session->isActive) { $session->open(); }
// get session id
Yii::$app->session->getId();
I got 26 character string in session id. "itddoa1lr247phpds34aemr0v0"
This link can be helpful: http://www.yiiframework.com/doc-2.0/guide-runtime-sessions-cookies.html#sessions
Yii::$app->session->Id
And no need to explicitly open session. When you access session data through the session component, a session will be automatically opened if it has not been done so before.
http://www.yiiframework.com/doc-2.0/guide-runtime-sessions-cookies.html#sessions
I've set up cookie based login just like the guy in this thread. I can see that auth key is always generated correctly. I can see it in the DB and in cookie also. Cookie also has the proper expiration date. Nevertheless, I never get signed in automatically. I have set 'enableAutoLogin' => true and all the other methods are as default. So it should work. I read somewhere that calling Yii::$app->user->identity should trigger cookie login, but it doesn't. Any advice?
Do you set duration for login method?
Method User::login() has second argument named "duration". By default it is 0. It mean the identity information will be stored in session as long as the session remains active. If you want autologin, set duration > 0.
The problem might be caused by data retrieved from cookie. The $id parameter in User::findIdentity was not a MongoId or string but an array. Simplest solution is to overwrite the method e.g:
public static function findIdentity($id)
{
if(!empty($id) && is_array($id))
$id = new \MongoId($id['$id']);
return static::findOne($id);
}
I found this great node mysql boilerplate:
https://github.com/ocastillo/nodejs-mysql-boilerplate
it works terrific! However, now I need to hook it in to my existing user table, and my key field is named userID, not simply id, and changing the key fieldname in mysql breaks the example. So my question is, where in the project do I need to specify a different id field name? I see user.id in /util/auth.js passport.serializeUser and id in passport.deserializeUser functions, but it seems it must be specified elsewhere too. I'm hoping this is a simple question for users of passportjs!
Yes, you should only need to change the code in the serializeUser and deserializeUser functions. Those two functions you control, and state within them what you'd like to serialize into the session cookie (when the user logs in), and deserialize from the session cookie (when the user revisits the site after logging in). Think of them as ways to remember who this person is, once they return. The passport.use function is only used to define the authentication strategy, and within that, the manner in which you'll "log the user in".
So this should work (assuming I've followed what you've said above):
passport.serializeUser(function(user, done) {
done(null, user.userID);
});
passport.deserializeUser(function(user_id, done) {
new data.ApiUser({userID: user_id}).fetch().then(function(user) {
return done(null, user);
}, function(error) {
return done(error);
});
});
You might benefit from more examples, here's a gist I put together on passport configuration within Node (however this one uses Mongo): https://gist.github.com/dylants/8030433