I use a user object (attribute email, display name, permissions…) on several areas.
Is it possible to load the user details after the login and save it for the complete live time?
Or I need to reload the user information from Azure database by each load a new page?
Regards
Stefan
Your question is hard to understand, but if you're asking if you need to query the user with each request, the answer is yes. HTTP is a stateless protocol. Each request that is made is as if nothing happened before or since. In other words, the fact that you queried something from your database on a previous request has no bearing whatsoever on the current request.
You can use sessions to fake state, by persisting a serialized representation of the object in the session store. However, the session store will be a database, itself, if you're doing it right, so it still would involve a query. The only benefit would be that the query would be simplistic. In other words, there's some value of persisting to the session or some other form of cache if your original query was extremely complex and/or time-consuming to complete. However, querying a row by id is about as simplistic as a query can get, so that's not the situation here.
Long and short, if you need the user again, just query it again.
Related
So for the login, since it doesn't really make anything new in the database but rather just returns if we've logged in, and possibly some user data, should it be a command or query?
And as for the register, since it creates a new user, should it be a command then? What if i want to return the users data or a jwt?
Should i run my commands and once the client receives a response run a query right after them?
As with most design related questions, I’d answer this one with ‘it depends’. I have seen both solutions implemented in different situations.
The main question you’d need to ask is whether you consider a user logging in as a state change of the system or not. Note that whether it changes state in de database isn’t relevant. The system is more than the database.
Log in as a command
For some systems, it’s important to know which users had been logged in and when, from where, etc. One example I had seen was a medical system that needed to record which doctor logged in when and where, and which medical records had been accessed. Also, logging in on one machine would stop tbe session on another. A reliable trace of these actions was essential to the application. As such, log in was implemented as a command which generated events that were stored in the Event Store. Projections kept the current logged in state for each user.
Log in as a query
Most systems I have seen, however, simple beed to know whether any given credentials can ve mapped to a user account. If that is the case, a token is generated containing the ‘proof’ of authentication. The system itself doesn’t really care who is logged in. It’s just that each request needs to be validated by checking the ‘proof’. In this case, logging in is a query.
What is the correct and safe way to persist the user authentication state after refreshing the page?
So far I created a custom AuthenticationStateProvider that reads the state from the Browser Storage and it works fine, however I came across many opinions that this is not safe to keep sensitive data there, which are in my case Id, Name, Last Name, Role and TimeStamp of the user (in a form of encrypted JSON saved via ASP.NET Core Protected Browser Storage).
I've read about many other possibilities, but none seem to be the right one:
Cookie - in Server-Side Blazor (Razor Components) it's only possible to create/read a cookie on the initial Http request, what makes it impossible to work if the user logs-in afterwards
CircuitHandler - after refresh there's completely new Circuit established, so all the session information get lost
Linking current session to the User's IP - in majority of cases it remains the same after refreshing, but it's also not safe and not reliable enough
So what am I missing here to make it work right? Are there any other possibilities for server-side Blazor?
thanks a lot for your contribution, I went through a lot of your posts already and they really cleared many things up for me :)
The sources I've read about it mentioned Cookies as a better way for that, only.
Currently my solution is that i just serialize ClaimsIdentity directly into Json and save encoded string into Storage. The biggest concern I have is that no matter how hard encoded the string would be, anybody could just copy this and decode in his own code, even via mentioned previously ASP.NET Core Protected Browser Storage and simply change his role to get extended access and decode again.
That's why I thought about mplementing some kind of Storage OnChange event handler that would force the user to provide login information again and download fresh data from the database or Storage revalidation after x minutes whether it's still in line with Db.
How can I tell if a user is logged in using straight SQL based on their email address?
We have a system that is highly coupled with ExpressionEngine and cannot use the Magento API in many of the EE templates.
Edit to show current login code:
Mage::getSingleton('core/session', array('name'=>'frontend'));
$session = Mage::getSingleton('customer/session');
$session->login($ParticipantInfo['PreferedEmailAddress'],'default_password');
$session->setCustomerAsLoggedIn($session->getCustomer());
TL;DR: As far as i know, even if session data is stored in the db, there is no definite way of telling only via plain SQL.
Question would also be: Which user? Customer, admin or api user? Assuming you store session data within the file system, I could think of some options:
API
For API-Users, have a look at the api_session table, you can do a join with the api_user table, which stores the email address. However, there is no way, the information in these two tables will suffice, as only session id and logdate are saved for a specific user id and you have no way of telling if a session is still active.
Querying for this data those would probably be something along the lines of:
SELECT *
FROM api_user
INNER JOIN api_session ON api_user.user_id = api_session.user_id
WHERE api_user.email = "<known_email>"
Admin & Customer
Admin users are stored within admin_user, however, like for api_user, no information is stored along for session management.
Customers are stored within the customer_* tables. You can look them up in the log_visitortable:
SELECT *
FROM log_visitor_online
INNER JOIN customer_entity ON customer_entity.entity_id = log_visitor_online.customer_id
WHERE c.email = "<known_email>"
Again, no information can be retrieved, if the session is still valid. EDIT: Tim showed how to do it correctly in his answer.
The bad news, in general
No information is stored directly, if a user is logged in currently, only, when the creation date of the session. With out-of-the box functionality you should not be able to tell accurately via SQL if a user is currently logged in or not - this would be insensible at best, as magento checks the user's session's validity against the stored session data in the db/filesystem, so without the user's session data, you can determine nothing with 100% accuracy.
The good news if you can write a module
With a little bit of work you can hook into the session management of Magento. There's a cheat sheet for events the core ships with. You can also create you own custom events, which you may listen to and execute code upon.
The idea here would be to write a module which could store extra information on the customer (admin or api user vice versa) or within an extra module table. You can hook into the login process and set a timestamp for the api_user/customer/admin has logged in and refresh that timestamp upon a request. If a user's timestamp hasn't been refreshed for, let's say, X Seconds, you assume the user is logged in any more. You delete the user's timestamp upon the logout event.
However, this is also not 100% accurate and it heavily depends on what a user does in you system.
Anyway, I hope I could provide some insight.
lg,
flo
In my application I want to prompt a user about a new feature with some kind of a dialog the first time they visit the screen. And on a subsequent visit this dialog is not shown.
The obvious solution is to use a cookie or save this in the database.
But I'm concerned that:
- over time all the checks in the code will result in messy code
- with the database solution - it can bring performance issues.
And also if the user clears his cookies (for example) I don't want them to see every new feature update for the past two years (one screen can be have multiple new features over time).
Is there a stupid/simple way to handle this? How does twitter and facebook do this when they promote their new features?
My environment is MSSQL, ASP MVC if does matter.
Use both - cookies as a caching technique - first check the cookie. If it doesn't contain the flag - then ask the DB.
Also, you can initialize that cookie at login. One DB call per user session.
Personally, I'd use a database flag against the user record.
Like you say, cookies can be destroyed and lead to annoying duplicate reminders.
I don't think you need to worry about "messy code" if you're doing it right.
Since you have user login, I assume you also have some type of server-side session. You could store user preferences in the database, and cache them in the session upon login, avoiding going to the database for every request. As long as you trust your session for authentication purposes, you certainly can trust it for user preferences.
We store it in XML. Then you can use serialization to quickly save/load the settings. We store the XML in SQL (MS SQL have features that support XML)
Well the checks in the code are independant from the place you store the datas, it is a different problem.
As of your question I'ld say to use the database, for speed + ease reasons.
I heard in an old stackoverflow podcast that they minimized the use of sessions, and that they basically only needed it when posting. How can that be? Don't they need to use some form of sessions on every page view if nothing more than to tell that I'm logged in? How else do they show your username instead of the "Log In" prompt at the top of the screen?
When this type of thing becomes important is when you're persisting your sessions in a database. Now each time you touch your session store, you touch your database. So it would be great if you could avoid it.
You could store all your state in a cookie, but if you care at all about security, then you'll probably want to control state on your server instead.
I don't know about the podcast you're referring to, but I'm not really sure they were saying what you thought they were saying...
Session data doesn't necessarily have to be written to DB everytime it's touched. You could easily have a cached (using memcached or something similar) intermediary. You could then write the session data to DB every X amount of requests/minutes/writes/whatever.