Laravel sanctum limit no of tokens for each user? - laravel

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.

Related

Laravel: calculated field used in a query

I am working on a function that allows a user to check if their existing device contacts are using our platform, based on phone numbers.
For privacy and security, we are hashing the user's contact's phone numbers on device (salted with the user's id) before sending to our server.
Server side, we then need to hash our entire contacts table (using the user's id as a salt), which is currently being done in a for loop.
We then check this list against the request list, and return the details for any matches.
However, I'm sure there is a more efficient way of doing this, something like computing the hash in a calculated field then including the $request->hashes in a "whereIn" clause.
Could someone give me a pointer on the best approach to be taking here?
The question is, what privacy and security are you achieving by sending hashed value of contact number?
You are hasing the contact in client side(device), that means you are using a key and salt that is available in clinet side already. How can that be a security feature?
If you want to search hashed value in database then it's better to save hashed contract number in a column in the first place. So you can directly run where query in database table.
Ideally, if you really concern about user's contact number you should:
Encrypt the user's contacts in backend/databse not in frontend.
If you need to query for a field in database then you should make a hash valued column that can be matched easily. I mean searchable fields should be hashed so you can run direct query.
Nothing to worry about user's contact security in frontend if you are already passing it trhough Secure HTTP(HTTPS).
Even it a common practice in the industry, to pass a submitted plain password via HTTPS when a user submit it in frontend. It shouln't be a concern of privacy or security.

Is there any way that hasura decodes the token and can use its content in a query?

I was wondering if there is any way to do this in hasura without resorting to creating another service.
Let me explain, in an api a user sends his token, this is decoded in the backend and and so we know who the user is, this is useful for example to search and return records in the database that only belong to this user.
Is there any way to do that with Hasura? the only return the records that belong to a certain user using its token?.
Token data is available as session data so you can use hasura column presets to insert the user id and add permission to only fetch rows that have user id equal to user id from session https://hasura.io/docs/latest/graphql/core/databases/postgres/schema/default-values/column-presets.html#column-presets

CRUD operations validation

Supposed I have a database with 3 tables:
Customers
Orders
CustomerOrders
I build a WebAPI with standard auth using bearer token and I have a middleware to receive all necessary claims from the token, and I have a controller for basic CRUD operations for Orders.
for example:
DELETE - Orders/{id}
PUT - Orders/{id}
How can I make sure that the order that the user is trying to manipulate belongs to the current user?
Do I first need to query the database to make sure that the OrderId belongs to the current UserId before each operation? or is there an easier way to do it?
You can somehow manage to have the information if the user the token was issued for granted the client application to manipulate orders in general dependending on the options of your identity management and token provider.
But to make sure that this specific order belongs to the current user can only be checked in your backend and this needs of course to be done with every operation. The order id could be brute-forced (guessed) and manipulated in the request so therefore you need check this on each request.
I suggest though to extract this checking logic - does the passed order id belong to the user id provided in the token - to some service method to make it reusable from different places. In your case, for instance reuse it for the different CRUD methods such as DELETE and PUT.

Best Practices For Creating A Login Flow?

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.

How to implement cookie, user -tracking in grails?

I'm working on a affiliate system in grails where users can create individual links and guests who are visiting this links get an cookie with an unique session id. If some of the guests come a few days later to my webApp again i want to know that they've been here already and wich user brought this guest to my website in the past.
How would you implement this in grails? I would say with filters. But how should i implement such a filter? Using the grails default session id wouldn't be good, because it gets invalidated and i can't upgrade the grails session lifetime as much because of the servers memory (RAM). Or is the sessionId always there and gets only refreshed, so the session lifetime in grails could be 1 hour and i'm able to track everything longer than an hour too?
Or should i set a new cookie with a unique session id especially for my purpose?
You probably need at least one filter and one cookie.
When the visitor comes to your site for the first time, I'm imagining that you define the affiliate ID as a request parameter. You probably need to create a before filter to see if the visitor already has a cookie set.
If you're just trying to associate sales with an affiliate then you don't need a unique visitor ID, just the affiliate ID that referred the visitor. Inside your filter, if the affiliate ID request parameter is present but there is no cookie, you can set the cookie. Then, when you are processing a sale, you can check if the affiliate cookie exists.
If you are trying to get more advanced metrics then you probably will need two filters (or one filter that does 2 things). One to set the cookie, and one to track the visit. Once you know the things you want to track, you can also put flag's in the user's session to keep your metrics accurate (i.e. if you don't consider each request a visit you may want to put a flag in the user's session after you increment the number of visits for the visitor.)

Resources