rest icon indicating copy to clipboard operation
rest copied to clipboard

How do I get post data?

Open tomofu74 opened this issue 6 years ago • 26 comments

Hi, I am a beginner of developing humhub. I want to GET/POST a post from my humhub with API. So, I wrote a test with curl, but it does not work. Probably, I must be wrong, but, I don't know how I should do. I wrote like this,

curl -H "Authorization; token " https://.com/api/v1/post/18010

but, it returns

{"name":"Unauthorized","message":"Wrong number of segments", "code":0, "status":401, "type":"yii\web\HttpException"}

How does it have to be? Please teach me the writing format. Thank you.

tomofu74 avatar Dec 25 '19 17:12 tomofu74

Seems there is a problem with your authorization. Did you tried basic auth?

luke- avatar Jan 22 '20 13:01 luke-

Thank you, Luke.

I tried basic auth and that is going as desired.

I can send a new post to contentcontainer6 (=a existing space) by REST-API with basic auth: e.g.,

curl -k --request POST -H "Content-Type:application/json" -H "Authorization:Basic $(echo -n '~username~:~password~'|openssl base64)" -d '{"data":{"message":"PostActionTEST from REST-API"}}' "https://www..../api/v1/post/container/6"

But, I don't know how to write with Bearer Token. Please give me a chance to learn.

tomofu74 avatar Jan 31 '20 05:01 tomofu74

e.g. to create a group:

curl --user Admin:secretPassword -d '{"name":"Test group"}' -H 'Content-Type: application/json' http://example.com/api/v1/user/group

luke- avatar Jan 31 '20 16:01 luke-

You can use also Postman, we have a complete collection with all possible requests here: https://github.com/humhub/humhub-modules-rest/tree/master/docs/postman

luke- avatar Jan 31 '20 16:01 luke-

I have the same issue. On the API configuration page under JWT Key, it says If empty, a random key is generated automatically.

When I leave it empty and click Save, I get a Syntax error : Invalid Argument – yii\base\InvalidArgumentException

I then go back and refresh the page and a JWT token is automatically filled in. I then click Save and it saves successfully. I then use that JWT token with Postman and get the same error as OP. (Wrong number of segments)

The best I can see is that in the file /protected/vendor/firebase/php-jwt/src/JWT.php in the function decode($jwt, $key, array $allowed_algs = array()) it explodes the jwt token on a period '.'.

$tks = \explode('.', $jwt); if (\count($tks) != 3) { throw new UnexpectedValueException('Wrong number of segments'); }

Since the token doesn't have two periods, I assume it will always throw this error. When I paste the JWT token into jwt.io it says it has an invalid signature.

The HTTP Basic Authentication works for me though.

GeraldBecker avatar Oct 20 '20 19:10 GeraldBecker

On the API configuration page, the JWT Key is the secret key (not the token you will use).

To get the token key, go to https://jwt.io/:

  • Select algorithm HS512
  • In PAYLOAD:DATA (replace 1 with the user id that will be used to execute the API actions):
{
 "uid": 1
}
  • VERIFY SIGNATURE: replace your-256-bit-secret by the secret key (in the API configuration) and uncheck secret base64 encoded
  • Copy the encoded token: this is the token you will use to send actions to the API

marc-farre avatar Oct 20 '20 21:10 marc-farre

Thanks @funkycram !!!! That worked perfectly.

GeraldBecker avatar Oct 20 '20 21:10 GeraldBecker

Thanks @funkycram They lacked to explain this better in the documentation.

YuriFontella avatar Nov 05 '20 12:11 YuriFontella

Hey @funkycram did you mean like that image

Yes. I really don't know why you have 400 bad request.

marc-farre avatar Sep 14 '21 14:09 marc-farre

Hey guys, specifically @funkycram

I am really struggling here as its giving me a 136 character string from JWT and it can only be 128 long.

Based on whats been said above I have copied the string the module creates and put that as the secret key on JWT.io

I have set "uid":1 on the payload as well and the type is HS512.

Please can someone tell me what I am doing wrong here as I receive this error:

{"name":"Unauthorized","message":"Invalid token!","code":0,"status":"401"}

BaconTriple avatar Jan 10 '22 15:01 BaconTriple

Sorry @BaconTriple, I don't know what's happening for you, I don't have much experience with this module, I just did it according to the procedure I gave above...

marc-farre avatar Jan 12 '22 10:01 marc-farre

