Forum Moderators: coopster

Message Too Old, No Replies

Authentication a server before serving a feed

Remote server authentication.

         

mack

4:16 pm on Aug 8, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



I am working on allowing other sites to install a simple script that will allow them to present a feed on their site.

Producing the feed was easy as was writting the parser in php to supply to sites wishing to use the feed. What I want to do is reqire sites to register before they are allowed to view.

The script that I provide has an install that allows users to customise the feed's apperance. After they have done this they then need to register to be able to use the feed.

This is done on their server using a simple form with the data send to a php script on my server. The php script gathers the following data. name, username, password, and url. The form also sends the ip address of the server that script is installed on as a hidden field. The Ip address is then stored. All data is stored in mysql in a table called "sites".

The field "user" is then also saved on the users server in a text file.

When ever the users server makes a request for the the feed their username is also appended.

The feed is dynamic and is actualy produced by a php script parsed as .rss Here is a copy of the code I use to produce the feed.


<? header('Content-type: text/xml');?>
<?
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
?>
<MY_FEED>
<title>My feed title</title>
<description>Description of my feed</description>
<link>http://www.example.com</link>
<copyright>My copyright</copyright>
<?php
$u = urlencode ($q);
include "http://www.example.com/rss.php?q=something" ;?>
</MY_FEED>

The above code works great and produces a valid rss feed.

The code calls a php script that has been modified to produce an output that resembled rss format.

What I want to do is only display the feed to sites that have registered. What I want to do is have this script file verify the server before issuing the rss feed. I already have the users details stored in the "sites" table. What I want to do is add a mysql select so validate the server.

I can get the ip address of the server using..
$refip = $_SERVER['SERVER_ADDR'];

The username will also be send along with the query.

example.com/rss.php?q=test?user=mack

I how have the refering ip address (server) and a username. The code I had in mind was something like the following..


<? header('Content-type: text/xml');?>
<?
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
?>
<UKWIZZ_SEARCH>
<title>My feed title</title>
<description>My feed description</description>
<link>http://www.example.com.com</link>
<copyright>my copyright</copyright>
<?php
$refip = $_SERVER['SERVER_ADDR'];
$user = "$user";
$link = mysql_connect(localhost,dbuser,password) or die("Unable to connect to server");
$db_selected = mysql_select_db(dbname, $link) or die("Unable to connect to database");
$num_result = mysql_query("select count(*) FROM sites where ip = '$refip' and user = $user") or exit(mysql_error());
if (!$num_result)
{
include "http://www.example.com/fail.rss" ;?>
end;
}
$u = urlencode ($q);
include "http://www.example.com/rss.php?q=$u" ;?>
</MY_FEED>

Does this seam like a logical way of doing this. The simple fact is it doesnt work. It belive the problem is with my mysql select.

Mack.

coopster

5:54 pm on Aug 8, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



It may be the SELECT, if the user column is string it should be wrapped in quotation marks, just like you did with the ip column.

Another possible issue is that the result returned from a mysql query is a result resource and only returns false when the query is syntactically invalid or if there was some other issue such as a permissions problem. You will want to use mysql_num_rows() to find out how many rows were returned for a SELECT statement or mysql_affected_rows() to find out how many rows were affected by a DELETE, INSERT, REPLACE, or UPDATE statement.

mack

7:29 pm on Aug 8, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



trying to make the request determine if there is a row. Mysql_select_rowns probable the way to go. Another idea I had was.


$result = mysql_query("SELECT count(*) FROM sites where ip = $refip and user=$user", $link);
if ($result == 0)
{
$request='http://www.example.com/fail.php';
}else{
$u = urlencode ($q);
$request='http://www.example.com/feed.php?q=$u';
}
include "$request";?>

Mack.

dmorison

7:50 pm on Aug 8, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



SELECT COUNT(*) FROM ... will always return 1 row with 1 column containing the value of COUNT(*).

Regardless of whether or not the answer is zero, mysql_query() simply returns a resource ID to the result - it is not something you can test to find out the answer to your COUNT(*) query - you have to go on to get the row from the database library using mysql_fetch_array() or similar function.

In addition, I would always recommend using the SQL syntax SELECT COUNT(*) AS name to avoid the ambiquity amongst various SQL library implementations as to what the COUNT(*) column returned may actually be called.

This would lead to some code something like:

$result = mysql_query("SELECT count(*) as total FROM sites where ip = $refip and user=$user", $link);

$row = mysql_fetch_array($result);

if ($row["total"])
{
$u = urlencode ($q);
$request='http://www.example.com/feed.php?q=$u';
}
else
{
$request='http://www.example.com/fail.php';
}

include "$request";

mack

7:21 am on Aug 9, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Thanks guys, great help... I an now able to echo pas or fail. I have however hit a problem that I never though of.

When a user registers, their server ip address is send in a hidden field. It is then stored in mysql with their username.

When the script issues a request the username will be appended to the query. I then assumed that $refip = $_SERVER['REMOTE_ADDR']; would get me the ip of the refering server. I know this works for getting the ip address of a computer browsing a page. I just assumed it would also work for a server making an include request.

If there any way this info can be got?

The Ip address is vital to my authentication method. The ip address and username need to match the row.

Thanks again.

Mack.

dmorison

7:48 am on Aug 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Do you not have the issue here that the remote IP address from which a user who wants to use your feed registers from is not likely to be the IP address of their server from which the feed is requested? For example, they're registering from home using thier ISP account, but the actual connection comes from their dedicated server located at some hosting company.

For your mechanism to work, it would seem that the registration needs to come from the server that will be making the actual request, but it looks like that is not the case.

I operate a system very similar to what you're trying to achive here, and $_SERVER["REMOTE_ADDR"] works fine for scripted requests from other servers, not just human users on the end of a browser.

In my implementation, a user register for an account and by default have access to the service from any IP address; however since each request costs them money; they have an access control list (ACL) through which they can enter the IP address of any server from which they wish to make requests. If this list is populated, the server compares $_SERVER["REMOTE_ADDR"] against the ACL before servicing the request.

Hope this helps...

mack

8:40 pm on Aug 9, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Hi again thanks for the comments :)

It is the ip of the hosting server that I need to get.

On installation of the script the user/operator is required to fill out a form. The ip address of the server and a username choose by the user is send to a script on my server. My server then stores the data in mysql.

Then when the script makes a request from a remote server the username will be appended to the query. This is where it gets tricky.

I already have a mysql row with a username and ip address. their script will send a username with the query. A script on my server will then determine what ip address they should be coming from (their server address) I then need a method to get a true refering server ip.

If the ip they provide matches they ip I have in mysql then they are good to view the feed.

sorry if I explained it poorly.

Mack.

dmorison

7:02 am on Aug 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You should have no problem with $_SERVER["REMOTE_ADDR"]. It sounds like the tricky part is getting the correct IP address at the time of registration. Is the user actually entering the IP address of their server into a form?

mack

2:36 pm on Aug 10, 2005 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The form works in the same way as the verification part. It detects the ferering ip and stores it in a variable.. then writes it to db.

So far I have been able to test it and the data is written well.

user: mack
password: mypass
url: www.example.com
ip: #*$!.xxx.xxx

in the form the refering ip works ok because the user was refered from another page on the users server. (another page in the script)

When I install the script on another server and run the install and registration i can view the data in phpmyadmin or webmin and read the data it sent. The data looks good.

I just can seam to repeat this when reading the refering ip in the verification part of the script.

Mack.