简体   繁体   English

Slim PHP Framework中间件自定义URL过滤器

[英]Slim PHP Framework middleware custom URL filter

I am creating API using Slim Framework. 我正在使用Slim Framework创建API。 I need to filter requests required authentication and route them to the specific auth handler. 我需要过滤请求所需的身份验证,并将其路由到特定的身份验证处理程序。 Or it would be better to say that I need to filter URI that don't require auth (public information). 或者最好说我需要过滤不需要auth(公共信息)的URI。

I have created following middleware skileton 我创建了以下中间件Skileton

class TokenAuth extends \Slim\Middleware {
    private $auth;
    public function __construct($userEmail,$accesToken,$appSecret) {

    }

    /**
     * Deny Access
     *
     */
    public function deny_access() {
        $res = $this->app->response();
        $res->status(401);
    }


    public function authenticate($token) {
        ....
    }

    /**
     * Call
     *
     */
    public function call() {
        //Get the token sent from jquery

        $tokenAuth = $app->request->headers->get('Authorization');

        //Check if our token is valid
        if ($this->authenticate($tokenAuth)) {
        ....
        } else {
            $this->deny_access();
        }
    }

}

In this case I cannot access any URI without token, how to solve this problem, allowing access to the public resources. 在这种情况下,如果没有令牌,我将无法访问任何URI,如何解决此问题,从而允许访问公共资源。
I would be grateful for any help. 我将不胜感激。 Thx in advance. 提前谢谢。

A common strategy here is to implement a firewall with rules. 这里的常见策略是使用规则实施防火墙。

A very simple firewall might ignore public assets (ie, anything ending in .jpg, .png, .css, .js, etc.). 一个非常简单的防火墙可能会忽略公共资产(即以.jpg,.png,.css,.js等结尾的任何内容)。 Rules are commonly simply regular expressions. 规则通常只是正则表达式。

An example firewall configuration might look like (note the order the rules are applied are also important). 示例防火墙配置可能看起来像(注意应用规则的顺序也很重要)。

firewalls:
    # Public assets, anyone can see
    assets:
        expression: \.(js|css)$
        auth: false

    # Everything exception login requires auth
    secure:
        expression: ^(?!login$)
        auth: true

    # Everything else gets through
    public:
        expression: ^/
        auth: false

Have you framework parse the definition and iterate over the rules. 您是否有框架来解析定义并遍历规则。 From there, you can decide how to handle the routing. 从那里,您可以决定如何处理路由。

You have mainly two ways of doing it : 主要有两种方法可以执行此操作:

Global middleware 全球中间件

One way consist in adding an OAuth middleware to your API so you can check if user is authenticated or not and setup a flag, then inside each route you can do a simple check if user is authenticated or not. 一种方法是将OAuth中间件添加到您的API中,以便您可以检查用户是否通过身份验证并设置标志,然后在每个路由内可以简单检查用户是否通过身份验证。

<?php
$app = new \Slim\Slim();
$app-authenticated = false;
$app->add(new MyOAuthMiddleware());

Then your MyOAuthMiddleware : 然后您的MyOAuthMiddleware:

<?php
 class MyOAuthMiddleware extends \Slim\Middleware {
  public function call() {
   //Do your OAUTH check stuff here
   $this->app-authenticated = true;
  }
}

Now you can check in all your routes : 现在,您可以检查所有路线:

<?php
$app->get('/hello/:name', function ($name) {
   $app = \Slim\Slim::getInstance();
   if($app->authenticated === true){
    echo "Hello, $name";
   } else {
    echo "You need to login";
   }
});

Specific route middleware 特定路由中间件

You can follow Slim documentation and choose to add your Middleware directly on each declaration : 您可以遵循Slim 文档,并选择直接在每个声明上添加中间件:

<?php
$authenticateForRole = function ( $role = 'member' ) {
    return function () use ( $role ) {
        $user = User::fetchFromDatabaseSomehow();
        if ( $user->belongsToRole($role) === false ) {
            $app = \Slim\Slim::getInstance();
            $app->flash('error', 'Login required');
            $app->redirect('/login');
        }
    };
};
$app = new \Slim\Slim();
$app->get('/foo', $authenticateForRole('admin'), function () {
    //Display admin control panel
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM