Written by Manabu Bannai

【CodeIgniter】MySQLの操作/パスワード暗号化の基礎

CodeIgniter PROGRAMMING

CodeIgniterでMySQL操作の基礎とパスワード暗号化の基礎をまとめました。MySQL操作の入門として、以下の記事をご覧いただくと理解が深まりやすいです。
【CodeIgniterの基礎】ビューの作成、複数ビューの読み込み設定

記事のもくじ

それではまとめていきます。

CodeIgniterの初期セットアップ

データベースを作成する

テーブル名:users
カラム数:4

mysql_db

CodeIgniterをDBに繋ぐ

以下の記事を参考にDBとCodeIgniterを接続してください。
» 【Codeigniterの基礎】DBから情報を読み込み、ビューに表示する方法

一点だけ注意点があります。今回は『mysql』ではなく、『’mysqli』を利用します。よって、DB情報は以下のように記述してください。

$db['default']['dbdriver'] = 'mysqli';

ちなみに、mysqliとは、mysqlがアップグレードしたものです。詳しく知りたい人はこちらをどうぞ。
» [Q&A] mysql mysqli 違いなど

CodeIgniterでDBに情報を挿入する

ユーザー情報をDBに送信するメソッドを作成する

新規作成ファイル:application/models/model_users.php


public  function insert_into_user(){
	$data = array(	//以下、2つのデータを取得して、$dataに紐づける
		"username" => "takashi",
		"password" => "testing_password"
	);
	$this->db->insert("users", $data);
}

ユーザー情報をDBに送信するメソッドを利用してみる

トップページにアクセスした際に、メソッドを実行します。
新規作成ファイル:application/controllers/main.php


public function index(){
	$this->load->model("model_users");
	$this->model_users->insert_into_user();
}

データベースに以下の情報が格納されていることがわかります。

username:takashi
password:testing_password

※このままだとページをリロードするたびに、DBに上記情報が格納されていきます。

ここでエラーがおきた場合は、databaseがオートロードされているか確認してください。

CodeIgniterでDBから情報を取得する

ユーザー情報をを取得するモデルを作成する

編集ファイル:application/models/model_users.php


public function get_user(){
	$query = $this->db->get("users");	//usersテーブルからすべての値を取得する
	return $query;
}

ユーザー情報をを取得するメソッドを作成する

編集ファイル:application/controllers/main.php
外部からのアクセスを遮断するために、privateファンクションを利用します。


private function get_user_data(){
	$this->load->model("model_users");	//model_usersのモデルを読み込む
	//model_usersのモデル内のget_user機能を使って、結果を$resultに紐づける
	$result = $this->model_users->get_user();
	return $result;
}

ユーザー情報をを取得する

編集ファイル:application/controllers/main.php


public function index(){
	$this->load->model("model_users");
	// $this->model_users->insert_into_user();
	
	//get_user_dataメソッドから取得した値を$dataに格納する
	$data["user_data"] = $this->get_user_data();

	//メインビューを表示する際に、$dataを渡す
	$this->load->view("main_view", $data);
}

次にmain_viewを作っていきます。

main_viewを作成する

新規作成ファイル:application/views/main_view.php

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>メインページ</title>

</head>
<body>

<div id="container">
	<h1>メインページ</h1>

	<?php
		var_dump($user_data);
	?>

</body>
</html>

main_view

表示されるクエリ結果を絞る

編集ファイル:application/models/model_users.php


public function get_user(){
	$query = $this->db->get("users");	//usersテーブルからすべての値を取得する
	return $query->result();
}

※result()とは
データベース内から引っ張れる情報のみを表示するメソッド。
» クエリ結果の生成 : CodeIgniter ユーザガイド 日本語版

表示されるクエリ結果をforeachで表示してみる

新規作成ファイル:application/views/main_view.php


username;
		echo "Your password is :" . $row->password;
	}

?>

