Cookie Authentication for Client - is session store needed? - express

I am creating an application and I am looking for a solution for user authentication (checking if the user is logged in, basically). I am reading online and it seems that many people recommend using a session store/table in your db (store roles, views etc..) vs. just storing the cookie id in the DB in that users column. My question is, what is the difference between storing this data in a "session" store, which is basically just another table and storing this data in your database alongside the other user data (username, passwordHash etc..). I understand that this is useful for data that may change when the user logs in and out again, but are there any advantages to having a session store if my applications state stays consistent across log ins. Thanks.

You need a way to store user data between HTTP requests and sessions helps you to do so.When a user visits our site, it creates a new session for the user and assigns them a cookie. Next time the user comes to the site , the cookie is checked and the session id which is stored in the cookie is retrieved and searched in the session store .Session store is a place where you store all your data regarding your session.So using a session store automates this method and it eases your work.So whenever someone pings your server it will add the session id of the user in your database. I will recommend foe you to look into JWT which is also a interesting way to do authentication.

Related

How to prevent concurrent login for a web application using express-session

I am creating a web application which will be used by App's Administrators and for security reasons we don't want to allow multiple active logins from a single user at any point of time.
I am storing session data in the web browser's cookie and want backend to have active user's information who are currently logged in to the application so that on successful login request I can find out if this particular user already has an active session. If that is possible then I can block the login for that user.
One way to do that is storing IsLoggedIn in the Database with LastLoginTime and on each login, I can use this two flags to identify if an active session exists.
Open to other better solutions if any
I think a more robust solution than checking last login times would be to generate and store an id for each new login and then include a middleware to make sure the session's id for each user matches what you expect. That way every time the user logs in on another device the previous one will be invalidated and only one session will be valid at a time. You may even just be able to use express-session's req.session.id.

How to handle logged in state of user authenticated via 3rd party OAuth1.0a?

I am building a website using Node.JS/Express.JS that will allow a user to log in using a 3rd party provider (Discogs via OAuth1.0a).
I have successfully implemented the authentication process so that a user grants access to their Discogs account and I am returned an Access Token for future API calls. The Access Token does not expire. The user is classed by Discogs as an "authenticated application".
At the moment I am storing the Access Token in a session, which persists even when the user restarts the browser, or my server is restarted, so the user stays logged in. Great.
However, when I log the user out by destroying their session and they repeat the authentication process, the 3rd party provider treats the user as a newly authorised application, leaving the old authorised app behind. How can I get around this? Is it better to not destroy the user's session on log out and instead store the logged in state of the user? Discogs do not provide a method for de-authentication.
Also, there is some config to be set against a user once they are logged in. Should I created a dedicated DB table or equivalent for this, or would storing this in the session suffice? It seems like a dedicated user table may be superfluous as I am relying on the user's session id to identify them.
Generally, you will probably want to save some info about your users permanently on your own servers, so probably in a database.
In your specific case, that database should probably save some kind of unique user ID that you get from Discogs (do not save the access token itself for security reasons), which you can use on subsequent logins to identify which access tokens belong to the same user.
Your flow would probably be something like this:
User logs in via Discogs for the first time, you get an access token, put that in session
You figure out a unique user id somehow, you save that to your DB along with any other user info you might need
You put that ID in the session as well
User logs out, you destroy the session, but keep the info in your DB
User logs in via Discogs again, you get a different access token, put that in session
You figure out the unique user id, which matches the ID in your DB, so you write that ID into your session - now you can treat the user as the same user, just with a different access token
The unique user ID can be anything that is, you guessed it, unique. Might be an actual ID, a username or email address - I'm not familiar with Discogs but I'm sure you can figure something out and how to obtain it.

Is asp.net core session not user specific?

When i was working with classic ASP.NET or even with old web forms the HttpContext.Current.Session was User specific. So when user makes the request he receives the session cookie and then onward that session belongs to that user only. So two different users can have session key with the same name in their respective session.
I am reading the documenation on session in ASP.NET Core and looks like it has the same concept as old asp.net however certains notes in the documentation is confusing.
here it says
Session storage relies on a cookie-based identifier to access data
related to a given browser session (a series of requests from a
particular browser and machine). You can’t necessarily assume that a
session is restricted to a single user, so be careful what kind of
information you store in Session. It is a good place to store
application state that is specific to a particular session but which
doesn’t need to be persisted permanently
also here it says
Session is non-locking, so if two requests both attempt to modify the
contents of session, the last one will win. Further, Session is
implemented as a coherent session, which means that all of the
contents are stored together. This means that if two requests are
modifying different parts of the session (different keys), they may
still impact each other.
so lets say i have User1 logged in and upon some action i set
`Session.SetInt32("key1", 123)`
now User2 logs in from some other machine and upon some action i set
`Session.SetInt32("key1", 999)`
Question 1
Will this overwrite User1's key?
Also note here says
ASP.NET ships with several implementations of IDistributedCache,
including an in-memory option (to be used during development and
testing only)
Question 2
What are the other implementation of IDistributedCache that i can use in production?
For Question 1.
No, one user modifying a session key will not overwrite a different user's key. The session is unique to each visitor/user because of the .AspNetCore.Session cookie that is created.
All of the Session.Set calls get stored per that unique identifier.
#1
Session isn't tied to a user because session is only identified by it's session key, so if someone gets possession of the session key/cookie, he can access it.
Asp.Net Core Identity has its own cookie (if you are using cookie authentication) and Session middle ware use its own cookie too.
Naturally, you can also use Sessions without a user. Take Google.com for example. When you first visit Google, it shows you policies and set a session cookie. All settings you do (i.e. maturity filter), will be saved in the session which gets accessed each time you perform a search.
This all without being logged in, so there is no user at all.
#2
Open Source is your friend:
https://github.com/aspnet/Caching/tree/dev/src
Redis and SqlServer are the default distributed caches, with InMemory being for development / single-node only. There also may be other third party libraries which add support.

