11

I've made a Yii2 REST API. With the API you can get a list of cars. Now I want to use the Bearer Authentication to protect the API. But I don't know how it works.

First of all. I set up the authenticator in the behaviors method of my controller.

public function behaviors(){
    return [
        'contentNegotiator' => [
            'class' => ContentNegotiator::className(),
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
            ],
        ],
        'authenticator' => [
            'class' => CompositeAuth::className(),
            'authMethods' => [
                HttpBearerAuth::className(),
            ],
        ]
    ];
}

This works just fine. If I go to the URL I will get an 'Unauthorized' message.

In my wordpress plugin I've made an function to use the API and set the header with the authentication key.

function getJSON($template_url) {
    $authorization = "Authorization: Bearer " . get_option("auth_key");

    // Create curl resource
    $ch = curl_init();
    // Set URL
    curl_setopt($ch, CURLOPT_URL, $template_url);
    // Return transfer as a string
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // Set headers
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', $authorization));
    // $output contains output as a string
    $output = curl_exec($ch);
    // Close curl resource
    curl_close($ch);

    return json_decode($output, true);
}

But now my question is. How can I check in the API if this key is valid and give me the response. I want to search for the key in de database and if it exists it should also give me the id or email thats in the same row.

I have no idea how to do this.

Wouter den Ouden
  • 1,523
  • 2
  • 17
  • 44

1 Answers1

12

\yii\filters\auth\HttpBearerAuth::authenticate() will simply call \yii\web\User::loginByAccessToken() :

$class = $this->identityClass;
$identity = $class::findIdentityByAccessToken($token, $type);

So you just need to implement findIdentityByAccessToken() in your user identity class, e.g. :

public static function findIdentityByAccessToken($token, $type = null)
{
    return static::findOne(['auth_key' => $token]);
}
soju
  • 25,111
  • 3
  • 68
  • 70
  • In the class I use another table than where the access_tokens are. Any idea of how I can check the access tokens in another table? – Wouter den Ouden Mar 01 '16 at 11:17
  • 2
    @WouterdenOuden when `findIdentityByAccessToken` returns `null` authentication will be rejected. so do whatever logic you need inside it (like also checking token validity) and return `null` if authentication should fail or return a **user** instance that `Yii::$app->user->identity` will hold so you can use it any where inside your app. check [this](http://www.yiiframework.com/doc-2.0/guide-rest-authentication.html) and [this](http://blog.neattutorials.com/angularjs-and-yii2-part-2-authentication/) for more details. – Salem Ouerdani Mar 01 '16 at 11:26
  • ...you may also need to build Actions to handle login, signup, ... like in this [example](https://github.com/tunecino/Yii2_foundation-apps/tree/master/backend/auth/controllers). – Salem Ouerdani Mar 01 '16 at 11:29
  • So I could just make a query with one() and if it doesn't find anyting it will return null? and if it finds data the authentication would be successful? – Wouter den Ouden Mar 01 '16 at 11:31
  • exactly. just remember that `findIdentityByAccessToken` should return either `null` or a `user` instance. (note that by default [findOne()](http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#findOne()-detail) will return `null` if user not found) – Salem Ouerdani Mar 01 '16 at 11:34
  • Is there a way to test if my getJSON function sets the httpheader? because I can't get it to work. – Wouter den Ouden Mar 01 '16 at 12:07
  • Take a look at your debug log – soju Mar 01 '16 at 12:18
  • the findIdentityByAccessToken should be put in basic/vendor/yiisoft/yii2/web/User.php or could I also put it in basic/models/Car.php?? – Wouter den Ouden Mar 01 '16 at 12:35
  • I am a bit confused because my models folders contains a User.php as well. So I don't know where to put the findIdentityByAccessToken – Wouter den Ouden Mar 01 '16 at 12:48
  • In your user identity class ! – soju Mar 01 '16 at 13:01
  • Got it to work finally. Thanks. I had to change the loginByAccessToken a little bit. – Wouter den Ouden Mar 01 '16 at 13:39