以下のような画面が表示されます。

Your username is :takashiYour password is :testing_password

CodeIgniterでDB情報を編集(アップデート)する

ユーザーデータをアップデートするモデルを作成する

編集ファイル:application/models/model_users.php


public function user_update($data, $id){
	$this->db->where("id", $id);	//$idのデータを
	$this->db->update();		//アップデートする
}

ユーザー情報をアップデートするメソッドを作る

編集ファイル:application/controllers/main.php


private function update_user_data(){
	$data["username"] = "Mike";
	$data["password"] = "updated_password";

	$id = $this->get_user_data()->id;

	$this->load->model("model_users");	//model_usersのモデルをロードする
	$this->model_users->user_update($data, $id);	//特定の$idデータの情報をアップデートする
	}

アップデートしたユーザー情報を表示する

新規作成ファイル:application/controllers/main.php


public function index(){
	$this->load->model("model_users");

	$this->update_user_data();
	$data["user_data"] = $this->get_user_data();

	$this->load->view("main_view", $data);
}

しかし、このままだと、以下のエラーメッセージが表示されます。

A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: controllers/main.php

Line Number: 442
A Database Error Occurred
You must use the "set" method to update an entry.
Filename: /Applications/MAMP/htdocs/basicsite/models/model_users.php

A PHP Error was encountered
Severity: Warning
Message: Cannot modify header information - headers already sent by (output started at /Applications/MAMP/htdocs/basicsite/system/core/Exceptions.php:185)
Filename: core/Common.php

上記エラー解決のために、user_updateモデルを変更します。
編集ファイル:application/models/model_users.php


public function user_update($data, $id){
	$this->db->where("id", $id);	//$idのデータをアップデートする
	$this->db->update("users", $data);		//どこのテーブルのデータをアップデートするのか明確化する
}

update()クラスの詳細はドキュメントをご確認ください。
» Active Record クラス : CodeIgniter ユーザガイド 日本語版

この時点で実行すると、以下のエラーが表示されます。

A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: controllers/main.php

上記エラーを解決していきます。
編集ファイル:application/controllers/main.php


private function update_user_data(){
	$data["username"] = "Mike";
	$data["password"] = "updated_password";

	//$id = $this->get_user_data()->id;  ←すべての値を取得してしまっているのでエラーが発生している

	//get_user_dataメソッドで取得した値をrowに格納
	foreach($this->get_user_data() as $row){
		$id = $row->id;
	}

	$this->load->model("model_users");	//model_usersのモデルをロードする
	$this->model_users->user_update($data, $id);	//特定の$idデータの情報をアップデートする
}

CodeIgniterでDB内のパスワードを暗号化(ハッシュ)する

CodeIgniterにあるハッシュ機能の存在を確認する

編集ファイル:application/views/main_view.php

<?php
	echo (! function_exists("mcrypt_encrypt")) ? "No" : "Yes";
?>

Yesと表示されればOKです。

Encryptionファンクションを利用するためのセットアップ

編集ファイル:application/config/config.php

/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| If you use the Encryption class or the Session class you
| MUST set an encryption key.  See the user guide for info.
|
*/
// $config['encryption_key'] = '';
$config['encryption_key'] = 'nskajflnasklab flab8273yr82';

Encryptionファンクションをロードしてみる

編集ファイル:application/controllers/main.php

public function index(){
	$this->load->library("encrypt");
}

必要のないコードはコメントアウトしておきます。
画面をロードしてエラーが表示されなければOK。
※ロードしているだけなので、とくに画面に変化はおきません。

my_messageを定義してから、メッセージを暗号化してみる

編集ファイル:application/config/config.php

public function index(){
	$this->load->library("encrypt");
	$data["my_message"] = "こんにちは!";
	$data["my_encrypted_message"] = $this->encrypt->encode($data["my_message"]);
}

暗号化したメッセージを復元してみる

編集ファイル:application/views/main_view.php

<?php
	echo "あなたのメッセージは:" . "$my_message";
	echo "<br />";
	echo "暗号化されたあなたのメッセージは:" . "$my_encrypted_message";

暗号化されたメッセージをもとにもどしてみる

編集ファイル:application/controller/main.php

public function index(){
	$this->load->library("encrypt");
	$data["my_message"] = "こんにちは!";
	$data["my_encrypted_message"] = $this->encrypt->encode($data["my_message"]);
	$data["my_decoded_message"] = $this->encrypt->decode($data["my_encrypted_message"]);

暗号化されたメッセージを復元して、表示してみる

編集ファイル:application/views/main_view.php

<?php
	echo "あなたのメッセージは:" . "$my_message";
	echo "<br />";
	echo "暗号化されたあなたのメッセージは:" . "$my_encrypted_message";
	echo "<br />";
	echo "復元されたあなたのメッセージは:" . "$my_decoded_message";

セキュアハッシュアルゴリズムをつかう

編集ファイル:application/controller/main.php


public function index(){
	$this->load->library("encrypt");
	$data["my_message"] = "こんにちは!";
	$data["my_encrypted_message"] = $this->encrypt->encode($data["my_message"]);
	$data["my_decoded_message"] = $this->encrypt->decode($data["my_encrypted_message"]);

	$data["sha1_message"] = sha1($data["my_message"]);

セキュアハッシュアルゴリズムを使ったメッセージを表示してみる

編集ファイル:application/views/main_view.php

<?php
	echo "あなたのメッセージは:" . "$my_message";
	echo "<br />";
	echo "暗号化されたあなたのメッセージは:" . "$my_encrypted_message";
	echo "<br />";
	echo "復元されたあなたのメッセージは:" . "$my_decoded_message";
	echo "<br />";
	echo "セキュアハッシュアルゴリズムを使ったあなたのメッセージは:" . "$sha1_message";

MD5で暗号化をしてみる

編集ファイル:application/controller/main.php

public function index(){
	$this->load->library("encrypt");
	$data["my_message"] = "こんにちは!";
	$data["my_encrypted_message"] = $this->encrypt->encode($data["my_message"]);
	$data["my_decoded_message"] = $this->encrypt->decode($data["my_encrypted_message"]);

	$data["sha1_message"] = sha1($data["my_message"]);
	$data["md5_message"] = md5($data["my_message"]);

MD5で暗号化したメッセージを表示してみる

編集ファイル:application/views/main_view.php

<?php
	echo "あなたのメッセージは:" . "$my_message";
	echo "<br />";
	echo "暗号化されたあなたのメッセージは:" . "$my_encrypted_message";
	echo "<br />";
	echo "復元されたあなたのメッセージは:" . "$my_decoded_message";
	echo "<br />";
	echo "セキュアハッシュアルゴリズムを使ったあなたのメッセージは:" . "$sha1_message";
	echo "<br />";
	echo "MD5を使ったあなたのメッセージは:" . "$md5_message";

パスワードを暗号化しつつDBに保存する機能を実装する

insert_into_user のモデルを変更する

編集ファイル:application/models/model_users.php

public  function insert_into_user(){
	$data = array(	//以下、2つのデータを取得して、$dataに紐づける
		// "username" => "Taro",
		"username" => "Mike",
		"password" => $enc_password
	);
	$this->db->insert("users", $data);
}

次に、上記で利用している、$enc_passwordを作成していきます。

パスワード暗号化のモデルを作成する

編集ファイル:application/models/model_users.php

public function encrypt_password($password){
	$salt_key = "^&*(Ithink&*(Youcant^&*figureout^&*(this&*(KEY";
	$password = $password . $salt_key; //パスワードをソルトキーをミックスする
	$enc_password = sha1($password);
	return $enc_password;
}

encrypt_passwordのモデルが完成しました。
encrypt_passwordモデルを使って、insert_into_userモデルを書き換えていきます。

encrypt_passwordモデルを使って、insert_into_userモデルを書き換える

編集ファイル:application/models/model_users.php

public  function insert_into_user(){
	// encrypt_passwordモデルを使って、insert_into_userモデルを書き換える処理
	$enc_password = $this->encrypt_password("ThisisaTestPasswrod");

	$data = array(	//以下、2つのデータを取得して、$dataに紐づける
		// "username" => "Mike",
		"username" => "Taro",
		"password" => $enc_password
	);
	$this->db->insert("users", $data);
}

上記プログラムでは、password” => $enc_password と書かれています。
encrypt_passwordモデルがない場合だと、DBには “ThisisaTestPasswrod” という情報が保存されます。
しかし、当プログラムではencrypt_passwordモデルが存在するため、DBへの保存前に、 “ThisisaTestPasswrod” が暗号化されます。

insert_into_userモデルを実行するコントローラーをつくる

編集ファイル:application/controllers/main.php

public function index(){
	$this->load->model("model_users");
	$this->load->library("encrypt");

	$this->model_users->insert_into_user();
	$this->load->view("main_view");

コントローラーが完成したので、ビューをすこし書き換える

編集ファイル:application/views/main_view.php
以前に書いたプログラムは必要ないので、以下のように書き換えます。


echo "暗号化されたパスワードのDB挿入が完了しました";

この時点でトップページをリロードしてみます。
すると、暗号化されたパスワードがDBに保存されていることがわかります。

ユーザー情報を表示してみる

編集ファイル:application/models/model_users.php
get_userモデルを以下のように変更します。

public function get_user(){
	// ThisisaTestPasswrodをパスワードとしているユーザー情報の取得
	$this->db->where("password", "ThisisaTestPasswrod");
	$query = $this->db->get("users");	//usersテーブルからすべての値を取得する
	return $query->result();
}

get_userモデルを実行するコントローラーを作成する

編集ファイル:application/controllers/main.php

public function index(){
	$this->load->model("model_users");
	$this->load->library("encrypt");

	$data["user_data"] = $this->get_user_data();
	$this->load->view("main_view", $data);
}

取得した情報をvar_dumpで表示してみる

編集ファイル:application/views/main_view.php

var_dump($user_data);

ここで画面更新をすると、以下のように表示されます。
array(0) { }

なぜでしょうか?
get_userモデルでは、ThisisaTestPasswrodをパスワードとするユーザー情報の取得を定義しました。

$this->db->where("password", "ThisisaTestPasswrod");

しかし、現状のDBに保存されているパスワードはすでに暗号化されています。
元のパスワードは “ThisisaTestPasswrod” でしたが、すでに元のパスワードではユーザー情報を検索することができないことがわかります。

次に、暗号化されたパスワードとユーザー情報を照合できるプログラムを作っていきます。

暗号化されたあとのパスワードを照合できるモデルをつくっていく

編集ファイル:application/models/model_users.php

public function get_user(){
	// 新たに$enc_passwrodを定義して、encrypt_passwordモデルが実行されたあとのパスワード情報を取得する
	$enc_passwrod = $this->encrypt_password("ThisisaTestPasswrod");

	// $this->db->where("password", "ThisisaTestPasswrod");
	$this->db->where("password", $enc_passwrod);

	$query = $this->db->get("users");	//usersテーブルからすべての値を取得する
	return $query->result();
}

ここで画面をリロードすると、以下の情報を取得することができます。

array(1) {
  [0]=>
  object(stdClass)#21 (4) {
    ["id"]=>
    string(2) "4"
    ["username"]=>
    string(4) "Taro"
    ["password"]=>
    string(40) "dc89e074cbb249ca713aa366c3a8088ee2e9cf79"
  }
}

以上となります。
参考になりましたら幸いです( ◜◡‾)