Best Practices For Creating A Login Flow? - session

What is the best way to securely login in a user and keep the user signed in with cookies and sessions?
For example:
Check if password and email are valid for a specific user
Set a cookie with arbitrary string
Create a session with the same arbitrary string
Validate each request by the user by making sure the arbitrary strings of the cookie and session are the same

What is the best way to securly login in a user and keep the user signed in with cookies and sessions?
Using an established library.

It depends on how you define "create a session". For our purposes here let's define this as "create a server-side data store with an id and set a cookie with that id"; i.e. what the default session_start() does. Then:
Ensure the connection is HTTPS.
Check login credentials.
If valid, create a session (see above) with a large, (pseudo-)random id and an expiration time as short as possible but as long as necessary. Security here comes from the fact that it's infeasible to guess suitably random session ids, so the longer they are and the shorter their window of validity is the better.
Store the id of the logged in user in the session.
On each page request, see if the session with the id from the cookie exists; if so, use the user id stored in it to get your logged in user.
Optionally storing and checking the user agent is not a bad idea; you should not check the IP address though, as that may change legitimately.

Apart from storing it in sessions , you can also follow this method for keeping an user logged in , even after he closes the browser ->
1) Create a cookie storing user details and an unique hash
2) Create a sessions table (in a mysql db or any other db of your choice) where the unique hash is stored against the user-id, and the user agent of the browser,and the ip address .
3) Next time when the user logs in check that when the user logs in , is it from the same ip,same user agent .. If not , then delete the database entry , and repeat steps 1 and 2.
Apart from keeping an user logged in , it also gives you better security than just storing in sessions.

Related

Re-Ranking Algorithm for Anonymous Users

I have a website:
10,000 pages, each page represent a category, for example: "Laptops".
On each page I am showing 20 recommended products
99% of the users are anonymous
For each user I have a context (device, user-agent and category)
For each product I have the price and the seller name
I have 2 events: outbound & purchase
I would like to re-rank (re-order, sort) the results for each new anonymous user based on the user context. I would like to re-rank based on performance (outbound & purchase).
Do you have recommendation for Specific algorithm OR tool OR service to do that? I found AWS Personalize very nice but the problem is that all of my users are anonymous so I don't believe it can be effective in my use case.
Amazon Personalize can still be used effectively when most/all users are anonymous. If you track users as visitors using a cookie or local storage, then a visitor's session ID can be considered the userId in Personalize. You will lose the continuity of stitching together the same logical user's activity across multiple sessions but you can still get in-session personalization. This requires calling PutEvents with the visitor's session ID in the sessionId field and excluding the userId field. Then when calling the GetRecommendations or GetPersonalizedRanking APIs, use the visitor's session ID as the userId field. Personalize will consider the event activity for the visitor's session when providing recommendations or reranking items.
If the visitor is a known user or later becomes known (i.e. signs in or creates an account), then pass their user ID in the userId field for PutEvents and GetRecommendations/GetPersonalizedRanking. At the next training, Personalize will associate any prior anonymous events (i.e. those with a sessionId but not a userId) to the user. The key is using a consistent sessionId across the anonymous and known events for the user for the session.

Laravel sanctum limit no of tokens for each user?

I am using laravel sanctum for API authentication for my mobile app.
How can we limit the maximum number of active tokens per user?
Currently, in the personal_access_tokens sanctum generated table, there is no user_id reference. With the current table, imagine if a user logs in and logs out unlimitedly. We will have N number of new tokens created in the table.
Is there a default way of limiting the total number of tokens per user out of the box or this needs to be done on my own?
Is this a good practice to have new rows of tokens added to the DB table on every new login?
There is a reference to user, namely tokenable_type and tokenable_id. Which in this case references App\Models\User and the user ID in the tokenable_id.
Somewhere in your application, you are creating these tokens for that specific user. You have the choice here to issue new tokens for every login session, but you could also demand the user to use an old token. That is up to you and the use case of the application.
However, if you are creating new tokens for every login session, consider revoking old tokens (since they will probably not be used anymore). Check the Sanctum documentation.
Tokens are valid for as long as defined in: config/sanctum.php in the expiration key. Standard, personal access tokens do not expire because the expiration key is set to null.
Answering your questions:
Yes, you can simply get the amount of tokens using $user->tokens()->count(); and do whatever you want to do with it (removing old tokens, or returning an error).
This answer depends on your use case. If tokens are valid forever, why would you create a new one on every login, instead of demanding the token that is still valid? Alternatively, you could create a form for the user to request a new token if they forgot their old one, removing the old token and issuing a new one. This way, all tokens in the DB are valid.

