Posted By

mladoux on 07/09/12


Tagged

security authentication codeigniter


Versions (?)

mAuth


 / Published in: PHP
 

URL: http://markladoux.com

A simple user management library. It makes no attempt at handling sessions or cookies, I'll leave that part up to you. It's just a drop in that will allow you to create users, update passwords, and make sure that user supplied information is correct. Should easily integrate into any application setting that you might be able to think of. The library is completely database agnostic, as it makes use of the dbforge library to automatically generate databases on first use. As long as CodeIgniter supports the database, this library will work with it.

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3.  * mAuth Authentication Library
  4.  *
  5.  * Simple authentication library for CodeIgniter 2. This class does not
  6.  * make any attempts at handling access control, so you will need another
  7.  * library or helper to do that for you. This library also doesn't perform any
  8.  * cookie or session management, that should be left up to your individual
  9.  * application. This is a simple drop in user creation and verification library.
  10.  *
  11.  * @author Mark LaDoux <[email protected]>
  12.  * @version 20120708
  13.  * @copyright Copyright (c) 2012, Mark LaDoux
  14.  */
  15.  
  16. class mAuth
  17. {
  18. /**
  19.   * CodeIgniter Object
  20.   *
  21.   * @access protected
  22.   * @since 20120708
  23.   * @var object
  24.   */
  25. protected $ci;
  26.  
  27. /**
  28.   * Database table to use
  29.   *
  30.   * @access protected
  31.   * @since 20120708
  32.   * @var string
  33.   */
  34. protected $table;
  35.  
  36. /**
  37.   * Number of iterations to process hash with
  38.   *
  39.   * @access protected
  40.   * @since 20120708
  41.   * @var int
  42.   */
  43. protected $rounds;
  44.  
  45. /**
  46.   * Class Constructor
  47.   *
  48.   * Initializes the class for first use!
  49.   *
  50.   * @access public
  51.   * @since 20120708
  52.   * @return void
  53.   */
  54. public function __construct()
  55. {
  56. // get CodeIgniter instance
  57. $this->ci =& get_instance();
  58.  
  59. // retrieve settings
  60. $this->ci->config->load('mauth');
  61. $this->table = $this->ci->config->item('mauth_table');
  62. $this->rounds = $this->ci->config->item('mauth_rounds');
  63.  
  64. // verify secure settings for $this->rounds
  65. if($this->rounds < 4 || $this->rounds > 32) $this->rounds = 8;
  66.  
  67. // load dependancies
  68. $this->ci->load->database();
  69.  
  70. // Install database if necessary
  71. if(! $this->ci->db->table_exists($this->table))
  72. {
  73. $this->_install();
  74. }
  75. }
  76.  
  77. /**
  78.   * Install database table
  79.   *
  80.   * @access protected
  81.   * @since 20120708
  82.   * @return void
  83.   */
  84.  
  85. protected function _install()
  86. {
  87. // load dbforge
  88. $this->ci->load->dbforge();
  89.  
  90. // prepare fields
  91. $fields = array(
  92. 'user_id' => array(
  93. 'type' => 'INT',
  94. 'unsigned' => TRUE,
  95. 'auto_increment' => TRUE,
  96. ),
  97. 'username' => array(
  98. 'type' => 'VARCHAR',
  99. 'constraint' => '50',
  100. ),
  101. 'email' => array(
  102. 'type' => 'VARCHAR',
  103. 'constraint' => '255',
  104. ),
  105. 'password' => array(
  106. 'type' => 'CHAR',
  107. 'constraint' => '60',
  108. ),
  109. );
  110. $this->ci->dbforge->add_field($fields);
  111.  
  112. // configure indexes
  113. $this->ci->dbforge->add_key('user_id', TRUE);
  114. $this->ci->dbforge->add_key('username');
  115. $this->ci->dbforge->add_key('email');
  116.  
  117. // create table
  118. $this->ci->dbforge->create_table($this->table, TRUE);
  119. }
  120.  
  121. /**
  122.   * Generate password hash
  123.   *
  124.   * Generates a password hash using the bcrypt algorithm
  125.   *
  126.   * @access protected
  127.   * @since 20120708
  128.   * @param string $password plaintext password to hash
  129.   * @return string hashed password
  130.   */
  131. protected function _hash_pass($password)
  132. {
  133. // generate a salt
  134. $lowercase = str_shuffle('abcdefghijklmnopqrstuvwxyz');
  135. $uppercase = str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
  136. $other = str_shuffle('./');
  137. $legal_chars = str_shuffle($lowercase.$uppercase.$other);
  138. $salt = '';
  139.  
  140. for($i = 0; $i < 22; $i++)
  141. {
  142. $salt .= $legal_chars[mt_rand(0,63)];
  143. }
  144.  
  145. // format salt
  146. $salt = sprintf('$2a$%02d$', $this->rounds).str_shuffle($salt);
  147.  
  148. // return hash
  149. return crypt($password, $salt);
  150. }
  151.  
  152. /**
  153.   * Verify password hash
  154.   *
  155.   * Checks plaintext password against stored hash to see if it is valid
  156.   *
  157.   * @access protected
  158.   * @since 20120708
  159.   * @param string $password plaintext password to verify
  160.   * @param string $stored hash from database to check against
  161.   * @return bool
  162.   */
  163. protected function _verify_pass($password, $stored)
  164. {
  165. $check = (crypt($password, $stored) == $stored) ? TRUE : FALSE;
  166. return $check;
  167. }
  168.  
  169. /**
  170.   * Check if username is in use
  171.   *
  172.   * @access public
  173.   * @since 20120708
  174.   * @param string $username username to check
  175.   * @return bool
  176.   */
  177. public function check_user($username)
  178. {
  179. $this->ci->db->where('username', $username);
  180. $query = $this->ci->db->get($this->table);
  181.  
  182. // check if the username is in use
  183. if($query->num_rows() > 0)
  184. {
  185. // username is in use
  186. return TRUE;
  187. }
  188.  
  189. // username is not in use
  190. return FALSE;
  191. }
  192.  
  193. /**
  194.   * Check if email address is in use
  195.   *
  196.   * @access public
  197.   * @since 20120708
  198.   * @param string $email email address to check
  199.   * @return bool
  200.   */
  201. public function check_email($email)
  202. {
  203. $this->ci->db-where('email', $email);
  204. $query = $this->ci->db->get($this->table);
  205.  
  206. // check if email is in use
  207. if($query->num_rows() > 0)
  208. {
  209. // email is in use
  210. return TRUE;
  211. }
  212.  
  213. // email is not in use
  214. return FALSE;
  215. }
  216.  
  217. /**
  218.   * Create user
  219.   *
  220.   * @access public
  221.   * @since 20120708
  222.   * @param string $username username to set
  223.   * @param string $email email address to set
  224.   * @param string $password password to set
  225.   * @return bool
  226.   */
  227. public function create_user($username, $email, $password)
  228. {
  229. // check to make sure username is not taken
  230. if($this->check_username !== FALSE)
  231. {
  232. return FALSE;
  233. }
  234.  
  235. // check to make sure email address is not taken
  236. if($this->check_email !== FALSE)
  237. {
  238. return FALSE;
  239. }
  240.  
  241. // check to make sure email is valid
  242. if(! filter_var($email, FILTER_VALIDATE_EMAIL))
  243. {
  244. return FALSE;
  245. }
  246.  
  247. // prepare our password hash
  248. $hash = $this->_hash_pass($password);
  249.  
  250. // prepare user information
  251. $data = array(
  252. 'username' => $username,
  253. 'email' => $email,
  254. 'password' => $hash,
  255. );
  256.  
  257. // add user to the database
  258. $this->ci->db->insert($this->table, $data);
  259. return TRUE;
  260. }
  261.  
  262. /**
  263.   * Verify user
  264.   *
  265.   * This function is set up to verify a user with either a username or an
  266.   * email address, and will check for which you are using automatically so
  267.   * that you can set up your application to operate however you prefer.
  268.   *
  269.   * @access public
  270.   * @param string $user username or email address to verify
  271.   * @param string $password password for the user to verify
  272.   * @return bool
  273.   */
  274. public function verify_user($user, $password)
  275. {
  276. $valid = FALSE;
  277.  
  278. if(filter_var($user, FILTER_VALIDATE_EMAIL))
  279. {
  280. $this->ci->db->where('email', $user);
  281. }
  282. else
  283. {
  284. $this->ci->db->where('username', $user);
  285. }
  286. $query = $this->ci->db->get($this->table);
  287.  
  288. if($query->num_rows() > 0)
  289. {
  290. $row = $query->result();
  291. $valid = $this->_verify_pass($password, $row->password);
  292. }
  293.  
  294. return $valid;
  295. }
  296.  
  297. /**
  298.   * Change password
  299.   *
  300.   * This application is set up to change a password using the username
  301.   * or email address, and will check for which you are using automatically
  302.   * so that you can set up your application however you prefer.
  303.   *
  304.   * @access public
  305.   * @since 20120708
  306.   * @param string $user user to update password for
  307.   * @param string $password new password to set
  308.   * @return void
  309.   */
  310. public function change_password($user, $password)
  311. {
  312. // prepare hash
  313. $hash = $this->_hash_pass($password);
  314. $data = array('password' => $hash);
  315.  
  316. // prepare where statement
  317. if(filter_var($user, FILTER_VALIDATE_EMAIL))
  318. {
  319. $this->ci->db->where('email', $user);
  320. }
  321. else
  322. {
  323. $this->ci->db->where('username', $user);
  324. }
  325.  
  326. // update password
  327. $this->ci->db->update($this->table, $hash);
  328. }
  329.  
  330. /**
  331.   * Retrieve user info
  332.   *
  333.   * This function will retrieve user info using either an username or
  334.   * email address. It will check which you are using automatically so
  335.   * that you can set up your application to use whatever method you prefer.
  336.   * This function will also strip password information from the array, so
  337.   * that you don't have to worry about it accidentally getting out.
  338.   *
  339.   * @access public
  340.   * @param string $user username or email address to retrieve info for
  341.   * @return array
  342.   */
  343. public function user_info($user)
  344. {
  345. // retrieve data
  346. if(filter_var($user, FILTER_VALIDATE_EMAIL))
  347. {
  348. $this->ci->db->where('email', $user);
  349. }
  350. else
  351. {
  352. $this->ci->db->where('username', $user);
  353. }
  354. $query = $this->ci->db->get($this->table);
  355. $row = $query->result();
  356.  
  357. // prepare data
  358. $data = array(
  359. 'user_id' => $row->user_id,
  360. 'username' => $row->username,
  361. 'email' => $row->email,
  362. );
  363.  
  364. // return data for further processing
  365. return $data;
  366. }
  367.  
  368. /**
  369.   * Delete user
  370.   *
  371.   * This function will delete a user using either the username or the
  372.   * email address. It will check which you are using automatically, so that
  373.   * you can set up your application to use whichever that you prefer.
  374.   *
  375.   * @access public
  376.   * @param string $user username or email address of the user to delete.
  377.   * @return void
  378.   */
  379. public function delete_user($user)
  380. {
  381. if(filter_var($user, FILTER_VALIDATE_EMAIL))
  382. {
  383. $this->ci->db->where('email', $user);
  384. }
  385. else
  386. {
  387. $this->ci->db->where('username', $user);
  388. }
  389. $this->ci->db->delete($this->table);
  390. }
  391. }

Report this snippet  

You need to login to post a comment.