Jump to content

PW API access from remote website


Recommended Posts

Dear All,

If this has been discussed, please let me know the url. Otherwise...

A feature that I have to build into the web app I'm creating is that a new user has to be able to register from an approved third party website, which would collect all the standard user data (for their own use), and then send that data to my remote website app, via an "API", whereupon my web app would return some type of response, probably a double opt in link of some type, sent to the user's email address, as well as a status message to the 3rd party website.

I'm thinking that the best way to go would be to have a special page that parsed the incoming data as if it was post data from a form.

The page would run some routines to parse the basic data, plus look for a 3rd party authentication key, to stop anyone else from using the page except the approved site.

Does that sound like a plan? Is it enough to just have a form action type page that looks for post input from a remote, authenticated site? In other words, I don't have to provide the 3rd party with an "API" -- I just have to say, "Send these xyz fields and key to this url, as post data, and use whatever language or method you want to send it."

For example, I know how to send data like that in Perl, using LWP. (e.g. sending post data to PayPal, which looks for a hash, but I'm thinking that I could just look for a specific list of POST fieldnames.)

Not sure if I'm missing something, but I'd appreciate any input.

Thanks!

Peter

Link to comment
Share on other sites

If you check the ip, then that is pretty good authentication. But since you are creating users, sending email etc you cannot be too careful.

Good and simple solution is to calculate simple hash from posted params and add shared secret in too. So only you and the third party know how to calculate the hash.

Before doing anything on your side you calculate the hash and if it matches (third party sends hash as a post param too) you continue and return success message.

Hash can be something like md5($username . "abc123" . $email).

  • Like 1
Link to comment
Share on other sites

Dear Antti,

Those are good ideas, thanks!

I think my main question is, does PW have something in its code already, or in modules, to deal with incoming data, per above?

Or, in a module? I didn't see anything.

This may just be a PHP question, i.e. how one deals with post data sent as a batch, perhaps in an array, and the specs necessary for the remote programmer.

I've been asked to provide that remote person with an "API" to send data to a PW website, but it seems like I'll have to roll my own from within PW.

Any tips, anybody?

Thank you all very much!

Peter

Link to comment
Share on other sites

Nothing ready. Other way around there would be api module (servicePages if I remember correctly).

It is just the same as any other form. Just define the required stuff, url where to post and possible hash and you are ready to go. Also tell what you are going to return if success or not.

Link to comment
Share on other sites

I've been asked to provide that remote person with an "API" to send data to a PW website, but it seems like I'll have to roll my own from within PW.

The PW API is always the same regardless of context. One of strengths of PW is in it's flexibility when it comes to sending or receiving web service data, and this is one of the things I use it for quite a lot. But you do have to tell it what to do, rather than it telling you what to do. At the simplest level, you could validate against an IP and/or password for authenticating the request. That may or may not be adequate, depending on who/what you are dealing with. In either case, use POST rather than GET. Here is a simple web service that adds a new user (written in the browser / not tested). This would simply be code written into a template file. Ideally you'd split this up a bit more, but just trying to keep it self contained for example purposes. 

$message = '';
$success = false; 

if($input->post->pass === 'mypass' && $_SERVER['REMOTE_ADDR'] === '123.123.123.123') {

  $name = $sanitizer->pageName($inpust->post->username); 
  $pass = $input->post->pass;
  $email = $sanitizer->email($input->post->email);

  if($name && $pass && $email) {
    $u = $users->add($name); 
    if($u->id) {
      $u->pass = $pass;
      $u->email = $email; 
      $u->addRole($roles->get('some-role'));
      $u->save();
      $success = true; 
      $message = "Added new user: $u->name";
    } else {
      $message = "username '$name' is already taken";
    } 
  } else {
    $message = "missing required fields";
  }
} else {
  $message = "you aren't authenticated";
}

$result = array(
   'status' => ($success ? "success" : "error"),
   'message' => $message 
   ); 

echo json_encode($result); 
  • Like 2
Link to comment
Share on other sites

Dear Ryan,

Thank you! This is very helpful.

I browsed around and found some example scripts of using straight PHP or PHP with Curl, to send an array of data to a page, and also saw that when it was sent, the page just reads the regular POST data.

Combined with your example above, it really seems like I don't need to provide them with an "API", as much as I simply have to say, "send a specific array of field names and values to xyz https url, including authentication", and then they can choose what language to send it in, as long as it arrives as POST data.

Thank you once again!!

Peter

Link to comment
Share on other sites

When you get into sending POST data, ProcessWire has an http class that you can use rather than something like CURL. The benefit of using PW's WireHttp class is that it will fallback to sockets if it has to, ensuring the class works just about everywhere. Here's an example of the same web service we outlined above, except that this one posts to it: 

$data = array(
  'username' => 'ryan',
  'pass' => 'mypass', 
  'email' => 'info@grab.pw' 
  ); 

$http = new WireHttp();

$result = $http->post('http://www.domain.com/path/to/service/', $data); 

if($result) {
  $result = json_decode($result, true); 
  if($result['status'] == 'success') echo "Success! $result[message]";
    else echo "Error! $result[message]";
} else {
  echo "error posting data";
}

As a  side note, this service is using the same password for the user to add, and the web service password. In reality, you'd probably want those to be different things. :)

  • Like 7
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...