How to implement "remember me" using ServiceStack authentication

I am trying to implement a Remember me feature in a ServiceStack-based project. I don't want to use Basic Authentication because it requires storing password in clear text in a browser cookie, so I need to come up with an alternative approach that will be easy to maintain and customized to my existing database.
I understand that ServiceStack's own support for Remember me is based on caching the IAuthSession instance in the server-side cache, which by default is an in-memory data structure that is wiped out when the website restarts (not good). Alternatively, the cache can also be based on Redis or Memcached, which is better (cached data survives website restarts) but adds more moving parts to the picture than I care to add to it.
Instead, I would like to implement the this functionality using my own database:
Table Users:
UserID (auto-incremented identity)
Username
Password
Email
Name
etc...
Table Sessions:
SessionID (auto-incremented identity)
UserID (FK to Users)
StartDateTime
EndDateTime
SessionKey (GUID)
The way I see things working is this:
On login request, AuthService creates an empty instance of my UserAuthSession class (implements IAuthSession) and calls my custom credentials provider's TryAuthenticate method, which authenticates the user against the Users table, populates UserAuthSession with relevant user data and inserts a new record into the Session table.
Then the auth session is cached in the in-memory cache and ServiceStack session cookies (ss-id and ss-pid) are created and sent to the browser.
If the user checks Remember me then additionally my custom credential provider's OnAuthenticate method creates a permanent login cookie that contains the user's username and the auto-generated Sessions.SessionKey. This cookie will help us track the user on subsequent visits even if the auth session is no longer in the cache.
Now, suppose the site has been restarted, the cache is gone, so when our user returns to the site his auth session is nowhere to be found. The current logic in AuthenticateAttribute redirects the user back to the login screen, but instead I want to change the flow so as to to try to identify the user based on my custom login cookie, i.e.:
look up the latest Sessions record for the username extracted from the login cookie
check if its SessionKey matches the key in the login cookie
if they match, then:
read the user's data from the Users table
create my custom auth session instance, fill it with user data and cache it (just like at initial login)
insert a new Sessions record with a new SessionKey value
send back to the browser a new login cookie to be used next time
if the keys don't match then send the user back to the login screen.
Does the above logic make sense?
Has anyone already implemented anything similar using ServiceStack?
If I were to proceed with this approach, what is the best course of action that doesn't involve creating my own custom version of AuthenticateAttribute? I.e. which hooks can I use to build this using the existing ServiceStack code?
This is already built for you! Just use the OrmLiteCacheClient.
In your AppHost.Configure() method, add this:
var dbCacheClient = new OrmLiteCacheClient {
DbFactory = container.Resolve<IDbConnectionFactory>()
};
dbCacheClient.InitSchema();
container.Register<ICacheClient>(dbCacheClient);
I am not sure when this particular feature was added, perhaps it wasn't available when you originally asked. It's available in v4.0.31 at least.

What information to save to a cookie for future account authentication?

So I'm building my first ever website with user accounts. What data should I store to the cookie so the user can prove that they are in fact that user? Right now when the user logs in I save the user ID, the username, a randomly generated session ID and the hashed and salted password for future authentication. I'm not sure if I should be doing the last part...
Before anyone suggests it I would use OpenID but my target audience isn't guaranteed to be tech-savvy and I think it would just confuse them. I don't want interested users going to the competition so I'm keeping things as "regular" as possible. I suppose I could offer both site registration AND OpenID...
You really only need to store the session ID: as long as the session data is kept, any other data can be stored server-side against the session. Keeping personal data in cookies isn't a good idea, since they are stored and transmitted in plaintext.
Have a look into session hijacking if you are worried about people grabbing onto someone else's session using this method... Though, with cookies it's usually a little harder to do (the most common case of this happening is on sites that pass the session ID around as part of the GET request).