From 074ba0d93e9a0dc87cceb96963dbada5fced31b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=80=99=E5=AD=A6=E6=9D=B0?= Date: Fri, 5 Jan 2018 15:42:41 +0800 Subject: [PATCH] oauth access tokens --- src/PdAuth/Middleware/Authenticate.php | 87 ++++++++++++++++++++++++++ src/PdAuth/{Client.php => OAuth.php} | 27 ++++++-- src/PdAuth/PdAuthServiceProvider.php | 35 ++++++++++- 3 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 src/PdAuth/Middleware/Authenticate.php rename src/PdAuth/{Client.php => OAuth.php} (62%) diff --git a/src/PdAuth/Middleware/Authenticate.php b/src/PdAuth/Middleware/Authenticate.php new file mode 100644 index 0000000..4176955 --- /dev/null +++ b/src/PdAuth/Middleware/Authenticate.php @@ -0,0 +1,87 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string|null $guard + * @return mixed + */ + public function handle($request, Closure $next, $guard = null) + { + //oauth 回调 + $code = $request->input('pd_code'); + if ($code) { + $token = app('pd.auth')->getAccessToken($code); + if (isset($token['access_token'])) { + setcookie(self::CookieName, $token['access_token'], strtotime($token['expire_at'])); + + $qs = $request->getQueryString(); + $params = explode('&', $qs); + $qs = '?'; + foreach ($params as $k => $v) { + if (Str::startsWith($v, 'pd_code=')) { + continue; + } + $qs .= $v . '&'; + } + abort(302, '', [ + 'Location' => $request->getSchemeAndHttpHost() . $request->getBaseUrl() . $request->getPathInfo() . $qs, + ]); + } + } + + //登录状态检测 + if ($this->auth->guard($guard)->guest()) { + return redirect(app('pd.auth')->connect($request->getUri())); + } + + //权限检测 + $path = $request->path(); + $privileges = config('pdauth.roles_privileges'); + $user = $request->user(); + $match = []; + foreach ($user['roles'] as $role) { + if (array_key_exists($role['role']['role'], $privileges)) { + $match = $privileges[$role['role']['role']]; + } + } + + if (in_array($path, $match)) { + return $next($request); + } + + abort(403, '无权访问,请联系管理员授权'); + return $next($request); + } +} diff --git a/src/PdAuth/Client.php b/src/PdAuth/OAuth.php similarity index 62% rename from src/PdAuth/Client.php rename to src/PdAuth/OAuth.php index cd45af7..536292a 100644 --- a/src/PdAuth/Client.php +++ b/src/PdAuth/OAuth.php @@ -2,7 +2,7 @@ namespace PdAuth; -class Client +class OAuth { protected $host; @@ -27,17 +27,36 @@ class Client return $this->host . "/connect?appid={$this->id}&redirect=$redirect"; } + public function getAccessToken($code) + { + $resp = $this->get("$this->host/api/access_token?id={$this->id}&secret={$this->secret}&code={$code}"); + if ($resp['code'] == 0) { + return $resp['data']; + } + return null; + } + /** * 根据用户token获取用户信息 * @param $username * @param $token * @return array|null */ - public function getUserInfo($username, $token) + public function getUserInfo($token) { $token = urlencode($token); - $resp = $this->get("$this->host/api/{$username}/info?access_token=$token"); - if( $resp['code'] == 0 ){ + $resp = $this->get("$this->host/api/user_info?access_token=$token"); + if ($resp['code'] == 0) { + return $resp['data']; + } + return null; + } + + public function getGroups($token) + { + $token = urlencode($token); + $resp = $this->get("$this->host/api/{$this->id}/groups?access_token=$token"); + if ($resp['code'] == 0) { return $resp['data']; } return null; diff --git a/src/PdAuth/PdAuthServiceProvider.php b/src/PdAuth/PdAuthServiceProvider.php index 4e8e0c3..dfbb79f 100644 --- a/src/PdAuth/PdAuthServiceProvider.php +++ b/src/PdAuth/PdAuthServiceProvider.php @@ -2,16 +2,49 @@ namespace PdAuth; +use Illuminate\Contracts\Encryption\DecryptException; +use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; +use PdAuth\Middleware\Authenticate; class PdAuthServiceProvider extends ServiceProvider { + /** + * Boot the authentication services for the application. + * + * @return void + */ + public function boot() + { + // Here you may define how you wish users to be authenticated for your Lumen + // application. The callback which receives the incoming request instance + // should return either a User instance or null. You're free to obtain + // the User instance via an API token or any other method necessary. + + $this->app['auth']->viaRequest('api', function (Request $request) { + + $token = $request->cookie(Authenticate::CookieName); + + if ($token) { + try { + $user = app('pd.auth')->getUserInfo($token); + if ($user) { + return $user; + } + } catch (DecryptException $ex) { + return null; + } + } + return null; + }); + } + public function register() { $this->app->singleton('pd.auth', function () { $this->app->configure('pdauth'); - return new Client(config('pdauth')); + return new OAuth(config('pdauth')); }); }