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

<pre><code>&lt;?php
namespace Craft;

$user = craft()-&gt;userSession-&gt;getUser();
if (!$user) {
    HeaderHelper::setHeader(array('status' =&gt; 404));
    craft()-&gt;end();
}
</code></pre>

<p>Note that you can replace the <code>404</code> with <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error" rel="noreferrer">another HTTP status code</a> if you want to; pick whatever feels appropriate to your app.</p>

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

<pre><code>&lt;?php 
namespace Craft;

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

return [
    ...
</code></pre>

<p>Then, it's simply a matter of calling this function from your restricted endpoints' <code>transformer</code> callbacks:</p>

<pre><code>'news.json' =&gt; [
    'elementType' =&gt; 'Entry',
    'criteria' =&gt; ['section' =&gt; 'news'],
    'transformer' =&gt; function(EntryModel $entry) {

        // This endpoint should be restricted
        requireLogin();

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

    },
],
...
</code></pre>

CC BY-SA 3.0
2016-11-26T13:29:26.330Z
Thanx @Mats tried it today and works like a charm, I also added basic authentication for usage in an app
Maarten Heideman
CC BY-SA 3.0
2016-12-02T10:14:04.013Z
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
CC BY-SA 3.0
2016-12-02T10:26:47.227Z
@MaartenHeideman Yes, that's possible – something like this would work fine: `craft()->end(JsonHelper::encode(['status' => 'error']));`
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2016-12-02T10:27:23.343Z
You should probably not use HTTP status 404 if you're returning an error object though.
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2016-11-20T19:46:59.667Z
2016-11-20T19:46:59.667Z
Mats Mikkel Rummelhoff
<p>For the people who needs something similar. The basic auth function for the Element API.</p>

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

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

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

}
</code></pre>

<p>And you use these params in your url: <code>?loginName=username&amp;password=yourpass</code></p>

CC BY-SA 4.0
2018-10-16T17:05:41.697Z
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
CC BY-SA 4.0
2018-10-16T17:29:25.487Z
I am switched over to the JWT manager
Maarten Heideman
CC BY-SA 3.0
2016-12-02T19:59:06.033Z
2016-12-02T21:48:41.403Z
2016-12-02T21:48:41.403Z
Maarten Heideman
<p>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 <code>requirelogin</code> or <code>currentUser</code> for this?</p>

<plugin-elementapi><authentication>
How to use the Element API plugin only when logged in?
# How to use the Element API plugin only when logged in?

(Asked by: username_0 on 2016-11-20)

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?

**Tags:** plugin-elementapi, authentication


---

## 2 answers

### Answer by username_0 on 2016-12-02. Score: 0 | Accepted answer

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

> **Comments:**
> **username_2**: 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.  
> **username_0**: I am switched over to the JWT manager  

---

### Answer by username_1 on 2016-11-20. Score: 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:
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. 
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,
            ...
        ];

    },
],
...

> **Comments:**
> **username_0**: Thanx @Mats tried it today and works like a charm, I also added basic authentication for usage in an app  
> **username_0**: 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  
> **username_1**: @MaartenHeideman Yes, that's possible – something like this would work fine: `craft()->end(JsonHelper::encode(['status' => 'error']));`  
> **username_1**: You should probably not use HTTP status 404 if you're returning an error object though.  

---

