webman 获取用户ip的建议

0

~~ webman中
$request->getRemoteIp()取的是真实tcp连接 ip
如有代理 nginx 就不友好,不管头怎么设置真实ip都是nginx的真实ip
自己实现获取用户ip虽不难,但是,建议加入到 request 类里面
$request->header('X-Real-IP')~~

已邀请:

walkor

赞同来自: 张先生

代码看着没什么问题。


不过鉴权更适合用中间件,大部分框架都是用中间件来鉴权的,这样可以控制业务流程流转,比如在鉴权失败时统一跳转到登录页面,如果在你说的那个控制器初始化函数里做就很难做到。


另外用 $request->user_id$控制器->user_id 更合理一些。$request类似用户输入的变量,包含请求数据,用户鉴权数据。控制器是公共的方法,只根据输入变量$request来处理业务,控制器自身不应该存储用户状态数据。控制器是单例的多请求共享的,也就是说上一个请求设置的$控制器->user_id,下一个请求没有将$控制器->user_id重置直接使用将得到错误的用户数据。

walkor

赞同来自:

更新下 webman-framework 到1.0.2或者后续的更高版本,使用 $request->getRealIp(); 方法获取真实ip。

张先生

赞同来自:

首先说明我为什么需要初始化函数,在我们的业务中我想,在中间件鉴权,鉴权后给控制器赋值当前用户的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);
}
}
}
```

要回复问题请先登录注册