2

I'm trying to create a REST API and looking for a way to login using PHP, the documentation provided a login example using Python but I don't have an idea how to do this using PHP. I'm thinking if there's a PHP version of the Python code below.

See below code:

def login():
global sessionID
req = urllib2.Request("https://<host>/appserver/j_spring_security_check")
req.add_data(urllib.urlencode({"j_username" : "admin","j_password" :"demoserver"}))
res = opener.open(req)
sessionID = getCookie("JSESSIONID",cookies)
# Get the value of JSESSIONID cookie
response = res.read()
return

What is the login script (PHP version) that I can use if I need to login to web service using PHP (considering the Python example)?

Additional information:

Logging into the web service requires a JSON object as the request body with user name and password:

Successful execution of the method will return a Cookie session Id

Example request JSON: {"j_username" : "username", "j_password":"*******"}

User needs to parse the cookies and extract cookie with key as JSESSIONID. This JSESSIONID value needs to be added manually in all headers of the Rest calls

“Cookie”: “JSESSIONID=“ + cookieValue

Another example using Python:

//Request for All Apps
global sessionID
sID = "JSESSIONID="+sessionID
uri = "https://<hostname>/appserver/portal/api/1.0/apps"
req = urllib2.Request(uri)
req.add_header("Content-Type", "application/json")
req.add_header("Cookie", sID) # Header
req.get_method = "lambda: GET” # Method Type
res = opener.open(req) # URL Call
response = res.read()
return response

Request headers:

Host: 192.168.100.100:444
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*\/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://192.168.100.100:444/appserver/portal/login;jsessionid=6AD37194D43AB02BB79E26C71554958F
Cookie: JSESSIONID=6AD37194D43AB02BB79E26C71554958F
Connection: keep-alive
Upgrade-Insecure-Requests: 1

----------

When I tried curl using Linux, here's the code.

curl -k -i -H "Content-type: application/x-www-form-urlencoded" -c cookies.txt -X POST https://192.168.100.100:444/appserver/j_spring_security_check -d "j_username=admin&j_password=demoserver"

Here's the result of the linux curl, which I believe has succeed in connecting since I was routed to the welcome page.

HTTP/1.1 302 Found
Date: Thu, 16 Feb 2017 18:41:59 GMT
Server: Apache/2.2.26 (Unix) mod_ssl/2.2.25 OpenSSL/1.0.1e mod_jk/1.2.37
Set-Cookie: JSESSIONID=358446CC1F87B2D698D48AFECA373691; Path=/appserver/; HttpOnly
Location: https://192.168.100.100:444/appserver/portal/welcome;jsessionid=358446CC1F87B2D698D48AFECA373691
Content-Length: 0
Access-Control-Allow-Origin: *
Content-Type: text/plain

----------

But when I tried using PHP curl with the code, still could not connect though.

<?php
$ch = curl_init();
$url  = "https://192.168.100.100:444/appserver/j_spring_security_chec‌​k";
$postData = 'j_username=admin&j_password=demoserver';
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1); // -X
curl_setopt($ch, CURLOPT_POSTFIELDS,$postData); // -d
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'application/x-www-form-urlencoded'
)); // -H
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt'); // -c
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt'); // -c
curl_setopt($ch, CURLOPT_HEADER, true); // -i
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // -k
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec ($ch);
curl_close ($ch);

This is the resulting header in my browser. Request URL: http://localhost/curl.php Request method: GET Remote address: 127.0.0.1:80 Status code: 200 OK Version: HTTP

Response header:
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/\*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

Response headers:
Date: Thu, 16 Feb 2017 18:43:52 GMT
Server: Apache/2.2.26 (Unix) mod_ssl/2.2.25 OpenSSL/1.0.1e mod_jk/1.2.37
Content-Language: en-US
Content-Length: 4815
Access-Control-Allow-Origin: *
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html;charset=UTF-8
Mark Toledo
  • 101
  • 1
  • 15
  • You probably need to add a 'CURLOPT_FOLLOWLOCATION' option to follow redirects. I added this to the code below. – mevdschee Feb 20 '17 at 23:30

3 Answers3

3

You need to use CURL

Request to url : "https://<host>/appserver/j_spring_security_check"

And post data : "j_username=admin&j_password=demoserver"

So your code would look like

<?php
    $ch = curl_init();
    $url  = "https://<host>/appserver/j_spring_security_check";
    $postData = "j_username=admin&j_password=demoserver";
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$postData);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $server_output = curl_exec ($ch);
    echo $server_output;
    curl_close ($ch);
