My Problem:
My app has number of pages/resources that should be accessible by guest users but only after providing correct pair [Resource Code - Unique Token] (each page has one Page Code and multiple unique "Tokens" issued for each user). Tokens are generated beforehand and stored in DB. After accessing the page, user will be able to interact with multiple other resources belonging to particular page.
How I organized this so far:
Page asks user to provide token and checks it with records in DB. If this is a correct token for resource requested, it writes cookie and then, every time user interacts with the resource or its content, controller will every time read cookie and check [PageCode-Token] pair with database before continuing the action.
Question:
Is there any other, more elegant and efficient approach? Should I use Session instead? I feel a bit bad about querying DB every time.
This depends on how many users access your service, if the volume is too large it would be recommended to create a cache where all tokens are stored, thus avoiding a database overload. However if the service is not widely used this is not necessary as a database can handle a lot of requests.
You could create a cache in two ways, using ready-made software or create a small cache within the project itself.
If you choose to use software, I would recommend Redis, it is a cache database that stores values with or without a timeout, ie after a while the tokens are deleted.
Keep in mind that this does not prevent you from making requests to the database, but you will always make requests to the cache first (Redis) and if the value does not exist, it is necessary to search within the database.
But if you choose to create your own, you will need to do most things manually and always knowing how much resources can be allocated. It may be more advantageous to use software than reinvent the stone.
Related
I have an MVC application, where one controller returns a View that have an iframe , controller also returns url that need to loaded.
I need that iframe to load legacy .aspx pages.
Now I want to share some data from MVC controller to that .aspx page via 'SESSION' or 'Request' object.
Is it possible ? Do I have any other alternative to share data securely (I don't want to pass as get parameters).
Since we are talking about two different applications, there are some options but none through SESSION
Your first issue is how to identify the same user. There are two options here.
Through the use of cookies, if both applications are in the same domain. You can store a session identifier there and it will be sent to both applications. A jwt token would do fine or any other session identifier
Through the use of a single sign on system. This would be more tricky to implement and there are a lot of oauth/openidconnect systems out there to choose from.
Now onto the session iteself. Since we are talking about two applications, you are going to need some kind of shared place to store the session values
The simplest form would be a shared database where you store the session values. It could be in memory tables in mssql to speed things up. On the downside, you should be careful to invalidate/update the values which would cost in queries
Some kind of distributed cache, like REDIS.
Warning - You might see suggestions to use session state store. This is to share SESSION between servers and not so easily between applications, so I wouldn't suggest that.
Currently i'm searching for a technique to create a named user license system
with asp.net mvc. For example a customer has bought 10 user licenses, it should
only be possible, to log in 10 times parallel.
The problem I'm struggeling with, is the fact that there is no permanent
connection in web technologies. (Between client and server, besides using web sockets or some similar things).
Or is there a well known and good alternative?
Thank you very much!
A possible solution (which may or may not be the right one for you), is to store the amount of sessions a user currently has and is allowed to have in two columns in your database.
Let's say you have the functions login(username, password) and logout(username), or something similar. Then, you need two new columns in your database, one storing the maximum amount of sessions a user can have, e.g. maxSessions , the other one containing the current count of sessions a user has, e.g. curSessions.
Now you can check with every call of login(username, password) if a user has reached the maximum of allowed sessions, and deny his access to your service. If he hasn't, add 1 to curSessions, then run your other login code. If logout(username) gets called, remove 1 from curSessions, and run your logout code.
If I understood your question the right way, this is what you were looking for.
I have somewhat of a thought problem, where I'm not sure if what I already built can be done a lot more efficiently, so that's why I'll share my 'problem' here. (to be clear, everything I have built works, I'm just looking to make it more efficient).
I have a webapp made with MVC & SQL which has a log-in system etc for users.
A user has a status, which is an enum, and can be active, blocked etc and is stored in the database (along with other user-data).
Within my webapp I have made a custom AuthorizeAttr. for authorizing users on every call made (applied as a global filter).
However, the 'normal' authentication is based on the cookie, which does not change when I would change the user-status in the database. For instance, users can de-activate another user in the same group (when being Admin). These database changes are not taking immediate effect since by default the authorization only verifies the cookie, and the cookie is based on the status when logging in.
To fix this issue, I added some additional logic to my authorizationAttr, which on every request calls the database for the current user status (the enum), and then simply does some checks whether the user is allowed to continue, or a redirect is required.
Calling the database on every request seems (even just for 1 enum) seems to be a bit taxing on the server/db especially when the webapp would grow in popularity (= lots of users).
One idea I thought of was to cache the enum in session cache but for short periods of time (like 60 seconds), this would save some database calls, but obviously the user can still use the webapp for max 60seconds after being de-activated.
I could be wrong in thinking that these database calls are actually that taxing of course.
Any ideas for improvement?
how do you know that checking status per request is too expensive? did you measure performance cost of checking user status in the database? have you created your custom cache without actually measuring the cost of simple solution? do you use ORM like hibernate? they have 2nd level cache built in so often there will be no roundtrip to the database.
i think it's way better to stick to the KISS principle rather than creating custom solution for a difficult problem. even if your database will be the bottleneck then usually buying additional hardware once is cheaper than maintaining overcomplicated solution for years
if your application grow, first thing you throw away is relation database
Have you considered using ADO.NET DataSets for your requirement? If you don't have multiple front-ends you could possibly read the login statuses initially into the dataset. All read/write operations could be made to this and you could later save your changes to the actual database. In case you have multiple front-ends, would it be possible for you to restrict all read/write/modify operations of one group to a single front-end instance? Because I guess you could use the dataset approach in that case as well.
I'm working with ASP.NET and I want to load once a big object (specific by user) in my controller and then use it in my view.
I though about a static property but I find some problems with it.
See : Is it a bad idea to use a large static variable?
I'm not familiar with this language and I have no idea how to properly share the same object between the different methods for each user. Could you tell me how to do that ? Do you know if singleton could be a solution ?
A singleton won't help you here if this big object is going to be different for every user.
Without knowing all the details, I'd say perhaps your best option is to store it in the Session object,
HttpContext.Current.Session["bigObject"] = bigObject;
Depending on the size & traffic, this can have performance problems, so I'd suggest you read up on the pros and cons of using Session
If you want to get to use something for the next simultaneous request, then use TempData - which is a bucket where you can hold data that is only needed for the following request. That is, anything you put into TempData is discarded after the next request completes.
If you want to persist the information specific to user, then go for Session. With session, you will have timeout, so that after certain amount of time the data stored in session will be lost. You can configure this value to much more bigger value. Apart from that when you go for Webfarm of servers, then maintaining session will be a problem, probably you might need to go for managing session in SQL Server or in some other store.
Alternatively you can Use Runtime Cache object in ASP.Net MVC to keep all the common data. Cached data can be accessed fast and we have other benefits like expiring cache etc. You can share this Cache object across users, or you can maintain different cache objects for different users, that is purely dependent on your logic. In case of webfarms, yo u have distributed cache servers like redis, Azure Cache service etc., which you can use them.
C# - ASP MVC - .NET 4.5 - Bootstrap - Razor
I have a form wizard (http://vadimg.com/twitter-bootstrap-wizard-example/examples/basic.html) that is used to setup a complex object (obj1). A property of obj1 is a List<obj2>. On one step of the wizard I want to add multiple obj2's to the list. Since obj2 is slightly complex as well, I thought I would use another wizard to help build it. Except I need to persist this List<obj2> on wizard 1, while I'm off in wizard 2 building another obj2.
My first thought was to use a session to hold the List<obj2>, I was just wondering if that's a good option, or if there would be a better one? The user may leave from Wizard1 to go to Wizard2 and come back multiple times.
There's no perfect answer here; each approach has trade-offs. But here are some options that I can think of (and these are independent of ASP.NET/C#)
Session (as you suggest)
This will store data in web server memory (by default). If you have a lot of users, this could be a problem.
You risk the information being lost when the user gets a new cookie/the session times out.
Potentially better performance that a db, depending again on the number of users
Database (as you mentioned)
Could cause more database traffic.
Can save information for user even if they close a browser, switch computer, the power goes out, etc.
Maybe a separate NoSQL database just for transient wizard data would be worth trying.
Cookie (store data on the user's computer)
Users can potentially tamper with/view the data
There is a limit on cookie size (4 KB each?)
Local storage (HTML5)
Similar to cookies
But not such a small limit
Not every browser supports it (may need polyfill)
Form/Post/Hidden/ViewState
You could just post the data and drag the information from response to response
But this gets really annoying with back buttons & timeouts
Lots of work, and again, the user can tamper with the information