3

I want to use the Element API plugin, but the content must only be visible when users are logged in. How I do this for a section? Is it possible to use requirelogin or currentUser for this?

5

If you want to restrict the whole API, you can add some code to the top of your /config/elementapi.php file (right below namespace Craft;) that checks for a logged in user, and ends the request with an appropriate status if the user isn't logged in:

<?php
namespace Craft;

$user = craft()->userSession->getUser();
if (!$user) {
    HeaderHelper::setHeader(array('status' => 404));
    craft()->end();
}

Note that you can replace the 404 with another HTTP status code if you want to; pick whatever feels appropriate to your app.

If you want to restrict specific endpoints, but leave others open, the best approach is probably to wrap the above code in a function, i.e.

<?php 
namespace Craft;

function requireLogin() {
    $user = craft()->userSession->getUser();
    if (!$user) {
        HeaderHelper::setHeader(array('status' => 404));
        craft()->end();
    }
}

return [
    ...

Then, it's simply a matter of calling this function from your restricted endpoints' transformer callbacks:

'news.json' => [
    'elementType' => 'Entry',
    'criteria' => ['section' => 'news'],
    'transformer' => function(EntryModel $entry) {

        // This endpoint should be restricted
        requireLogin();

        return [
            'title' => $entry->title,
            ...
        ];

    },
],
...
| improve this answer | |
  • Thanx @Mats tried it today and works like a charm, I also added basic authentication for usage in an app – Maarten Heideman Nov 26 '16 at 13:29
  • Is it possible to add an array in the craft()->end(); tag? On fail login I want to return a json object wit 'status' => 'error' or something like that – Maarten Heideman Dec 2 '16 at 10:14
  • 1
    @MaartenHeideman Yes, that's possible – something like this would work fine: craft()->end(JsonHelper::encode(['status' => 'error'])); – Mats Mikkel Rummelhoff Dec 2 '16 at 10:26
  • You should probably not use HTTP status 404 if you're returning an error object though. – Mats Mikkel Rummelhoff Dec 2 '16 at 10:27
0

For the people who needs something similar. The basic auth function for the Element API.

function requireLogin()
{
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: X-Requested-With");

    if (craft()->userSession->isLoggedIn()) {
        // you are authenticated
    } else {
        // check params
        $loginName = craft()->request->getQuery('loginName');
        $password = craft()->request->getQuery('password');

        if (craft()->userSession->login($loginName, $password)) {
            // login success
            $user = craft()->userSession->getUser();
        } else {
            // login fails echo message
            $errorCode = craft()->userSession->getLoginErrorCode();
            $errorMessage = craft()->userSession->getLoginErrorMessage($errorCode, $loginName);
            craft()->end(JsonHelper::encode(array('data' => array( ['status' => 'error','message' =>'wrong login']  ))));
        }
    }

}

And you use these params in your url: ?loginName=username&password=yourpass

| improve this answer | |
  • FTR, I'd highly recommend not passing username/passwords combinations in the querystring as it opens up all sorts of security related issues. You can use some alternative authentication methods, such as token based. – Brad Bell Oct 16 '18 at 17:05
  • 1
    I am switched over to the JWT manager – Maarten Heideman Oct 16 '18 at 17:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.