CodeIgniter 4中SSO OAuth2跳转后代码无法继续执行问题
SSO登录重定向问题排查与修复
我的SSO登录基础功能正常,但点击登录后无法跳转到管理员角色对应的默认页面。排查后怀疑是header跳转相关问题,因为跳转到authUrl后后续代码停止执行。
原问题代码
public function loginsso(){ $session = session(); $model = new \App\Models\UserModel(); $provider = new Keycloak([ 'authServerUrl' => 'https://sso.example.com', 'realm' => 'test', 'clientId' => 'sensor', 'clientSecret' => 'sensor', 'redirectUri' => 'sensor' ]); if ($this->request->getGet('code') === null) { $authUrl = $provider->getAuthorizationUrl(); $session->set('oauth2state', $provider->getState()); $oauth=$session->get('oauth2state'); header('Location: ' . $authUrl); // Tidak ada pernyataan 'return' di sini, membiarkan eksekusi berlanjut } elseif ($this->request->getGesst('code') !== null) { $token = $provider->getAccessToken('authorization_code', [ 'code' => $_GET['code']]); $user = $provider->getResourceOwner($token); $where2 = ['niplama' => $user->getNip()]; $status = $model->cek_login($where2)->getRow(); $user = $provider->getResourceOwner($token); $logout_url = $provider->getLogoutUrl(); $d = $model->get_pegawai_by_id($user->getNip()); $lvl = $model->get_lvl($user->getNip()); //echo $user->getUsername(); echo $lvl; if($d){ $session = session(); $session->set('user_id', $d['id']); $session->set('role', $d['role']); $session->set('username', $user->getUsername()); $session->set('niplama', $user->getNip()); if ($d['role'] === 'admin') { return redirect()->to('/inputrpd'); } elseif ($d['role'] === 'operator') { return redirect()->to('/chartview'); } }else{ "tidak terdaftar di database"; } } else { // Handle ketika 'code' tidak ditemukan echo "Parameter 'code' tidak ditemukan di URL."; } }
问题点分析
- header跳转后未终止脚本:执行
header('Location: ' . $authUrl);后没有立即终止代码,后续逻辑仍会运行,可能导致流程混乱。 - 方法名拼写错误:
$this->request->getGesst('code')是笔误,正确应为getGet,直接导致登录回调分支无法触发。 - 角色分支未覆盖全:如果用户角色既不是
admin也不是operator,没有对应的处理逻辑,会出现无响应。 - 错误提示未输出:未注册用户的提示仅为字符串,没有
echo语句,用户看不到错误信息。
修复后的代码
public function loginsso(){ $session = session(); $model = new \App\Models\UserModel(); $provider = new Keycloak([ 'authServerUrl' => 'https://sso.example.com', 'realm' => 'test', 'clientId' => 'sensor', 'clientSecret' => 'sensor', 'redirectUri' => 'sensor' ]); if ($this->request->getGet('code') === null) { $authUrl = $provider->getAuthorizationUrl(); $session->set('oauth2state', $provider->getState()); // 跳转后立即终止脚本,避免后续代码干扰 header('Location: ' . $authUrl); exit; } elseif ($this->request->getGet('code') !== null) { $token = $provider->getAccessToken('authorization_code', [ 'code' => $_GET['code'] ]); $user = $provider->getResourceOwner($token); $where2 = ['niplama' => $user->getNip()]; $status = $model->cek_login($where2)->getRow(); $logout_url = $provider->getLogoutUrl(); $d = $model->get_pegawai_by_id($user->getNip()); $lvl = $model->get_lvl($user->getNip()); if($d){ $session->set('user_id', $d['id']); $session->set('role', $d['role']); $session->set('username', $user->getUsername()); $session->set('niplama', $user->getNip()); if ($d['role'] === 'admin') { return redirect()->to('/inputrpd'); } elseif ($d['role'] === 'operator') { return redirect()->to('/chartview'); } else { // 处理其他角色的情况 echo "当前角色无对应访问页面"; exit; } } else { echo "用户未在系统中注册"; exit; } } else { echo "URL中缺少'code'参数"; exit; } }
关键修复说明
- 在
header跳转后添加exit;,确保脚本立即终止,避免后续代码执行。 - 修正
getGesst为getGet,保证登录回调分支能正常触发。 - 补充非
admin/operator角色的处理逻辑,避免无响应情况。 - 给未注册用户的提示添加
echo输出,让用户能看到错误信息。
内容的提问来源于stack exchange,提问作者corei54590
相关产品推荐
相关产品推荐

