根据 codeigniter 中的用户角色重定向到页面
Redirect to a page based on user roles in codeigniter
我正在使用 codeigniter 进行用户登录验证。
登录脚本效果很好。我的问题是,当用户登录时,我希望根据他的用户角色将用户重定向到一个页面
角色如下subscriber, admin, client, 邮递员
User_model.php如下
class User_model extends CI_Model {
public $status;
public $roles;
function __construct(){
// Call the Model constructor
parent::__construct();
$this->status = $this->config->item('status');
$this->roles = $this->config->item('roles');
}
public function insertUser($d)
{
$string = array(
'firstname'=>$d['firstname'],
'lastname'=>$d['lastname'],
'phonenumber'=>$d['phonenumber'],
'email'=>$d['email'],
'roles'=>$this->roles[1],
'status'=>$this->status[1],
'password'=> '',
'last_login'=> '',
'created_at'=> '',
'updated_at'=> ''
);
$q = $this->db->insert_string('users',$string);
$this->db->query($q);
return $this->db->insert_id();
}
public function isDuplicate($email)
{
$this->db->get_where('users', array('email' => $email), 1);
return $this->db->affected_rows() > 0 ? TRUE : FALSE;
}
public function insertToken($user_id)
{
$token = substr(sha1(rand()), 0, 30);
$date = date('Y-m-d');
$string = array(
'token'=> $token,
'user_id'=>$user_id,
'created'=>$date
);
$query = $this->db->insert_string('tokens',$string);
$this->db->query($query);
return $token . $user_id;
}
public function isTokenValid($token)
{
$tkn = substr($token,0,30);
$uid = substr($token,30);
$q = $this->db->get_where('tokens', array(
'tokens.token' => $tkn,
'tokens.user_id' => $uid), 1);
if($this->db->affected_rows() > 0){
$row = $q->row();
$created = $row->created;
$createdTS = strtotime($created);
$today = date('Y-m-d');
$todayTS = strtotime($today);
if($createdTS != $todayTS){
return false;
}
$user_info = $this->getUserInfo($row->user_id);
return $user_info;
}else{
return false;
}
}
public function getUserInfo($id)
{
$q = $this->db->get_where('users', array('id' => $id), 1);
if($this->db->affected_rows() > 0){
$row = $q->row();
return $row;
}else{
error_log('no user found getUserInfo('.$id.')');
return false;
}
}
public function updateUserInfo($post)
{
$data = array(
'password' => $post['password'],
'last_login' => date('Y-m-d h:i:s A'),
'created_at' => date('Y-m-d h:i:s A'),
'updated_at' => date('Y-m-d h:i:s A'),
'status' => $this->status[1]
);
$this->db->where('id', $post['user_id']);
$this->db->update('users', $data);
$success = $this->db->affected_rows();
if(!$success){
error_log('Unable to updateUserInfo('.$post['user_id'].')');
return false;
}
$user_info = $this->getUserInfo($post['user_id']);
return $user_info;
}
public function checkLogin($post)
{
$this->load->library('password');
$this->db->select('*');
$this->db->where('email', $post['email']);
$query = $this->db->get('users');
$userInfo = $query->row();
if(!$this->password->validate_password($post['password'], $userInfo->password)){
error_log('Unsuccessful login attempt('.$post['email'].')');
return false;
}
$this->updateLoginTime($userInfo->id);
unset($userInfo->password);
return $userInfo;
}
}
控制器主要代码如下
defined('BASEPATH') OR exit('No direct script access allowed');
class Main extends CI_Controller {
public $status;
public $roles;
function __construct(){
parent::__construct();
$this->load->model('User_model', 'user_model', TRUE);
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
$this->status = $this->config->item('status');
$this->roles = $this->config->item('roles');
}
public function index()
{
if(empty($this->session->userdata['email'])){
redirect(site_url().'main/login/');
}
/*front page*/
$data = $this->session->userdata;
$this->load->view('header');
$this->load->view('index', $data);
$this->load->view('footer');
}
public function login()
{
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if($this->form_validation->run() == FALSE) {
$this->load->view('header');
$this->load->view('login');
$this->load->view('footer');
}else{
$post = $this->input->post();
$clean = $this->security->xss_clean($post);
$userInfo = $this->user_model->checkLogin($clean);
if(!$userInfo){
$this->session->set_flashdata('flash_message', 'The login was unsucessful');
redirect(site_url().'main/login');
}
foreach($userInfo as $key=>$val){
$this->session->set_userdata($key, $val);
}
redirect(site_url().'main/');
}
}
public function logout()
{
$this->session->sess_destroy();
redirect(site_url().'main/login/');
}
}
这个答案可能有误,因为它需要一些假设。
假设:
- 每个用户只有一个"role"
$userInfo->role
的值是一个字符串
- 您要将授权用户发送到的控制器是
main
main
控制器的方法命名与 "role" 相同,例如
'subscriber'、'admin'、'client'、'postman'
如果以上任何一项为假,则此答案无效。
这是我建议的解决方案。我会在这段代码之后对其进行评论。
public function login()
{
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if($this->form_validation->run())
{
$post = $this->input->post();
//$clean = $this->security->xss_clean($post);
$userInfo = $this->user_model->checkLogin($post);
if( ! $userInfo)
{
$this->session->set_flashdata('flash_message', 'The login was unsucessful');
redirect('main/login');
}
$this->session->set_userdata($userInfo);
redirect('main/'.$userInfo->roles);
}
$this->load->view('header');
$this->load->view('login');
$this->load->view('footer');
}
您可能想知道我为什么要重新排列所有内容。好吧,主要是因为它消除了 else
与 if
一起使用的需要。代码越少越好 - 对吧?
调用 redirect()
结束脚本执行 意味着 redirect
之后的任何代码都不会 运行。因为 if($this->form_validation->run()){
代码块以对 redirect
的调用结束,这就是该函数结束的地方。所以,你不需要 else
。如果验证失败执行直接进入视图加载代码。
redirect
的语法错误。 redirect()
将根据您的配置文件值构建 URL。 (docs here) 因此,请确保 $config['base_url']
设置正确。
您的代码
redirect(site_url().'main/');
应该写成
redirect('main/');
你可能注意到我注释掉了这行
$clean = $this->security->xss_clean($post);
大多数开发人员会争辩说 XSS 预防应该在输出上进行,而不是在输入上进行。 (比你想知道的 XSS 预防更多 HERE。)
由于输入数据被用于 select 数据库记录,因此值似乎已转义,并且您不存储输入没有危险。使用 xss_clean()
是资源密集型的,在这种情况下没有用。
我删除了以下循环
foreach ($userInfo as $key => $val)
{
$this->session->set_userdata($key, $val);
}
并将其更改为
$this->session->set_userdata($userInfo);
如果您查看 set_userdata()
的代码,您会发现它几乎使用了您创建的完全相同的代码。 (代码在第 785 行附近的 /system/core/Session/Session.php
中。)保持 DRY 并使用框架的工具集。 set_userdata()
将接受关联数组并执行您需要完成的操作。
因为 $userInfo->roles
的值是一个字符串,它与您要将它们重定向到此调用的方法的名称匹配,应该可以解决问题。
redirect('main/'.$userInfo->roles);
如果 main
不是正确的控制器,则在上面进行更改。如果方法名称与角色值不匹配,则需要额外的代码。
希望这很清楚并且有所帮助。
我正在使用 codeigniter 进行用户登录验证。
登录脚本效果很好。我的问题是,当用户登录时,我希望根据他的用户角色将用户重定向到一个页面
角色如下subscriber, admin, client, 邮递员
User_model.php如下
class User_model extends CI_Model {
public $status;
public $roles;
function __construct(){
// Call the Model constructor
parent::__construct();
$this->status = $this->config->item('status');
$this->roles = $this->config->item('roles');
}
public function insertUser($d)
{
$string = array(
'firstname'=>$d['firstname'],
'lastname'=>$d['lastname'],
'phonenumber'=>$d['phonenumber'],
'email'=>$d['email'],
'roles'=>$this->roles[1],
'status'=>$this->status[1],
'password'=> '',
'last_login'=> '',
'created_at'=> '',
'updated_at'=> ''
);
$q = $this->db->insert_string('users',$string);
$this->db->query($q);
return $this->db->insert_id();
}
public function isDuplicate($email)
{
$this->db->get_where('users', array('email' => $email), 1);
return $this->db->affected_rows() > 0 ? TRUE : FALSE;
}
public function insertToken($user_id)
{
$token = substr(sha1(rand()), 0, 30);
$date = date('Y-m-d');
$string = array(
'token'=> $token,
'user_id'=>$user_id,
'created'=>$date
);
$query = $this->db->insert_string('tokens',$string);
$this->db->query($query);
return $token . $user_id;
}
public function isTokenValid($token)
{
$tkn = substr($token,0,30);
$uid = substr($token,30);
$q = $this->db->get_where('tokens', array(
'tokens.token' => $tkn,
'tokens.user_id' => $uid), 1);
if($this->db->affected_rows() > 0){
$row = $q->row();
$created = $row->created;
$createdTS = strtotime($created);
$today = date('Y-m-d');
$todayTS = strtotime($today);
if($createdTS != $todayTS){
return false;
}
$user_info = $this->getUserInfo($row->user_id);
return $user_info;
}else{
return false;
}
}
public function getUserInfo($id)
{
$q = $this->db->get_where('users', array('id' => $id), 1);
if($this->db->affected_rows() > 0){
$row = $q->row();
return $row;
}else{
error_log('no user found getUserInfo('.$id.')');
return false;
}
}
public function updateUserInfo($post)
{
$data = array(
'password' => $post['password'],
'last_login' => date('Y-m-d h:i:s A'),
'created_at' => date('Y-m-d h:i:s A'),
'updated_at' => date('Y-m-d h:i:s A'),
'status' => $this->status[1]
);
$this->db->where('id', $post['user_id']);
$this->db->update('users', $data);
$success = $this->db->affected_rows();
if(!$success){
error_log('Unable to updateUserInfo('.$post['user_id'].')');
return false;
}
$user_info = $this->getUserInfo($post['user_id']);
return $user_info;
}
public function checkLogin($post)
{
$this->load->library('password');
$this->db->select('*');
$this->db->where('email', $post['email']);
$query = $this->db->get('users');
$userInfo = $query->row();
if(!$this->password->validate_password($post['password'], $userInfo->password)){
error_log('Unsuccessful login attempt('.$post['email'].')');
return false;
}
$this->updateLoginTime($userInfo->id);
unset($userInfo->password);
return $userInfo;
}
}
控制器主要代码如下
defined('BASEPATH') OR exit('No direct script access allowed');
class Main extends CI_Controller {
public $status;
public $roles;
function __construct(){
parent::__construct();
$this->load->model('User_model', 'user_model', TRUE);
$this->load->library('form_validation');
$this->form_validation->set_error_delimiters('<div class="error">', '</div>');
$this->status = $this->config->item('status');
$this->roles = $this->config->item('roles');
}
public function index()
{
if(empty($this->session->userdata['email'])){
redirect(site_url().'main/login/');
}
/*front page*/
$data = $this->session->userdata;
$this->load->view('header');
$this->load->view('index', $data);
$this->load->view('footer');
}
public function login()
{
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if($this->form_validation->run() == FALSE) {
$this->load->view('header');
$this->load->view('login');
$this->load->view('footer');
}else{
$post = $this->input->post();
$clean = $this->security->xss_clean($post);
$userInfo = $this->user_model->checkLogin($clean);
if(!$userInfo){
$this->session->set_flashdata('flash_message', 'The login was unsucessful');
redirect(site_url().'main/login');
}
foreach($userInfo as $key=>$val){
$this->session->set_userdata($key, $val);
}
redirect(site_url().'main/');
}
}
public function logout()
{
$this->session->sess_destroy();
redirect(site_url().'main/login/');
}
}
这个答案可能有误,因为它需要一些假设。
假设:
- 每个用户只有一个"role"
$userInfo->role
的值是一个字符串- 您要将授权用户发送到的控制器是
main
main
控制器的方法命名与 "role" 相同,例如 'subscriber'、'admin'、'client'、'postman'
如果以上任何一项为假,则此答案无效。
这是我建议的解决方案。我会在这段代码之后对其进行评论。
public function login()
{
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');
if($this->form_validation->run())
{
$post = $this->input->post();
//$clean = $this->security->xss_clean($post);
$userInfo = $this->user_model->checkLogin($post);
if( ! $userInfo)
{
$this->session->set_flashdata('flash_message', 'The login was unsucessful');
redirect('main/login');
}
$this->session->set_userdata($userInfo);
redirect('main/'.$userInfo->roles);
}
$this->load->view('header');
$this->load->view('login');
$this->load->view('footer');
}
您可能想知道我为什么要重新排列所有内容。好吧,主要是因为它消除了 else
与 if
一起使用的需要。代码越少越好 - 对吧?
调用 redirect()
结束脚本执行 意味着 redirect
之后的任何代码都不会 运行。因为 if($this->form_validation->run()){
代码块以对 redirect
的调用结束,这就是该函数结束的地方。所以,你不需要 else
。如果验证失败执行直接进入视图加载代码。
redirect
的语法错误。 redirect()
将根据您的配置文件值构建 URL。 (docs here) 因此,请确保 $config['base_url']
设置正确。
您的代码
redirect(site_url().'main/');
应该写成
redirect('main/');
你可能注意到我注释掉了这行
$clean = $this->security->xss_clean($post);
大多数开发人员会争辩说 XSS 预防应该在输出上进行,而不是在输入上进行。 (比你想知道的 XSS 预防更多 HERE。)
由于输入数据被用于 select 数据库记录,因此值似乎已转义,并且您不存储输入没有危险。使用 xss_clean()
是资源密集型的,在这种情况下没有用。
我删除了以下循环
foreach ($userInfo as $key => $val)
{
$this->session->set_userdata($key, $val);
}
并将其更改为
$this->session->set_userdata($userInfo);
如果您查看 set_userdata()
的代码,您会发现它几乎使用了您创建的完全相同的代码。 (代码在第 785 行附近的 /system/core/Session/Session.php
中。)保持 DRY 并使用框架的工具集。 set_userdata()
将接受关联数组并执行您需要完成的操作。
因为 $userInfo->roles
的值是一个字符串,它与您要将它们重定向到此调用的方法的名称匹配,应该可以解决问题。
redirect('main/'.$userInfo->roles);
如果 main
不是正确的控制器,则在上面进行更改。如果方法名称与角色值不匹配,则需要额外的代码。
希望这很清楚并且有所帮助。