damn... I am really at a loss here because I need this api data, does anyone have a clear step by step with an example they could show me with screenshots. I feel the documentation side of this is lacking quite severely and this could help a lot of other people who stumble across this

BaconTriple avatar Jan 18 '22 15:01 BaconTriple

Ok so I have managed to get it to work using reqbin.com but the issue is I need to be able to query to current logged in user of a session but this JWT method only allows me to use one UID which means every request is just the user details of that UID. So what is everyone else doing?

BaconTriple avatar Jan 21 '22 09:01 BaconTriple

Trying to use the API (in another PHP app) and I hardly understand anything to what am I supposed to do with the tokens.

Got a basic PHP curl function that is supposed to work with anything

// Method: POST, PUT, GET etc
// Data: array("param" => "value") ==> index.php?param=value
function CallAPI($method, $url, $data = false)
{
    $curl = curl_init();

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    //curl_setopt($curl, CURLOPT_USERPWD, "user:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}

It works when I call it to auth on the API with my user and password:

$apidata =  array("username"=>"Myuser","password"=>"Mypassword");
$json = CallAPI("POST","https://www.myhumhub.com/api/v1/auth/login",$apidata);
$obj=json_decode($json);
$token=$obj->auth_token;
echo "Auth : ". $obj->message . "<br>Token = ".$token ."<hr>";

Returns

Auth : Success Token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2NDQ3NjIyMDUsImlzcyI6Imh0dHBzOlwvXC9lc3BlaHViLmJlXC8iLCJuYmYiOjE2NDQ3NjIyMDUsInVpZCI6MSwiZW1haWwiOiJ0b21AZXNwZXJhbnphaC5iZSJ9.J1BqDcBaFWmxKYJo7poWht-IpRD05LZeI0f0k25rcTR3RgbsOiKxXwhEzLRnx_YaiICe4tBEdl12Bm-27L4IUA

After that I am stuck. I can't figure out how to use any function of the API and especially how to pass the token I received.

Example :

            $apidata =  array("auth_token"=>$token); // retrieved previously
            $json = CallAPI("POST","https://www.myhumhub.com/api/v1/user",$apidata);
            echo var_dump(json_decode($json, true));

Gives :

array(4) { ["name"]=> string(12) "Unauthorized" ["message"]=> string(14) "Invalid token!" ["code"]=> int(0) ["status"]=> string(3) "401" }

How to use the token(s) isn't explained anywhere in the humhub API documentation, which is quite disappointing.

I tried to name my token variable differently, but couldn't guess something that work. I googled 2 hours and I am still stuck.

I also tried to use the trick explained above by @funkycram and use that token instead, but it doesn't work either.

Could you please provide an example of how to auth on and use the API with some basic PHP curl code ?

Cheers

DuvelCorp avatar Feb 13 '22 14:02 DuvelCorp

@yurabakhtin Can you please give a small example?

luke- avatar Feb 14 '22 09:02 luke-

@DuvelCorp @luke- The token should be passed separately, for example as 4th param:

function CallAPI($method, $url, $data = false, $token = null)

then add these lines into the function:

    if ($token) {
        $authorization = 'Authorization: Bearer ' . $token;
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization));
    }

and instead of your example please use code like this:

$json = CallAPI("GET","http://humhub.yb/api/v1/user", false, $token);
echo '<pre>';
var_dump(json_decode($json, true));
echo '</pre>';

For me it works:

test_rest

PS: this info is from first result of google search "php curl send bearer token" - https://stackoverflow.com/questions/30426047/correct-way-to-set-bearer-token-with-curl.

yurabakhtin avatar Feb 15 '22 09:02 yurabakhtin

@yurabakhtin Thank you very much, it now works perfectly ! 👍

DuvelCorp avatar Feb 16 '22 10:02 DuvelCorp

@yurabakhtin got additional troubles for the PUT /user

Basically I just want to update one custom profile field that I have created, which is the person ID in my other system. I can see this field in the json returned when I do a GET.

First I have modified my CallAPI function with

        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            if ($data){
                curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($data)));
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            }

Then I have supposed that in my PUT, I just have to specify the field I want to update, with their value, but that doesn't work. Things I tried:

    $data = array('profile'=>array('fc_id'=>$fcid));
    $payload = json_encode($data); 
    $json = CallAPI("PUT","https://www.myhumhub.com/api/v1/user/1",$payload, $HubToken);

--> Returns "NULL"

or

    $payload = '{"profile":{"fc_id": "'.$fcid.'"}}';
    $json = CallAPI("PUT","https://www.myhumhub.com/api/v1/user/1",$payload, $HubToken);

