Control (signature) number for data - php

I have a question, some might have encountered while working with data. Trying to figure out how to implement "signature" for data passed back and forth to SQL Server via PHP.
For example, I have a sales order that contains dates, numbers, other variables (string), etc.
The idea is that when that data is inserted into SQL, a "signature" is created based on all the variables (around 30-40) and stored in that table. That signature will be sent to the user when user pulls the data. Then, when a user updates that data and sends back to SQL along with the current signature, PHP would compare that current data signature with the one stored in the database and update the data if it matches. if not - the user will get a notification saying something like "the state of the order has been changed, new data available".
This will prevent one user from overwriting the data if that data has been changed by another user while the first user worked on it.
I thought to add "user signature" which is comparatively easy. However it does not resolve the situation when the same user has opened multiple windows with that data and then accidentally tries to submit updates from one window after he already submitted some data from another window. (Some users are old folks and not tech savvy and may have open multiple windows in the browser, you know).
Locking records won't work here as the data has to be accessible by multiple users at any time.
Thank you for your help!
NOTE: If someone is using SQL Server Management Studio, seems like you can add this column only via query. At least I coud not find this option in "design" view.
ALTER TABLE table_name ADD Version rowversion;

Related

Real time data with Angular

i want to create a web page with data, this data can be edited in Real Time.
Users will see data in Real Time and can edit it, something like "Google Sheets" where everyone can edit the same file and see others changes in real time.
I will be using PHP, MYSQL, AngularJS.
I want to consult you on how to do it in the best way, this is some points that i thought of:
Use angular polling every X seconds to update page data in real time, but if user editing one of the fields, how can i prevent from this specific field to be updated by polling?
How can i LOCK specific field that user is editing, to prevent 2 users to edit the same field in real time
There is any better way to pull data in real time than angular polling?
When user editing text field i want to update it in database without "submit" or save button, i thought to save the data after 3 seconds, any better ideas?
Thank you,
1:
I'd suggest for you to have an array of objects or a datastructure similar to that, which contains the fields, in your AngularJS controller. When a user starts editing a certain field, you could set isEditing to true in the field object in your datastructure. Whenever an update comes in, you loop through your datastructure and only update fields of which isEditing isn't set / isn't true.
For making it more realtime, instead of polling, setup WebSockets and let the server broadcast the newest values of a field to all editors whenever it gets changed.
2:
For locking a field that a certain user is working on, you could add a locked column to the database table containing the fields. Whenever a user wants to start editing, the following would occur:
User requests to edit a field
Server checks if the field is locked
If the field isn't locked, the user is permitted to edit the field and the server sets the locked column to true or to the username, depending on your needs.
If the field is locked, the user isn't permitted to edit the field
When a user saves a field after editing it, you should set the locked column to false. You should probably also set the locked column to false whenever the editing user gets disconnected.
3:
PHP on it's own is not able to send data to the client without the client making a request. You'd need to add WebSocket support to PHP (for example http://socketo.me/, haven't tried that out though).
If you are interested in a server platform that is able to do this out of the box, you could take a look at http://nodejs.org. When you plan on using Node.js, I suggest using http://socket.io/ for maximum browser compatibility. (it includes fallbacks for whenever WebSockets aren't supported by the users browser)
4:
You could save the current value every x seconds if the value is different from the previous save. This would be more efficient than always saving the value. You'd need to save the previously saved value in a variable for this.

How to avoid some SQL queries in PHP?

I am developing a PHP web app with jQuery and Twitter Bootstrap. And it uses AJAX for everything. So, I show a form in HTML5, the user press a button (class="btn"), the form is sent to PHP (jQuery, AJAX), PHP makes a query to the MySQL and echoes an answer, which is shown in the form (jQuery). This is basically how the web app works.
But here's the deal, the first form it is showed, it's a div that shows some news. For example:
A new user was created.
There is new important date.
Someone wants to text you.
So I've created a table in MySQL called News where I saved some values than mean something like:
1: A new user was created
...
Everytime the user log in will se that. It means that there will be a query and a response as soon as the HTML5 get loaded when a user log in.
The index.html file has a navbar (Bootstrap), and a option call News. When the user clicks it, the same query will be executed, but not necessarily the same response.
I thought in modifying the div with news whenever the user does an action. But, an action can also be done by another user. So it is necessary to make the query again!
Is there any solution that allows me to avoid querying the database when the user wants to get the news? Or how can I know that it is necessary to update the div right now? I was taking a look at caching queries but didn't arrive to a conclution.
Sorry if my english is not too good, it is not my native language.
Thank you.
You can send a timestamp in every news response from the server and save it in javascript. The next time you make a request, send the timestamp you saved and the server checks if there are more recent news, sending nothing if there is none as the last response is still the newest.
Well, there is a downside here, you still need to make a query to the database (filtring the results with a WHERE clause like 'WHERE ... TIMESTAMP > last_timestamp_from_browser') which is perfectly valid, SGBDs are designed for this, and if you don't have thousands of users accessing your website at the same time there will not be any problem. With this approach you will only save bandwitdh as the connection to the database is still made.
There is another way that prevents this connection from being made, cache some values of last news inserted which could be user specific or global and save them in APC module (or memcached). You'll need to discover what to cache and when (you can't cache the entire database, just some well organized timestamps and maybe the most requested news for example). This way you prevent the database connection from being made. This will force you to do many many more code, so, use it only if you really need it, like thousands of user connections at once.

