~~ webman中 $request->getRemoteIp()取的是真实tcp连接 ip 如有代理 nginx 就不友好,不管头怎么设置真实ip都是nginx的真实ip 自己实现获取用户ip虽不难,但是,建议加入到 request 类里面 $request->header('X-Real-IP')~~
更新下 webman-framework 到1.0.2或者后续的更高版本,使用 $request->getRealIp(); 方法获取真实ip。
$request->getRealIp();
还有一个建议,就是在控制器里面添加一个初始化方法,如果存在此方法,每个请求进来都会调用一下,此方法。
首先说明我为什么需要初始化函数,在我们的业务中我想,在中间件鉴权,鉴权后给控制器赋值当前用户的id及信息,当然,这里也可以赋值给request 对象的属性,但是我们习惯在 控制器里面$this->user_id,所以想在控制器每个请求进来就初始化的时候赋值用户id,但是初始化要在中间件后,下面是我修改的框架源代码,大家帮忙看看,有没有什么bug。
protected static function getCallback($app, $call, $args = null, $with_global_middleware = true) { $args = $args === null ? null : \array_values($args); $middleware = Middleware::getMiddleware($app, $with_global_middleware); if ($middleware) { $callback = array_reduce($middleware, function ($carry, $pipe) { return function ($request) use ($carry, $pipe) { return $pipe($request, $carry); }; }, function ($request) use ($call, $args) { self::_initialize($request); //在调用控制器回调前 调用初始化函数 if ($args === null) { $response = $call($request); } else { $response = $call($request, ...$args); } if (\is_scalar($response) || null === $response) { $response = new Response(200, [], $response); } return $response; }); } else { self::_initialize($request); //没有中间件的时候 if ($args === null) { $callback = $call; } else { $callback = function ($request) use ($call, $args) { return $call($request, ...$args); }; } } return $callback; }
``` /** * 控制器初始化 * @param string $request */ private static function _initialize($request) { if ($request->controller) { $controller_obj = static::$_container->get($request->controller); if (method_exists($controller_obj, '_initialize')) { $_initialize = [$controller_obj, '_initialize']; $_initialize($request); } } } ```
代码看着没什么问题。
不过鉴权更适合用中间件,大部分框架都是用中间件来鉴权的,这样可以控制业务流程流转,比如在鉴权失败时统一跳转到登录页面,如果在你说的那个控制器初始化函数里做就很难做到。
另外用 $request->user_id 比 $控制器->user_id 更合理一些。$request类似用户输入的变量,包含请求数据,用户鉴权数据。控制器是公共的方法,只根据输入变量$request来处理业务,控制器自身不应该存储用户状态数据。控制器是单例的多请求共享的,也就是说上一个请求设置的$控制器->user_id,下一个请求没有将$控制器->user_id重置直接使用将得到错误的用户数据。
$request->user_id
$控制器->user_id
$request
你说的我也明白,我的意思是,鉴权还是在中间件里面做,但是每个请求通过中间件后,在调用控制器方法前,调用一下控制器对象的特定方法(比如_initialize)。我们需要在这里做一些事情。比如清除一些数据,比如修改当前对象的一些值。可能只是我们有这个需求,cv代码的时候改动少。
更新下 webman-framework 到1.0.2或者后续的更高版本,使用
$request->getRealIp();
方法获取真实ip。还有一个建议,就是在控制器里面添加一个初始化方法,如果存在此方法,每个请求进来都会调用一下,此方法。
首先说明我为什么需要初始化函数,在我们的业务中我想,在中间件鉴权,鉴权后给控制器赋值当前用户的id及信息,当然,这里也可以赋值给request 对象的属性,但是我们习惯在 控制器里面$this->user_id,所以想在控制器每个请求进来就初始化的时候赋值用户id,但是初始化要在中间件后,下面是我修改的框架源代码,大家帮忙看看,有没有什么bug。
代码看着没什么问题。
不过鉴权更适合用中间件,大部分框架都是用中间件来鉴权的,这样可以控制业务流程流转,比如在鉴权失败时统一跳转到登录页面,如果在你说的那个控制器初始化函数里做就很难做到。
另外用
$request->user_id
比$控制器->user_id
更合理一些。$request
类似用户输入的变量,包含请求数据,用户鉴权数据。控制器是公共的方法,只根据输入变量$request
来处理业务,控制器自身不应该存储用户状态数据。控制器是单例的多请求共享的,也就是说上一个请求设置的$控制器->user_id
,下一个请求没有将$控制器->user_id
重置直接使用将得到错误的用户数据。你说的我也明白,我的意思是,鉴权还是在中间件里面做,但是每个请求通过中间件后,在调用控制器方法前,调用一下控制器对象的特定方法(比如_initialize)。我们需要在这里做一些事情。比如清除一些数据,比如修改当前对象的一些值。可能只是我们有这个需求,cv代码的时候改动少。