正确的实现自定义身份验证的方式rest cakephp api

时间:2014-06-06 11:43:05

标签: php cakephp authentication

我目前正在开发cakephp中的restful / stateless api,它使用令牌(目前)并且应该使用滚动令牌(如来自g-shearer的建议here)。我当前的实现工作正常,但我真的很担心我是否以正确的方式实现了所有内容(auth组件,尤其是自定义身份验证组件对我来说真的很混乱)

PS:我使用的是当前版本的cakephp(2.5.1)。

1:我在Controller / Component / Auth中创建了TokenAuthenticate.php文件:

<?php

App::uses('BaseAuthenticate', 'Controller/Component/Auth');

class TokenAuthenticate extends BaseAuthenticate {

public function authenticate(CakeRequest $request, CakeResponse $response) {
}

public function getUser(CakeRequest $request) {
    //set values from request headers
    $publictoken = $request->header('Security-Public-Token');
    $accesstoken = $request->header('Security-Access-Token');
    $timestamp = $request->header('Security-Timestamp');
    // check if required header fields are set
    if (empty($publictoken) || empty($accesstoken) || empty($timestamp)) {
        return false;
    }
    // init required token model
    $Token = ClassRegistry::init('Token');
    //check if token pair exists
    if ($dbtoken = $Token->findByPublic($publictoken)) {
        if ($accesstoken == md5($dbtoken['Token']['private'] . $timestamp)) {
            //valid token - return user
            $User = ClassRegistry::init('User');
            $dbuser = $User->findById($dbtoken['Token']['user_id'])['User'];
            return $dbuser;
        } else {
            //invalid token
            return false;
        }
    } else {
        //invalid token pair
        return false;
    }
}

public function unauthenticated(CakeRequest $request, CakeResponse $response) {
    return true;
}

}

?>

然后我将以下内容添加到我的控制器中:

class UsersController extends AppController {
public $uses = array('User', 'Token');
public $components = array('Auth' => array('authenticate' => array('Token')));

public function beforeFilter() {
    parent::beforeFilter();
    AuthComponent::$sessionKey = false;
    $this->Auth->autoRedirect = false;
    $this->Auth->allow('login', 'register');
}

在我的行动中,我检查状态如下:

if (!$this->Auth->loggedIn()) {
        $this->set(array('error' => 'INVALID_AUTHENTIFICATION'));
        $this->render('view');
    }

所以我可以设置一个自定义错误并输出它而不会被重定向到登录操作(注意我的tokenauthentication文件中的未经验证的函数返回true - 所以cakephp不会重定向你)

我认为登录过程应该发生在我的TokenAuthenticate文件的身份验证功能中,而不是在我的控制器的登录操作中,或者我错了?实现这一目标的正确方法是什么?

PS:如何使用cakephp自动添加一个新的令牌对(对每个经过身份验证的输出),以便令牌“滚动”?

如果重要的话,整个api输出是json编码的

即使我禁用了这个(AuthComponent :: $ sessionKey = false;),cakephp仍然会设置一个cookie。如何阻止这个?

编辑:所以我已经在我的用户控制器中添加了一个beforeRender()函数,现在令牌正在滚动(Y)

    //renew tokens
public function beforeRender() {
    //only add tokens if logged in
    if ($this->Auth->loggedIn()) {
        //find old token
        $oldToken = $this->Token->findByUser_id($this->Auth->user('id'));
        //delete old token
        $this->Token->delete($oldToken['Token']['id']);
        //create new token pair
        $this->Token->create();
        $this->Token->save(array(
            'user_id' => $this->Auth->user('id'),
            'public' => Security::hash(substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$') , 0 , 15 )),
            'private' => Security::hash(substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$') , 0 , 15 ))
        ));
        //set it for the view
        $this->set(array('token' => $this->Token->read()));
    }
}

这是实现这样的事情的正确方法吗?我总是想做正确的事情,并且完美无缺。所以任何评论都是受欢迎的。)

0 个答案:

没有答案