简体   繁体   English

CakePHP 3 REST API身份验证,同时仍使用现有控制器

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

I am having trouble implementing a REST API authentication for mobile in CakePHP 3. 我在CakePHP 3中为移动设备实现REST API身份验证时遇到了问题。

Reading the Authentication official CakePHP 3 documentation: 阅读认证官方CakePHP 3文档:

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

It said that I can use Stateless Basic Authentication instead of Form Authentication. 它说我可以使用无状态基本身份验证而不是表单身份验证。 However, I also read in one of the forums that you cannot use both Basic and Form Authentication at the same time. 但是,我也在其中一个论坛中读到,您不能同时使用基本身份验证和表单身份验证。

I also researched on using prefix route for REST API. 我还研究了使用REST API的前缀路由。

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

By doing so, I can now perform the Basic Authentication to the prefix route and the Form Authentication to the non-prefix route. 通过这样做,我现在可以对前缀路由执行基本身份验证,对非前缀路由执行表单身份验证。 However, this requires controllers to be defined in its prefix namespace which violates CakePHP's concept of keeping your code DRY; 但是,这需要在其前缀命名空间中定义控制器,这违反了CakePHP保持代码DRY的概念; as my controllers already consist logic catering for web and mobile devices. 因为我的控制器已经包含适用于网络和移动设备的逻辑。

If I were to just use Form Authentication, I can just create a POST request from my mobile to the web system but the response would be in HTML format. 如果我只是使用表单身份验证,我可以从我的手机创建一个POST请求到Web系统,但响应将是HTML格式。 It would not be a good approach to parse the entire HTML format. 解析整个HTML格式不是一个好方法。

I am stuck and do not know what to do. 我被困住了,不知道该怎么办。 I kept on researching the entire afternoon and still failed in finding a solution. 我整个下午一直在研究,但仍未能找到解决方案。

All I want is to be able to authenticate through my mobile app while still using the same controllers. 我想要的是能够通过我的移动应用程序进行身份验证,同时仍然使用相同的控制器。

EDIT: Workaround 编辑:解决方法

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);
    }
}

Managed to make it work by conditionally adding Basic Authentication to the authenticate configuration. 通过有条件地将基本身份验证添加到身份验证配置来管理以使其工作。

However, this is not the perfect solution as it certainly has pitfalls. 然而,这不是一个完美的解决方案,因为它肯定有陷阱。

This will only work under the assumptions that: 这只能在以下假设下工作:

  1. Referring to this post: CakePHP will do a priority based on the order of authentication schemes. 参考这篇文章:CakePHP将根据身份验证方案的顺序执行优先级。 Since the Form Auth came before the Basic Auth, the Basic Auth will not execute if the Form Auth is successful. 由于Form Auth在Basic Auth之前,如果Form Auth成功,Basic Auth将不会执行。

    CakePHP 2.1 - As a web application and REST service with Authentication CakePHP 2.1 - 作为具有身份验证的Web应用程序和REST服务

  2. Normally, web users will not visit URL with the file extension of json, so the user will be redirected to the user login page using Form Authentication. 通常,Web用户不会访问具有json文件扩展名的URL,因此将使用表单身份验证将用户重定向到用户登录页面。

  3. Once the user is authenticated through Form Authentication, the Basic Authentication won't pop up even if the user will indirectly visit URL ending with .json using AJAX. 通过表单身份验证对用户进行身份验证后,即使用户使用AJAX间接访问以.json结尾的URL,也不会弹出基本身份验证。

Is there any better way? 有没有更好的方法?

you can do this by using basic authentication .for web you have to use form authentication and for REST API you have to use basic authentication .and you can use both at a time.i have implemented it already below is the working example. 您可以通过使用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