質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • PHP

    20357questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • ログイン

    118questions

    ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

  • ハッシュ

    37questions

    ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

  • パスワード

    32questions

    パスワードは主に情報にアクセスする際に扱われます。主に、アクセス可能なユーザーを限定する手段として使われます。

【php】パスワードのハッシュ化を追加実装したい

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 297

DaisukeMori

score 62

現在ツイッターもどき(自作SNS)を練習で作成中でございまして、
新規会員登録から、ログインの実装までは行けたのですが、
パスワードがハッシュ化できておりません。

今のコードを利用しつつ、下記を実装する効率的な方法を教えていただきたいと思い質問しました。
①まずパスワードのハッシュ化(新規会員登録側)
②ハッシュ化したパスワード(データベース)とログインフォームに入力したパスワードの整合

また、その他ここはこうした方がいいなどあれば、ぜひとも教えていただければと思います。

【新規会員登録】
ファイル名:index.php
<?php

// 変数の初期化
$page_flag = 0;
$clean = array();
$error = array();

// サニタイズ
if( !empty($_POST) ) {
foreach( $_POST as $key => $value ) {
$clean[$key] = htmlspecialchars( $value, ENT_QUOTES);

}

// 入力確認画面
if( !empty($clean['btn_confirm']) ) {
$name = $_POST['your_name'];
$account = $_POST['account'];
$email = $_POST['email'];
$pass1 = $_POST['pass1'];

$error = validation($clean);

//エラーがなかったら
if(empty($error)){
$page_flag = 1;

session_start();
$_SESSION['page'] = true;
}

// 結果表示
} elseif( !empty($clean['btn_submit']) ) {
session_start();

if( !empty($_SESSION['page']) && $_SESSION['page'] === true ) {

$name = $_POST['your_name'];
$account = $_POST['account'];
$email = $_POST['email'];
$pass1 = $_POST['pass1'];

// データベース接続設定
$user = 'root';
$pass = '';
// データベースに接続
$dsn = 'mysql:host=localhost;dbname=my_sns;charset=utf8';
$dbh = new PDO($dsn, $user, $pass);
// データの追加
$sql = 'INSERT INTO member(your_name, account, email, password) VALUES(?,?,?,?)';
$stmt = $dbh -> prepare($sql);
$data[]=$name;
$data[]=$account;
$data[]=$email;
$data[]=$pass1;
$stmt -> execute($data);
// 切断
$dbh = null;

$page_flag = 2;
}else{
$page_flag = 0;
}
}

function validation($data) {
$error = array();
// 氏名のバリデーション
if(empty($data['your_name']) ) {
$error[] = "「お名前」は必ず入力してください。";
}elseif(20 < mb_strlen($data['your_name']) ){
$error[] = "「お名前」は20文字以内で入力してください。";
}

// ユーザーネームのバリデーション
if(empty($data['account']) ) {
$error[] = "「ユーザーネーム」は必ず入力してください。";
}elseif(20 < mb_strlen($data['account']) ){
$error[] = "「ユーザーネーム」は20文字以内で入力してください。";
}

// メールアドレスのバリデーション
if(empty($data['email']) ) {
$error[] = "「メールアドレス」は必ず入力してください。";
}elseif(!preg_match('/^[0-9a-z_.\/?-]+@([0-9a-z-]+\.)+[0-9a-z-]+$/',$data['email']) ){
$error[] = "「メールアドレス」は正しい形式で入力してください。";
}

// パズワードのバリデーション
if(empty($data['pass1']) ) {
$error[] = "「パスワード」は必ず入力してください。";
}
if($data['pass1'] != $data['pass2']){
$error[] = "「パスワード」が一致しません。";
}
return $error;
}

// var_dump($_POST);
?>

<!DOCTYPE>
<html lang="ja">
<head>
<title>新規会員登録</title>
<link rel="stylesheet" type="text/css" href="css/stylesheet.css">
</head>
<body>
<h1>新規会員登録</h1>

<!-- 確認画面 -->
<?php if( $page_flag === 1 ): ?>
<form method="post" action="">
<div class="element_wrap">
<label>お名前</label>
<p><?=$name; ?></p>
</div>
<div class="element_wrap">
<label>ユーザーネーム</label>
<p><?=$account; ?></p>
</div>
<div class="element_wrap">
<label>メールアドレス</label>
<p><?=$email; ?></p>
</div>
<div class="element_wrap">
<label>パスワード</label>
<p>*************</p>
</div>

<input type="submit" name="btn_back" value="修正">
<input type="submit" name="btn_submit" value="送信">
<input type="hidden" name="your_name" value="<?=$name; ?>">
<input type="hidden" name="account" value="<?=$account; ?>">
<input type="hidden" name="email" value="<?=$email; ?>">
<input type="hidden" name="pass1" value="<?=$pass1; ?>">
</form>
<br>
<p><strong style="color:red;">注意!</strong><br>
修正を押されますとパスワードは<br>
消えてしまいますので<br>
お手数ですが、再度ご入力をお願いします。</p>

<!-- 完了画面 -->
<?php elseif( $page_flag === 2 ): ?>

<p><?=$name; ?> 様<br>
ご登録完了しました。<br>
本登録が完了されましたので、<br>
ログインしてください。</p>

<div class="top_btn">
<a href ="http://localhost/mysns/login.php">ログイン画面へ</a>
</div>

<?php else: ?>

<!-- 初期画面 ~エラー表示~ -->
<?php if(!empty($error)): ?>
<ul class="error_list">
<?php foreach($error as $value): ?>
<li><?=$value; ?></li>
<?php endforeach; ?>
</ul>    
<?php endif; ?>

<!-- 初期画面 -->
<form method="post" action="">
<div class="element_wrap">
<label>お名前</label>
<input type="text" name="your_name" value="<?php if(!empty($_POST['your_name'])){echo $_POST['your_name'];} ?>">
</div>
<div class="element_wrap">
<label>ユーザーネーム</label>
<input type="text" name="account" value="<?php if(!empty($_POST['account'])){echo $_POST['account'];} ?>">
</div>
<div class="element_wrap">
<label>メールアドレス</label>
<input type="text" name="email" value="<?php if(!empty($_POST['email'])){echo $_POST['email'];} ?>">
</div>
<div class="element_wrap">
<label>パスワード</label>
<input type="password" name="pass1" value="<?php if(!empty($_POST['pass1'])){echo $_POST['pass1'];} ?>">
</div>
<div class="element_wrap">
<label>パスワード(確認)</label>
<input type="password" name="pass2" value="<?php if(!empty($_POST['pass2'])){echo $_POST['pass2'];} ?>">
</div>
<input type="submit" name="btn_confirm" value="入力内容を確認する">
</form>

<?php endif; ?>

</body>
</html>

【ログインフォーム】
ファイル名:login.php

<?php
session_start();

if( !empty($_POST['btn_confirm']) ) {

$account = $_POST['account'];
$pass = $_POST['pass'];

$error = array();

if(empty($account) ) {
$error[] = '「ユーザーネーム」は必ず入力してください。';
}
if(empty($pass) ) {
$error[] = '「パスワード」は必ず入力してください。';
}

if(!empty($account) && !empty($pass)){
$dsn='mysql:dbname=my_sns;host=localhost;charset=utf8';
$user='root';
$password='';
$dbh=new PDO($dsn,$user,$password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
$stmt=$dbh->prepare('SELECT * FROM member WHERE account=? AND password=?');
$data[]=$account;
$data[]=$pass;
$stmt->execute($data);

$dbh=null;

$rec=$stmt->fetch(PDO::FETCH_ASSOC);

if($rec==false){
echo 'ユーザーネームとパスワードが一致しません。';
}else{
header('Location:main.php');
exit();
}
}

}

?>

<!DOCTYPE>
<html lang="ja">
<head>
<title>ログイン</title>
<link rel="stylesheet" type="text/css" href="css/stylesheet.css">
</head>
<body>
<h1>ログイン</h1>

<!-- 初期画面 ~エラー表示~ -->
<?php if(!empty($error)): ?>
<ul class="error_list">
<?php foreach($error as $value): ?>
<li><?=$value; ?></li>
<?php endforeach; ?>
</ul>    
<?php endif; ?>

<form method="post" action="">
<div class="element_wrap">
<label>ユーザーネーム</label>
<input type="text" name="account" value="<?php if(!empty($_POST['account'])){echo $_POST['account'];} ?>">
</div>
<div class="element_wrap">
<label>パスワード</label>
<input type="password" name="pass" value="">
</div>

<input type="submit" name="btn_confirm" value="ログイン">
</form>
<a href="index.php">新規登録のまだの方はこちら</a>
</body>
</html>

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Kosuke_Shibuya

    2017/12/10 18:03

    https://teratail.com/help/question-tips#questionTips3-5-1 ここを読んでソースコードはシンタックスをs使って投稿してください。

    キャンセル

回答 2

checkベストアンサー

+1

パスワードのハッシュかについては、こちらに

PHPでログイン機能を実装するチュートリアル #1

// サニタイズ
if( !empty($_POST) ) {
  foreach( $_POST as $key => $value ) {
    $clean[$key] = htmlspecialchars( $value, ENT_QUOTES);
  } 
}


htmlspecialchars の使うべき場所が間違っています。
このコードだと、パスワードに < や > が入っていると正しく認証されませんよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-2

文字列のハッシュ化できました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    20357questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • ログイン

    118questions

    ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

  • ハッシュ

    37questions

    ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

  • パスワード

    32questions

    パスワードは主に情報にアクセスする際に扱われます。主に、アクセス可能なユーザーを限定する手段として使われます。