?>
Niklesh Raut
  • 34,013
  • 16
  • 75
  • 109
  • 1
    Thanks for the fast response, Rishi. However, I'm still not adept at using PHP. Could you kindly help on the specific scripts that I should execute? I've compiled my php with curl so I believe it could work. – Mark Toledo Feb 18 '17 at 09:52
  • 1
    @MarkToledo : have provided example code change `url` and `postData` accordingly. and analyze the response and use as you needed. – Niklesh Raut Feb 18 '17 at 09:57
  • 1
    Wow thanks for this, Rishi! Appreciate the help! Unfortunately, I still couldn't get it to work. I've scoured into the documentation and found additional info which might help.. I've added it in my post. Apparently, cookies and setting login details as JSON are required. – Mark Toledo Feb 18 '17 at 10:20
1

Maybe you need cookie support? Something like this:

<?php
    // this is for cookie handling in the session
    session_start();
    $tmpFname = tempnam(sys_get_temp_dir(),"COOKIE");
    if (isset($_SESSION['cookies'])) {
        file_put_contents($tmpFname,$_SESSION['cookies']);
    }

    // the request
    $ch = curl_init();
    $url  = "https://<host>/appserver/j_spring_security_check";
    $postData = "j_username=admin&j_password=demoserver";
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$postData);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/x-www-form-urlencoded'
        // you may add more request headers here
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    // the next two options are for cookie handling
    curl_setopt($ch, CURLOPT_COOKIEJAR, $tmpFname);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $tmpFname);
    $server_output = curl_exec ($ch);
    echo $server_output;
    curl_close ($ch);

    // this is for cookie handling in the session
    $_SESSION['cookies'] = file_get_contents($tmpFname);
    unlink($tmpFname);

I hope that helps.

mevdschee
  • 1,625
  • 19
  • 16
  • 1
    Thanks, this gave me a broader view. I have questions though. 1) How do you post a JSON `{"j_username" : "username", "j_password":"*******"}` instead of `j_username=admin&j_password=demoserver`? 2) How do you properly get a cookie like in this example python code `sessionID = getCookie("JSESSIONID",cookies)`? Since the webserver provides a session ID that can be fetched and added to the script.. – Mark Toledo Feb 19 '17 at 08:06
  • 1
    In the post, I've added the request header produced by the browser when I connected via firefox. – Mark Toledo Feb 19 '17 at 09:20
  • Updated the example to use JSON, although the (first) Python example does not use that. – mevdschee Feb 19 '17 at 12:55
  • This code will expect the cookie to be set using a "SetCookie" response header and will sent the appropriate cookies using a "Cookie" request header. If you want to modify the cookie, then you should (parse and) modify the $_SESSION['cookies'] variable. – mevdschee Feb 19 '17 at 12:57
  • You can also leave all the cookie handling out and just manually send a 'Cookie' request header in the same way I'm sending the 'Content-Type' and 'User-Agent' headers. – mevdschee Feb 19 '17 at 13:01
  • 1
    sorry mate, I was jumping through diff sites here and there. but I highly appreciate your efforts in guiding me with my problem. Cheers bro! :) – Mark Toledo Feb 22 '17 at 08:38
1

Based on your edited question I think it would be best if you did:

<?php
    $ch = curl_init();
    $url  = "https://<host>/appserver/j_spring_security_check";
    $postData = '{"j_username":"admin","j_password":"demoserver"}';
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$postData);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Host: 192.168.100.100:444',
        'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0',
        'Referer: https://192.168.100.100:444/appserver/portal/login;jsessionid=6AD37194D43AB02BB79E26C71554958F',
        'Cookie: JSESSIONID=6AD37194D43AB02BB79E26C71554958F'
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // see comment
    $server_output = curl_exec ($ch);
    echo $server_output;
    curl_close ($ch);

I think this suits your question, in it's current form, better.

mevdschee
  • 1,625
  • 19
  • 16
  • 1
    I'm also researching about the JSESSIONID, it is provided to me by the webservice upon opening the site. JSESSIONIDs are different each time I check it. Is there a way to properly fetch the JSESSIONID cookie given to me by the web service (like the python function `getCookie("JSESSIONID",cookie)` and use it in my login options? – Mark Toledo Feb 19 '17 at 14:33
  • 1
    As per my recent research, I could connect to the webservice using linux terminal via this code, it returns welcome page. I just don't know how to convert this to PHP curl.> > >`curl -k -i -H "Content-type: application/x-www-form-urlencoded" -c cookies.txt -X POST https://192.168.100.100:444/appserver/j_spring_security_check -d "j_username=admin&j_password=demoserver"` – Mark Toledo Feb 19 '17 at 16:09
  • @MarkToledo: See my answer on [Convert Linux Curl to PHP](http://stackoverflow.com/questions/42329617/convert-linux-curl-to-php/42333052) – mevdschee Feb 19 '17 at 21:28
  • Thanks for the help so far @mevdschee, I've added the resulting headers of linux curl and php curl in my post. I still couldn't figure out why linux curl succeeds while php curl doesn't connect. Headers are also different.. – Mark Toledo Feb 20 '17 at 07:55
  • You probably need to add a 'CURLOPT_FOLLOWLOCATION' option to follow redirects. I added this to the code. – mevdschee Feb 20 '17 at 23:29