I'm writing an hour registration system for my projectteam at school. Everything is pretty much working, but I can't seem to get the validation of user rights to work.
Validation is done in the acctype field within the user table. If 0 (guest), you can only view the list of hours, if 1 (specialist) you can add your own hours and if 2 (project-manager), you can review the hours users have submitted.
At first I was only using the $account query but instead of selecting them all I selected acctype only.
Does anyone have any idea what am I doing wrong?
$cookie = $_COOKIE['user'];
$account = mysqli_query($conn, "SELECT * FROM user WHERE user = '" . $cookie . "'");
$acctype = mysqli_fetch_assoc($account->acctype);
if(isset($cookie) && $acctype >= 1) {
} else {
}
Jonathan
I believe there's a few things wrong here:
You're reading the cookie before checking if it's set. That's a mistake. You should see if there's a cookie, and THEN read it in. You also don't need to assign it a separate variable.
Note: As I said in my comment, user data should be in a session, not a cookie.
I don't know what your DB schema looks like, but your query is SELECT * FROM user, meaning that if you have an ID, a user name, an access level, and some other things, you're going to get ALL that into the var $acctype, which obviously isn't an integer.
I think the fix is to execute your query, get your results, and then compare the row(s) returned and only check the acctype part:
if ($row['acctype'] >= 1){
}
Documentation: http://us1.php.net/mysqli_fetch_assoc
Related
I have the following PHP code:
<php>
$servername = "host";
$username = "username";
$password = "password";
$dbname = "db";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT steamid, bananas FROM es_player";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "PLAYER'S STEAM ID: " . $row["steamid"]. " - PLAYER'S BANANAS: "
.$row["bananas"]. " <br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
It just fetches specific fields from my database. When user's login, they use OpenID, and it is not through an actual database under my control. It is through Steam, users login with their Steam account through OpenID. I am able to fetch the user's SteamID with this when they log in, and there is even a variable for it.
I need to use this SteamID variable when they are logged in to specify which row they are on the database, and print ONLY the logged in user's profile fields, rather than just printing all rows in the database. This will be done using the SteamID of the user that logs in which will be compared against the SteamID field on my database, so that it will know which user you are when you log in.
I do not know how to accomplish this, which is why I am posting here. I just need the PHP code, or some help writing it.
You have several related problems that need more research. Since I've voted to close the question as too broad, I will mark this answer as Community Wiki. I really want to help, but in common with the values of the community here, I would encourage you to take the following points and to use them as avenues for further search-engine research. Your post for "just [needing] the PHP code" is a request for free work, which we try to discourage here.
I think I understand the problem, but I have no experience of the Steam API, so you may need to read their docs and adapt the following. If you have not used APIs or sessions before, hiring a freelancer in your locality may be the quickest and easiest route to getting your project on the road. You may only need a few hours of their time, so it need not be expensive.
Your OpenID script should deliver to your application one of the profile IDs you've described. When a user first creates an account in your site, you need to capture that profile ID and store it against other information of interest. At this point you should run the conversion routine, so that you have the other profile ID, and you can then store that too.
When the user logs on, you need to create a session. This is usually as simple as using session_start() and then saving the user record primary key as a variable, thus:
$_SESSION['user_id'] = $userId;
The user ID will come from your login screen, where you get an OpenID callback to prove that the current user does indeed own the Steam profile ID they have supplied to you. Having a session set up means that any subsequent page browsed by the user will have their user ID available, until they log off. This means that you don't need to do an OpenID call on every page.
Using this session ID, you can now obtain either of profile IDs you require, since they are both in your database. This is a trivial SELECT database operation involving the session ID, which you can read from $_SESSION['user_id].
Here is an example of a table in an OAuth application I wrote (it's open source, so you can pull it apart if you like). When the user logs on, this record is either created (if it does not exist) or updated (if it does exist):
mysql> SELECT * FROM user_auth;
+----+---------+---------------------------+----------+---------------------+
| id | user_id | username | provider | last_login_at |
+----+---------+---------------------------+----------+---------------------+
| 1 | 1 | https://github.com/halfer | github | 2015-01-13 18:05:49 |
+----+---------+---------------------------+----------+---------------------+
1 row in set (0.00 sec)
The username is the OpenID identifier, the provider is useful if you allow the user to choose from several authorisation systems (Steam being another), and of course the last_login_at is self-explanatory.
I also advised in the comments that you may have to write this code. Library re-use is a commendable habit to get into, but unfortunately there is not a library for every eventuality - sometimes the programmer just has to write something him or herself. We frequently see requests on Stack Overflow for a "library/tutorial/step-by-step guide for [project X]" here, and if readers can persuade posters that programming isn't really like that, they will have passed on a very useful lesson.
So, try the above in order? Feel free to ask for further help if I have misunderstood some basic part of the structure, but otherwise, please do use the keywords I've mentioned and pop them in a search engine. It's the only way to learn. Good luck!
It was actually quite simple. First, I took the SteamID 64 variable $steamid and ran it through this conversion, which will output the SteamID 32
$id = $steamid;
function parseInt($string) {
if(preg_match('/(\d+)/', $string, $array)) {
return $array[1];
} else {
return 0;
}}
$steamY = parseInt($id);
$steamY = $steamY - 76561197960265728;
$steamX = 0;
if ($steamY%2 == 1){
$steamX = 1;
} else {
$steamX = 0;
}
$steamY = (($steamY - $steamX) / 2);
And then to finish it off, I just made a variable that combined it into the full STEAM_0:000000000 combination.
$steamID = "STEAM_0:" . (string)$steamX . ":" . (string)$steamY;
I can now use $steamID as a variable on any page that I include this code on. I answered this myself so that if anybody else has troubles with this like I originally did, the answer will be here for them :)
I have a database running and I'm currently printing out in a website, in a "php block" the usernames of the database. I achieved it with this
if ($db_handle) {
print "Database ISSSSS Found ";
$SQL = "SELECT * FROM `database.com`.`users`";
$result = mysql_query($SQL);
//print $result;
while ( $db_field = mysql_fetch_assoc($result) ) {
print $db_field['username'] . "<BR>";
}
mysql_close($db_handle);
}
However this gives me a giant string of all the users (I currently have 4). How do I make it so its just the individual user accessing their profile through the website
Typically, when someone logs in, you would store non sensitive information about the user in the session. This way, you can get to it quickly without needing to make database calls on every page. For instance, if you wanted to show their username in the pages header, you would always have their username handy to do so. Then, when they go to view their profile, you can use that username you stored as part of your SQL WHERE clause to pull in information pertaining only to that specific user.
Use WHERE username = 'yourusername' in your SQL query.
That shall fix your problem
I know the title sounds like something that has already been posted But I promise I have taken the time to do my research and have found nothing for my problem.
I am not new to mysql I know how to grab info from the database and check it, but the way I want to check it is my issue. I have a subscription system that I have been building everything is working fine even the checking -- at first. what Is happening is I have made 2 test accounts when one of the test accounts subscribes to the other is is perfectly fine my script says that that user is subscribed to the user, and my database results support it. But when the other user subscribes back, the script that checks does not return correctly. I'm not sure if it is the way that my script is checking or if it's the fault in my logic and the way my database is setup.
I have a table called 'subs' with 5 columns
id, user, subed, accepted, date
the way I am checking if the user has subscribed to the other is by finding the row where user is the same as the user who is subscribing, and subscription is the same as the user who is being subscribed to. at the moment the 'accepted' row is not being checked because that is an option in the settings which has not been created yet.
I'm sure it will turn out to be an obvious answer that will make me feel and look really stupid, or something I have overlooked, thanks for taking the time to help, here is the function that seems to be messing up.
function subcheck($user, $sub){
$user = strtolower($user);
$sub = strtolower($sub);
//connect to the database
$dbh = new PDO('mysql:host=localhost;dbname=postreme', '****', '****');
$dbh->exec("SET CHARACTER SET utf8");
$check = $dbh->prepare("SELECT user FROM subs WHERE subed=:subed AND user=:user");
$check->bindParam(':subed', $sub);
$check->bindParam(':user', $user);
$check->execute();
$checks = $check->fetchColumn();
$checks = strtolower($checks);
if(!empty($checks)){
return true;
} else {
return false;
}
}
Query for return 1 if record exist and 0 if not exist:
select case when (select 1 FROM subs WHERE subed=:subed AND user=:user) is null then 0 else 1 end;
Here's a situation, i have a list of support tickets that when you click the title of the ticket takes you to a page that displays the ticket in more detail. If uses URL GET variables to query the database. I've taken SQL injection into account but what if someone modifies the url to an id that doesn't exist? whats the best way to deal with that?
Thanks,
Jonesy
If the ID does not exist, send a 404 - Not Found header along with a nice error page telling the user that it wasn't found.
You probably have to make a page handling unsuccessful searches anyway; just route it in there. Then you can help the user to find what (s)he searches in a consistent way, provide cues and "most-searched-after" and what not.
This may seem too simple, but you should always validate your GET (or POST) variable before doing anything with them. In your case, just verify that the ID exists in the database. If it doesn't, inform the user.
You should always check if your query returned anything. If it returned 0 rows, the ID doesn't exist.
<?php
$result = mysql_db_query("your query", $link);
$num_rows = mysql_num_rows($result);
if($num_rows < 1) {
// row with that id doesnt exist
// do whatever you want
} elseif($num_rows > 1) {
// you have problem with your ids in db
} else {
// everything went fine
// do your thing here
}
?>
Check if the ticket exists; if not, react accordingly. What "react accordingly" means is determined by your business logic: create a new ticket? raise an error? take the user to a list of available tickets?
An example using the old mysql extension for brevity:
$sanitized_numeric_id = (int) $_GET['ticket_id']; // assuming id is numeric
$query_resource = mysql_query('SELECT `somecolumn`, `column2`, `othercolumn`
FROM `tickets`
WHERE `id`= ' . $sanitized_numeric_id);
if (mysql_num_rows($query_resource) > 0) {
// the ticket exists, do something with it
} else {
// the ticket doesn't exist, react accordingly
}
Below is a page that handles a login script and I am wondering if I have put it any security holes. I have been reading articles on protecting from injections and others and wanted to make sure that my code is secure.
It is submitted via ajax and returns JSON based on the login being correct or not.
<?php
ob_start();
session_start();
include ("config.inc.php");
include ("jsonEncode.php");
// ausername and apassword sent from form
$ausername = '';
$apassword = '';
$ausername = mysql_real_escape_string(stripslashes($_GET['username']));
$apassword = mysql_real_escape_string(stripslashes($_GET['password']));
$sql = "SELECT * FROM admin WHERE ausername='$ausername' AND apassword='$apassword' LIMIT 1";
$result = mysql_query($sql) or die(mysql_error());
$data = mysql_fetch_array($result);
$count = mysql_num_rows($result);
if($count==1){
$_SESSION['ausername'] = $ausername;
$_SESSION['apassword'] = $apassword;
$_SESSION['admin_id'] = $data['a_id'];
$a_id = $data['a_id'];
$_SESSION['LastLogin'] = $data['last_login'];
$query = "UPDATE admin SET last_login = Now() WHERE `a_id`= $a_id";
mysql_query($query);
//echo $query;
$_SESSION['aloggedin'] = "1234";
// valid
$var = array('avalid' => 1, 'ausername' => $ausername, 'apassword' => $apassword);
print php_json_encode($var);
}else{
// invalid
$var = array('avalid' => 0, 'ausername' => $ausername, 'apassword' => $apassword);
print php_json_encode($var);
}
?>
You might want to use the POST method rather than GET with the login form, otherwise their password will appear in the URL and URLs aren't very secure (they might get bookmarked or sent to another server as a referral URL, for example).
You don't need to strip the slashes. Unless you are also stripping slashes when these columns are populated, you've actually introduced a security hole -- if for whatever reason you don't have a unique constraint on the username field, and/or you have slashes in the in the stored username or password fields, and their passwords differed only by a slash, you could get one user logged in as another.
You should be using bound parameters to put user data into your SQL, not string concatenation.
Also, you should probably be storing password hashes in your database - not the original plaintext passwords.
Finally, not a security issue, but setting $ausername and $apassword to '' immediately before giving them new values is entirely pointless.
Also, don't store the password in the session. Php session data is stored in the OS tmp/temp directory by default so the data could be viewed by others. Normally, I'll just keep the username in the session and query the database when needed. That avoids problems when a user's information is changed, but the session isn't updated.
(I'm an MSSQL bod, so don't know if any of these points are irrelevant to MySQL)
This isn't really to do with security, just general observations in case helpful:
Don't use SELECT * - list the columns you want back - looks like you only need a_id & last_login. You might add a Blob in that table with their photograph in the future, or personal notes etc. - it will kill performance in all the places where you did SELECT * in the past and didn't need the picture.
I wouldn't do LIMIT 1 - I'd quite like to know if there are DUPs at this point, and raise an error.
I would put the last_login column in another table linked 1:1 with your User / password table. Its a frequent-change item, and if you decide to introduce an Audit table on the user/Password table (i.e. store the old values whenever it changes) having a frequently changing "info" column mucks that up a bit.
Personally I would want to keep the column naming convention and the SESSION / variable one the same.
admin_id / a_id, LastLogin / last_login
Personally I wouldn't store password in the session unless you need it later on. I would store something to indicate the "permissions" the user has, and then use that to decide if they can view PageX or PageY etc.
All good answers above.
Only one thing I want to add that hasn't been mentioned... I tend to fetch the account password and do a PHP comparison rather than putting the password in the query and looking if the row exists.