PHP中的高级授权和API

时间:2014-06-19 22:34:48

标签: php api

我想要实现的是让我的应用程序使用自己的API。更具体地说,我正在将架构从HMVC改为:

CLIENTS
    MODEL
        model files
    CONTROLLERS
        API.php
             -option to consume API directly as JSON
        Clients.php 
             - consumes data directly from the API
             - exactly the same as if it had called it from the MODEL
     VIEW

控制器直接从“API”部分获取数据 - 但我避免了两个主要障碍:

a)将来自API控制器的JSON编码数据传递给Controller(只是为了节省编码/解码它的次要开销)

b)更重要的是,不必在每个请求上检查访问令牌,以确保允许应用程序访问信息。

我有以下情况:

  1. 用户登录系统并希望使用API​​ - 他们发送有效的访问令牌

  2. 用户已登录系统 - 导航至API页面但未提供访问令牌,因此应将其重定向回该部分/ 404页面的控制器。

  3. 用户未登录我们的系统但拥有授权令牌,因此可以使用该API。

  4. 用户登录但未提供INCORRECT访问令牌,因此应收到无效的令牌消息。

  5. 我最终得到的解决方案效果很好,但似乎非常“意大利面条”代码!

    我已经扩展了授权(Ion_Auth)类,如下所示:

    class Authentication extends Ion_auth {
    
        public $application = false;
    
    }
    

    然后在我所有的控制器中

    $this->authentication->application = true;
    

    __construct

    最后在 API控制器中,我有:

    private $application = false;
    
    public function __construct()
       {
        $this->token = $this->input->get_post('token');
            parent::__construct();
    
            if($this->authentication->application == true){
    
                $this->application = true;
            }
    
                    //API should have a token set before anything can happen, this is for every request
                    if($this->token){
                        //Check that the token is valid
                        if (!$this->checkToken($this->token)){
                            $this->error('Token did not match');
                        }
                        //all clear if we get to here - token matched
    
    
                    }else{ //no token was found
    
                        //ok so we have no token - is the user logged in? If not then they are trying to use the API but haven't set a token in the request.
                        if (!$this->authentication->logged_in()){
                            $this->error('No Token was sent');
                        }else{
    
                            //user is logged in and might have gone to the page by mistake 
                            if(!$this->application){
                              echo "you shouldn't be here"; //this will be replaced with the redirect
                                exit;                                
                            }
    
                        }
    
                    } 
    
                    //all cases passed and the application can continue - however we have a flag of $this->application set now which will let us decide whether to just 'return' data as array / object OR (if false i.e. from API) then we json encode the data for consumption.
    
      }
    

    有一个功能:

    private function sendIt($data){
        if($this->application){
            return $data;
        }else{
            $this->output
                ->set_content_type('application/json');
                echo json_encode($data);
            exit;
        }
    
    }
    

    用于代替'return'以确保应用程序使用的数据以正确的格式使用,而API数据则采用JSON编码。

    用法:

    return $this->sendIt($clients);
    

    这个功能正如我所说,但它似乎不是很简洁。任何人都可以提供任何关于我如何正确执行此操作的建议,即符合上述所有规则而无需在每个控制器中设置变量?

    为清楚起见,我的文件夹结构如下:

    CLIENTS
        MODELS
        CONTROLLERS
            - Client
            - Api
        VIEWS
    JOBS
        MODELS
        CONTROLLERS
            - Jobs
            - Api
        VIEWS
    

    导航到site/clients的想法导致数据直接从API页面中提取而不需要访问令牌 - 但导航到'site / clients / api'会导致重定向(如果已登录) )如果已登录或未登录但传递了错误的令牌,则出现“无令牌”错误(如果未登录)或“错误令牌”错误。

    我真的被困在这里,拥有600个控制器,所以我不想不止这么做!

    最终要点

    我不能使用类名和URL来识别直接调用API,因为我不想在每个不同的页面上设置规则,我当前的解决方案至少提供了一个剪切和粘贴解决方案!

    修改

    感谢halfer - 我无法在评论中回答,所以这里有一个编辑来解决他的评论并希望为他们增加清晰度

    $this->authentication->application 
    

    只是查看请求是否为内部的触发器 - 它应该是'$is_application'

    authentication module(在所有控制器之前运行)中设置为false的布尔值

    false。{/ p>中设置为authentication module

    那么,如果应用程序中的controller为模块调用了API控制器(我在自己的应用程序中使用它),则会将此标志设置为true

    我用这个'标志'做两件事:

    set the output type -> 'return' if the application requests the info or 'JSON' if it is requested directly from the API page.
    
    Decide if an access token for the API needs to be present - if the application requests info from the API internally then no access token is required - if it is accessed directly from the URL then an access token is required.
    

    我已经修改了顶部的结构,以更好地解释模块的布局。

    导航到site/clients会自动在控制器中查找clients.php文件。

    导航到site/clients/api导航到客户端控制器文件夹 - 然后导航到api文件。

    sites/clients处的控制器消费者所有数据并将数据发送到site/clients/api - 然后api与数据库进行通信。

    我也将把它变成一个单独的功能,这样控制器看起来就不那么混乱了 - 但这就是魔法将要发生的地方 - 这只是在玩!而且这只是在玩!

    希望增加清晰度,并再次感谢任何花时间达到这一点的人!!!!

0 个答案:

没有答案