Should I delete MySQL entries using a PHP script which users can run?

I'm currently working on a website which will have many users on it. These users are stored in a table with each having a unique id. The website will contain projects that the users can complete and these projects are stored in a separate table with unique id's as well.
I need to make the users have a page they can view which will display a list of all the projects they are currently working on.
To do this, I am going to set up another table in which each row will have the user's id as well as the project's id that they are working on. All of that will work alright but I would like to allow users to cancel their projects if they please. I am aware of how to do this, but I have read that deleting rows directly from a php script is insecure so the user used to access the database from PHP does not have 'DELETE' permissions. I am wondering if I should just delete rows at will when a user specifies which project to delete or if I should just have another field and simply mark each user-project row as being 'cancelled' in another field so I can work with them myself.
What you should do is, for maximum security is, have a parameter in the database table called "isActive", or something of that nature, that is a BIT data type to represent a boolean. If that boolean is false, then do not delete the project from the database, simply hide that tables data (do not display it on the site, but keep the data stored in the databse). That way, not only is your database secure from malicious users who would like to destroy data, but projects can also be "re-instated" if they wish to re-instate it. If the project sits around for a certain period of time, say, 14 days, just have the server delete it, not the user, if you wish. This worked for me in the past.
Hope This Helps!
The most common approach to this problem is to have a field in the table that can be used to mark a record as deleted. This would be the only access the general user would have to the table as far as deletion goes. Some people also have a full delete, which states clearly that it will never be accessible again after the operation is completed.
Personally, I prefer to retain full delete permission to administrators allow the user to only mark records as deleted. If you're concerned about space, add a last accessed field as well, and schedule at set intervals a call to perform a full delete on any records that are marked as deleted and have not been active for a certain amount of time.

How to secure JSON call without using a captcha

So we are building a website and created our basic information to send logins to our database. We have trouble trying to disallow requests that just plug their own data in.
E.g.
http://testing.site.com/php/interfaces/User.php?Action=1&Email=test#gmail.com&FirstName=herp%20derp
By replacing email and firstname, they are able to add multiple users to the database and potentially with a script thousands. Is there any way to prevent this without using a captcha? We are trying to be very minimal and open with the site's design so would love some input if this is possible.
One option we have considered is moving our PHP offline and only allowing our API to access it- however it still presents the problem of users adding in authorised data (and overloading our database with thousands of multiple requests)
Here is a sample option, create a table with 2 fields, one is an Auto Increment id and one is a random code, lets name them ID and CODE
When sending that request, create 1 record in that table and pass the ID and CODE along with request, when receiving the request, check if there is a record in database with that ID and CODE process the request and delete that record from database too and if there isn't that record, just ignore request ...

PHP, MySQL: How to retain and retrieve correct data when dealing with pagination

I have a form (that consists of 25+ fields) and the values for these fields, range from a tiny value to a concatenated string. This is like a search tool. Now when the user fills the form and submits the info, he gets to see all the relevant data that matches the criteria in the form. I am displaying 15 records at a time to the user. I have implemented pagination to enable user to see the other records as well.
THE MAIN PROBLEM:
The part, till the users submits the info and gets back the 1st set of data is good. The problem arises when user tries to go to 2nd page (or any page of his choice) via pagination. The user is able to navigate to the other pages but the query that is needed to execute properly for pulling out the results from the DB is not triggered. Notice that initally it was a POST operation that was performed in the form and the pagination performs a GET operation. So I am losing the values of the form that the user has input and I want to retain these values and query the DB with these values.
I am trying to avoid sending the form field values via GET because I fear that the data may exceed the maximum permissible value in the URL (& as it is less secure than a POST operation). There are other operations that can be performed on the results page that can lead to loss of the form values if I try to use a POST operation (like update query). Sessions would not really work as the user can choose to run the same form in different tabs with different inputs to compare the results and this can lead to the data of the older query replaced by the data from the newer query. I haven't thought of cookies as the user may have chosen to block it. Pretty much all the options seem to be exhausted.
So what can I do to retain the form values, run the proper query and get back the relevant values irrespective of the number of times the same form may be processed by the same user in different browser tabs/windows, without using sessions(given the restrictions on passing data via GET and possibly losing them in POST operations) and be able to perform other activities on the page as well?
Thank you in advance.
First off, GET is no "less" secure than POST. Both are not to be trusted at all (It's more inviting to modify a url string, but by no means harder)...
You have a few options:
One, would be to keep a global "store" of search results. You can use a db table with id, data where data is a serialized array of the variables. Then when someone submits a search, check to see if the data is in the table. If so, use that id. If not, then serialize the data and insert it (and get the id). Then redirect to a page like: results.php?id=4. That way, they can share the link yet it stays reasonably secure from tampering (they can't alter the search params). The downside here, is that the table could grow HUGE.
Another would be to base64 encode the data and pass that through as a get parameter (base64_encode(serialize($data));). I would try to stay away from this if you're concerned with tampering or url length.
Another solution would be to intercept the next link click in JS, and use it to issue a POST back to your server from hidden variables.
EDIT: Removed the session solution. Realized that it wouldn't work for your problem.
I am trying to avoid sending the form
field values via GET because I fear
that the data may exceed the maximum
permissible value in the URL
Then you're going to have to do your pagination with a form as well, so they can also POST. Either that, or you'll have to store query terms on the server side somewhere, possibly in a session -- but don't forget that a user might have multiple tabs open at once, so you need to be able to store more than query per user.
But there's no reason you can't store multiple queries in a single session, e.g. $_SESSION['queries'][1234]. Then your pagination links would look like ?query=1234&page=3
Consider, however, that it may be useful for users to be able to share URLs of their search results. e.g., if google used POST exclusively, I couldn't send you a link to http://google.com/search?q=somequery
(& as it is less secure than a POST operation)
Not really.
A possible approach would be to store the whole query you used for searching in your database in a table say called search_queries. That table should contain essentially two columns, a hash and the query used for that search item.
When a user submits a search form, his query is evaluated and inserted in that table and he is redirected to a page with his search_hash. Every time he navigates to a different page his hash is pulled from the database and results re-evaluated accordingly -- with the proper LIMIT of course.
Make sure you cron that table (for that you might need a timestamp for each search item)
Another viable implementation of this approach would be to store the query in a SESSION variable and use it for your querying purpose. For pagination, you would /search?page=1 and your _SESSION['query'] would be for example "SELECT * FROM Topics WHERE title LIKE '%test%'". You would essentially add "LIMIT "+($page*$perpage)+", $perpage"
However the latter approach would not be able to detect multi-windows this user has with the site. You could use an array in your _SESSION['queries'] and have the user submit a /search?id=0&page=1 where id would represent which query of the array you're querying in that window.

Categories