Auth user with a Key

I would like to make an auth page to my website with only a Key field.
Example : I give an Key like 'A5DP7123OAC' to my customer for the login.
And if the code is correct he can access to his panel. Actually I just create a Cookie :
withCookie(cookie()->forever('access', 'true'));
But it's not a good way I think.
Do you have solution to Auth an user only with a Key ?
Thank's
You could pass your key to the session and then check to see if the key the user provides matches the key in the session. If so you can log the user in manually using one of the methods found here: https://laravel.com/docs/5.2/authentication#other-authentication-methods
If you don't want to use the session, you could also create a DB table and store your keys there optionally giving them expirations so that the keys are only valid for a period of time. You could also make it so that keys are only valid for one IP address. Plenty of options.

Why can't I trust a client-generated GUID? Does treating the PK as a composite of client-GUID and a server-GUID solve anything?

I'm building off of a previous discussion I had with Jon Skeet.
The gist of my scenario is as follows:
Client application has the ability to create new 'PlaylistItem' objects which need to be persisted in a database.
Use case requires the PlaylistItem to be created in such a way that the client does not have to wait on a response from the server before displaying the PlaylistItem.
Client generates a UUID for PlaylistItem, shows the PlaylistItem in the client and then issue a save command to the server.
At this point, I understand that it would be bad practice to use the UUID generated by the client as the object's PK in my database. The reason for this is that a malicious user could modify the generated UUID and force PK collisions on my DB.
To mitigate any damages which would be incurred from forcing a PK collision on PlaylistItem, I chose to define the PK as a composite of two IDs - the client-generated UUID and a server-generated GUID. The server-generated GUID is the PlaylistItem's Playlist's ID.
Now, I have been using this solution for a while, but I don't understand why/believe my solution is any better than simply trusting the client ID. If the user is able to force a PK collison with another user's PlaylistItem objects then I think I should assume they could also provide that user's PlaylistId. They could still force collisons.
So... yeah. What's the proper way of doing something like this? Allow the client to create a UUID, server gives a thumbs up/down when successfully saved. If a collision is found, revert the client changes and notify of collison detected?
You can trust a client generated UUID or similar global unique identifier on the server. Just do it sensibly.
Most of your tables/collections will also hold a userId or be able to associate themselves with a userId through a FK.
If you're doing an insert and a malicious user uses an existing key then the insert will fail because the record/document already exists.
If you're doing an update then you should validate that the logged in user owns that record or is authorized (e.g. admin user) to update it. If pure ownership is being enforced (i.e. no admin user scenario) then your where clause in locating the record/document would include both the Id and the userId. Now technically the userId is redundant in the where clause because the Id will uniquely find one record/document. However adding the userId makes sure the record belongs to the user that's doing the update and not the malicious user.
I'm assuming that there's an encrypted token or session of some sort that the server is decrypting to ascertain the userId and that this is not supplied by the client otherwise that's obviously not safe.
A nice solution would be the following: To quote Sam Newman's "Building Microservices":
The calling system would POST a BatchRequest, perhaps passing in a
location where a file can be placed with all the data. The Customer
service would return a HTTP 202 response code, indicating that the
request was accepted, but has not yet been processed. The calling
system could then poll the resource waiting until it retrieves a 201
Created indicating that the request has been fulfilled
So in your case, you could POST to server but immediately get a response like "I will save the PlaylistItem and I promise its Id will be this one". Client (and user) can then continue while the server (maybe not even the API, but some background processor that got a message from the API) takes its time to process, validate and do other, possibly heavy logic until it saves the entity. As previously stated, API can provide a GET endpoint for the status of that request, and the client can poll it and act accordingly in case of an error.

Main list of all the user logged-in in a struts application

In my struts2 application, in the login action I am placing the user and role in the session.
I want to keep track of all the users who logged in so as to do stuff like following :
Avoid multiple login of same user-id.
Check wheather a user is looged in or not ! Or any body with role Admin is logged in or not !
and in some other actions !
How to do it any suggestion!
And also how to maintain the issues like
User close browser without loggin ! etc
Any material with more information of session can also realy help !
You can have a column in you user table called logged_in_time (timestamp type) and update it with the time when user logs in and make it null when user logs out.
Avoid multiple login of same user-id: : check if this columns alreadt has some value or not.
Check whether a user is looged in or not : check if that column is null or not.
User close browser without logging out : A schduler job may be, that runs at fixed interval of time to check the session(using sessionid may be) of the user and update this field accordingly.
Take a look at this discussion for further information. And another one.

Resources