--> Returns the user data, but field is not updated.

At this point I am wondering what my issue is, and if I am supposed to send in my PUT, the whole payload as described here https://www.humhub.com/en/marketplace/rest/docs/html/user.html#operation/updateUser , meaning ALL users data.

That doesn't sounds right to me, as I just want to update one field of the user profile

DuvelCorp avatar Feb 17 '22 07:02 DuvelCorp

It took me a couple of tries to get the Bearer auth to work, and it was really entirely my own fault. @funkycram has a perfectly sane and functional example via jwt.io, so thank you for that.

First, read the example carefully. I used "id" in place of "uid" and that surely won't work (duh). Second, I used my text username instead of my integer ID number. I wasn't sure of my uid as it's not entirely obvious (on my install anyway - we use LDAP). I found the uid by clicking the gear icon beside my name in the user admin and hovering over "edit". The ID is in the link (status bar). I could have looked at the DB as well. Could be something to put on the user list table on the user admin page at some point.

I will consider writing a basic markdown "how to" for the docs if someone wants to incorporate that into the main api documentation page. I think that would be worthwhile for users.

jelofson avatar Apr 06 '22 02:04 jelofson

Here is a gist that can be used as a guide if anyone wants it:

https://gist.github.com/jelofson/75d6d81cdb7daf9f337a11f10a96d4bb

jelofson avatar Apr 06 '22 02:04 jelofson

Thanks @yurabakhtin and @jelofson for theses guide. Perhaps it could be useful for others to share theses tips on https://github.com/humhub/rest/blob/master/docs/README.md or https://github.com/humhub/rest/blob/master/docs/MANUAL.md ?

marc-farre avatar Apr 06 '22 07:04 marc-farre

By all means. Take mine and tweak it or update it as you see fit. If it helps others that would be great. I won't have time to clone the docs and contribute directly, but if you want the content, please feel free. Maybe I will check out the community pages and see if there are any questions related to it as well.

jelofson avatar Apr 06 '22 13:04 jelofson

e.g. to create a group:

curl --user Admin:secretPassword -d '{"name":"Test group"}' -H 'Content-Type: application/json' http://example.com/api/v1/user/group

This command requires to have Allow HTTP Basic Authentication ticked in the module settings.

To connect with the JWT token (see how to generate the token here), you can use Authorization: Bearer xxxx.xxx.xxxxx (xxxx.xxx.xxxxx is the token):

curl -d '{"name":"Test group"}' -H 'Content-Type: application/json' -H 'Authorization: Bearer xxxx.xxx.xxxxx' https://example.com/api/v1/user/group

marc-farre avatar Nov 11 '22 11:11 marc-farre

On the API configuration page, the JWT Key is the secret key (not the token you will use).

To get the token key, go to https://jwt.io/:

  • Select algorithm HS512
  • In PAYLOAD:DATA (replace 1 with the user id that will be used to execute the API actions):
{
 "uid": 1
}
  • VERIFY SIGNATURE: replace your-256-bit-secret by the secret key (in the API configuration) and uncheck secret base64 encoded
  • Copy the encoded token: this is the token you will use to send actions to the API

Doing this exactly, but still seeing the error:

{
    "name": "Unauthorized",
    "message": "Invalid token!",
    "code": 0,
    "status": "401"
}

How to resolve/diagnose this issue?

arladmin avatar Jan 19 '23 17:01 arladmin

On the API configuration page, the JWT Key is the secret key (not the token you will use). To get the token key, go to https://jwt.io/:

  • Select algorithm HS512
  • In PAYLOAD:DATA (replace 1 with the user id that will be used to execute the API actions):
{
 "uid": 1
}
  • VERIFY SIGNATURE: replace your-256-bit-secret by the secret key (in the API configuration) and uncheck secret base64 encoded
  • Copy the encoded token: this is the token you will use to send actions to the API

Doing this exactly, but still seeing the error:

{
    "name": "Unauthorized",
    "message": "Invalid token!",
    "code": 0,
    "status": "401"
}

How to resolve/diagnose this issue?

I haved the same problem. And this instruction work perfectly. May be you do something wrong on https://jwt.io/ page. On this page you must see "Signature Verified" string at the botton on left side of the page (below "Encoded" field) before copy token.

TsysarAndrew avatar Mar 17 '23 10:03 TsysarAndrew

There is any existing module to request some data from an external API and show it inside a Hamhub Space?

bpieres avatar Dec 04 '23 20:12 bpieres