簡體   English   中英

CakePHP 3 REST API身份驗證,同時仍使用現有控制器

[英]CakePHP 3 REST API authentication while still using the existing controllers

我在CakePHP 3中為移動設備實現REST API身份驗證時遇到了問題。

閱讀認證官方CakePHP 3文檔:

http://book.cakephp.org/3.0/en/controllers/components/authentication.html#id1

它說我可以使用無狀態基本身份驗證而不是表單身份驗證。 但是,我也在其中一個論壇中讀到,您不能同時使用基本身份驗證和表單身份驗證。

我還研究了使用REST API的前綴路由。

http://www.bravo-kernel.com/2015/04/how-to-prefix-route-a-cakephp-3-rest-api/

通過這樣做,我現在可以對前綴路由執行基本身份驗證,對非前綴路由執行表單身份驗證。 但是,這需要在其前綴命名空間中定義控制器,這違反了CakePHP保持代碼DRY的概念; 因為我的控制器已經包含適用於網絡和移動設備的邏輯。

如果我只是使用表單身份驗證,我可以從我的手機創建一個POST請求到Web系統,但響應將是HTML格式。 解析整個HTML格式不是一個好方法。

我被困住了,不知道該怎么辦。 我整個下午一直在研究,但仍未能找到解決方案。

我想要的是能夠通過我的移動應用程序進行身份驗證,同時仍然使用相同的控制器。

編輯:解決方法

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Auth', [
            'authorize' => 'Controller',
            'authenticate' => [
                'Form' => [
                    'fields' => [
                        'username' => 'username',
                        'password' => 'password'
                    ]
                ]
            ],
            'loginAction' => ['controller' => 'Users', 'action' => 'login'],
            'unauthorizedRedirect' => $this->referer()
        ]);
    }

    public function beforeFilter(Event $event)
    {
        if($this->request->params['_ext'] === 'json')
        {
            $this->Auth->config('authenticate', ['Basic' => ['userModel' => 'Users']]);
            $this->Auth->config('storage', 'Memory');
            $this->Auth->config('unauthorizedRedirect', false);
        }
        return parent::beforeFilter($event);
    }
}

通過有條件地將基本身份驗證添加到身份驗證配置來管理以使其工作。

然而,這不是一個完美的解決方案,因為它肯定有陷阱。

這只能在以下假設下工作:

  1. 參考這篇文章:CakePHP將根據身份驗證方案的順序執行優先級。 由於Form Auth在Basic Auth之前,如果Form Auth成功,Basic Auth將不會執行。

    CakePHP 2.1 - 作為具有身份驗證的Web應用程序和REST服務

  2. 通常,Web用戶不會訪問具有json文件擴展名的URL,因此將使用表單身份驗證將用戶重定向到用戶登錄頁面。

  3. 通過表單身份驗證對用戶進行身份驗證后,即使用戶使用AJAX間接訪問以.json結尾的URL,也不會彈出基本身份驗證。

有沒有更好的方法?

您可以通過使用basic authentication來實現此目的。對於Web,您必須使用form authentication而對於REST API您必須使用basic authentication並且您可以一次使用兩者。我已經實現了它,下面是工作示例。

   public function initialize() {
        parent::initialize();
        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        $url = $this->request->url;
        $ext = $this->request->params['_ext'];
        if ((isset($ext) && $ext == 'json') && (!($this->request->is('ajax')) && ($url != 'users/loginapi.json')) ) {    
            $this->loadComponent('Auth', [
                'authenticate' => [
                    'Basic' => [
                        'fields' => ['username' => 'email', 'password' => 'api_key'],
                        'userModel' => 'Users',
                        'scope' => ['status' => 'A']
                    ],
                ],
                'storage' => 'Memory',
                'unauthorizedRedirect' => false
            ]);
        } else {
            $this->loadComponent('Auth', [
                'authenticate' => [
                    'Form' => [
                        'fields' => ['username' => 'email_or_mobile', 'password' => 'password'],
                        'userModel' => 'Users',
                        'scope' => ['status' => 'A'],
                        'finder' => 'auth'
                    ]
                ],
                'storage' => 'Session',
                //'unauthorizedRedirect' => false,
                'loginRedirect' => [
                    'controller' => 'Users',
                    'action' => 'index'
                ],
                'logoutRedirect' => [
                    'controller' => 'Users',
                    'action' => 'login'
                ],
                'authError' => false
            ]);
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM