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

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

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

2回答

1160閲覧

mysql パスワードを1件ずつ発行してUPDATEしたい

yoto009

総合スコア9

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

1クリップ

投稿2020/03/02 07:19

編集2020/03/11 02:30

前提・実現したいこと

お世話になっております。

パスワードを持たないユーザーを取得して1件ずつパスワードを発行してUPDATEしたいです。
普通にUPDATEすると全く同じパスワードで反映されてしまうのでこれを1件ずつ別々の文字列のパスワードを反映したいです。

初歩的な部分かもしれないのですがお知恵をお貸しいただけますと大変助かります。
よろしくお願い致しますm(_ _)m

※下記のusersテーブルでパスワードを持っていないuser_id毎に違うパスワードを発行したい

user_iduser_pwuser_name
1ユーザー1
2ユーザー2
3ユーザー3
4ユーザー4
5ユーザー5

⬇現在の状態

user_iduser_pwuser_name
112345678ユーザー1
212345678ユーザー2
312345678ユーザー3
412345678ユーザー4
512345678ユーザー5

⬇理想の形

user_iduser_pwuser_name
112345678ユーザー1
21234abcdユーザー2
3abcd1234ユーザー3
45678abcdユーザー4
5abcdefghユーザー5

該当のソースコード

php

1# パスワード発行用 2$num = 8; 3$ar1 = range('a','z'); 4$ar2 = range('A','Z'); 5$ar3 = range('0','9'); 6$ar_all = array_merge($ar1,$ar2, $ar3); 7shuffle($ar_all); 8$pass = substr(implode($ar_all), 0, $num); 9 10 11# パスワードを持っていないユーザーを取得してパスワード発行 12$sql = ' 13 UPDATE users 14 SET pass = :pass 15 WHERE user_id = :user_id 16'; 17$prepare = $dbn->prepare($sql); 18$prepare->bindValue(':pass', $pass); 19$prepare->bindValue(':user_id', ''); 20$prepare->execute();

追記

これでランダム文字列をhash化して初期値の設定はできました。

php

1foreach($user as $user_id) { 2 $pass = substr(bin2hex(random_bytes($num)), 0, $num); 3 $hash = password_hash($pass, PASSWORD_BCRYPT); 4 $sql = ' 5 UPDATE users 6 SET user_pw = :user_pw 7 WHERE user_id = :user_id 8 '; 9 $prepare = $dbn->prepare($sql); 10 $prepare->bindValue(':user_pw', $hash); 11 $prepare->bindValue(':user_id', $user_id); 12 $prepare->execute(); 13}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/03/02 07:21

> 違うパスワード とくに法則性とかいらないのですよね?
yoto009

2020/03/02 07:23

はい、法則性とかはいらないです。 ランダムに6桁で設定できればって感じです。
guest

回答2

0

これ、実務で使用しているものですよね?

一般的なパスワード再設定の方法を模倣するのが良いです。
パスワード設定用(初期化用)の画面のURL + token を送付し、ユーザの手でパスワードを設定させてください。

質問にある方向性は、設計も実装もひどすぎます。
セキュアな設計/コーディングを基礎から学ぶことをおすすめします。

投稿2020/03/02 10:02

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoto009

2020/03/02 10:08

>設計も実装もひどすぎます。セキュアな設計/コーディングを基礎から学ぶことをおすすめします。 基礎から見直します。ご指摘ありがとうございます!
退会済みユーザー

退会済みユーザー

2020/03/02 10:16 編集

そうしてください。 フレームワーク等の実装を参考にすると良いです。 また、どうしてもパスワードの初期値としてランダム文字列を使用するのであれば、最低限8桁できれば10桁以上を使用し、 暗号論的に安全とされている生成方法を取るのが必須です。 random_bytes() を使用しておけばとりあえず安全です。
guest

0

ベストアンサー

「1件ずつ発行してUPDATEしたい」と要件にあるように、パスワード未設定のユーザーをSELECTし、ループして1件ずつ指定するしかないかと思います。
もし「ランダムでも同じパスワードは避ける」のであれば再帰処理を行う必要がありますが、ユーザーが違うのであれば何かで被っても問題は起きにくいかと思います。
気になるのであれば桁数を8桁とか10桁とか増やしたり英数字、大文字小文字、記号を混ぜるなどルールを増やした方が良いです。

あと、そもそもですが、パスワードをそのまま平文で持っておくのはセキュリティ的によろしくないので、必ず暗号文にしてください。

投稿2020/03/02 07:31

編集2020/03/02 08:12
m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kyoya0819

2020/03/02 08:08 編集

暗号化ではなくハッシュ化では? ->この場合勝手に指定しちゃうので、暗号化でもいいのか、、 忘れてください。
m.ts10806

2020/03/02 08:11

対義語の「暗号文」のほうが良かったですかね。 ひとまず「そのまま入れちゃダメ」と伝われば良いので。
yoto009

2020/03/02 08:30 編集

なるほど、SELECTしたのをループさせる必要があるんですね… $sql = 'SELECT * FROM `users` WHERE `user_pw` = :user_pw'; $prepare = $dbn->prepare($sql); $prepare->bindValue(':user_pw', ''); $prepare->execute(); $result = $prepare->fetch(PDO::FETCH_ASSOC); このように取得したのをwhile文なりでループさせるということですよね? >パスワードをそのまま平文で持っておくのはセキュリティ的によろしくないので、必ず暗号文にしてください。 とても重要な部分ですよね、ご指摘ありがとうございます。注意します!
m.ts10806

2020/03/02 08:49

はい。ただ、空を条件に指定したいのであればバインドの必要はないですし、is nullなども考慮してあげてください。
yoto009

2020/03/02 10:00 編集

すみません、ループさせて1件ずつ処理するということは理解できたのですが ループさせたものをどのようにUPDATEに反映させればよいかわからずです ループのさせ方もおかしいのでしょうか?理解力がなくすみませんm(_ _)m $results = $prepare->fetch(PDO::FETCH_ASSOC); foreach($results as $result){ $data = $result; } これをこのようにするのでしょうか? $stmt = $this->pdo->prepare(' UPDATE `users` SET `user_pw` = :pass WHERE `user_id` = :user_id '); $stmt->bindValue(':pass', $pass); $stmt->bindValue(':user_id', $data); $stmt->execute();
m.ts10806

2020/03/02 09:57

あの、なぜパスワードを条件に?同じパスワードがあったら書き変わってしまいますよ。 use_idなど一意な情報を条件にしましょう。
yoto009

2020/03/02 10:07

教えていただいた内容で続けてみます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問