Skip to content

Instantly share code, notes, and snippets.

@kurozumi
Last active October 1, 2015 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurozumi/05f9f4b174890615621f to your computer and use it in GitHub Desktop.
Save kurozumi/05f9f4b174890615621f to your computer and use it in GitHub Desktop.
【CodeIgniter】Digest(ダイジェスト)認証ライブラリ
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Digest_auth
{
private $realm = "Restricted Area";
private $username = "username";
private $password = "password";
private $logged_in_key = 'logged_in';
public function __construct(array $config = array())
{
$this->CI = & get_instance();
$this->CI->load->library('session');
if(count($config))
{
$this->initialize($config);
}
}
public function initialize($config = array())
{
foreach ($config as $key => $val)
{
if (isset($this->$key))
{
$method = 'set_'.$key;
if (method_exists($this, $method))
{
$this->$method($val);
}
else
{
$this->$key = $val;
}
}
}
return $this;
}
private function set_username($username)
{
$this->username = $username;
}
private function set_password($password)
{
$this->password = $password;
}
public function get_username()
{
return $this->username;
}
private function get_password()
{
return $this->password;
}
public function login()
{
$logged_in = $this->CI->session->userdata($this->logged_in_key);
if ($logged_in !== true)
{
if ($this->auth())
{
$this->CI->session->set_userdata($this->logged_in_key, true);
} else
{
header('HTTP/1.1 401 Authorization Required');
header('WWW-Authenticate: Digest realm="' . $this->realm . '", qop="auth", nonce="' . uniqid() . '", opaque="' . md5($this->realm) . '"');
header('Content-type: text/html; charset='.mb_internal_encoding());
die("Please enter a valid username and password");
}
}
}
private function auth()
{
if (!$this->CI->input->server('PHP_AUTH_DIGEST'))
{
return false;
} else
{
// PHP_AUTH_DIGEST 変数を精査する
$data = $this->http_digest_parse($this->CI->input->server('PHP_AUTH_DIGEST'));
if (!$data || $data['username'] != $this->get_username())
return false;
// 有効なレスポンスを生成する
$hash_1 = md5(sprintf("%s:%s:%s", $data['username'], $this->realm, $this->get_password()));
$hash_2 = md5(sprintf("%s:%s", $this->CI->input->server('REQUEST_METHOD'), $data['uri']));
$valid_response = md5(sprintf("%s:%s:%s:%s:%s:%s", $hash_1, $data['nonce'], $data['nc'], $data['cnonce'], $data['qop'], $hash_2));
if ($data['response'] != $valid_response)
return false;
return true;
}
}
// http auth ヘッダをパースする関数
private function http_digest_parse($txt)
{
// データが失われている場合への対応
$needed_parts = array(
'nonce' => true,
'nc' => true,
'cnonce' => true,
'qop' => true,
'username' => true,
'uri' => true,
'response' => true
);
$data = array();
$keys = implode('|', array_keys($needed_parts));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
}
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Welcome extends CI_Controller {
public function index()
{
$this->load->view('welcome_message');
}
public function digest_auth()
{
$this->load->library('Digest_auth', array(
'username' => 'username',
'password' => 'password'
));
$this->digest_auth->login();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment