(ところで、これはすべてPHPでコード化されています。以下の関数からわかると思います)
パスワードを保存するとき、私はあなたがパスワードをハッシュしなければならないことを知っています。実際、これが私のコードです(十分に安全かどうか教えてください):
function hash($password)
{
return password_hash($password, PASSWORD_BCRYPT, array(
'cost' => 12,
'salt' => bin2hex(openssl_random_pseudo_bytes(16))
));
}
ただし、実際の質問は、適切なログインシステムを使用しているかどうかです。次の段落では、現在のシステムがどのように機能するかを説明します。問題がないか、変更する必要があるかどうかを誰かに教えてください。あなたがそうすることを想定している適切な方法は、クライアントがクッキーまたは何かに保存するトークンを使用することであると聞いたことがあります。
ユーザーが最初にサイトにアクセスし、アカウントが登録されると、ログインするように求められます。彼らが提供したパスワードを使用して、私はそれをハッシュし、それがデータベース内のパスワードとpassword_verify()で一致するかどうかを確認します。検証されたら、彼らは正しいログイン情報を持っているので、$ _ SESSIONにユーザー名とパスワード(サーバー側に保存されていることを理解しています)を設定して認証を行い、ユーザーが[Remember me]ボタンをチェックした場合はユーザー名を保存しますCookieのパスワード(ハッシュ化されていない)は1週間で期限切れになります。
アカウント情報などのページを読み込むなど、新しいアクションを実行しようとするたびに、コードの上部で関数が実行され、認証されているかどうかを返し、認証されているかどうかを確認します。 $ _SESSIONでユーザー名とパスワードを確認し、再度認証します。彼らがカチカチ音をたてて、$ _ SESSIONの有効期限が切れている場合は、そこからユーザー名とパスワードを取得します。
私の懸念は、ほとんどのWebサイトがトークンシステムを使用していると確信しているため、ログインするとCookieにトークンが保存され、毎回サインインする代わりにトークンが使用されます。また、たとえばフォーラムでは、誰がオンラインかを確認できますが、私の場合は確認できません。
誰かが私がしたことが正しいか、変更する必要があるか、それは最善ではないが技術的には安全であるかどうかに応じてください。私が確信しているセッションの部分は安全であり、私が見たいくつかのビデオよりもさらに安全です。ユーザーのIDをセッションに保存するだけで、ユーザーがパスワードを変更しても、まだログインしていると言う人もいます。しかし、Cookieの部分は、Cookieを盗む恐怖で私をつまずかせて、ハッシュ化せずにCookieに保存しています。
答えを見つけました。このため、JWTを使用しています。 Json Web Tokens。これらは、jsonデータの2つのbase64エンコードされた文字列と、情報が変更されていないことを検証する最後の有効な署名です。ログインセッションの有効期限とそのユーザー名が含まれます。ログインのために1つのデータベースと同期する必要がないため、新しいサーバーを簡単に採用したい場合に特に便利です。
認証をしたい人は誰でも、私は間違いなくそれをお勧めします。とても使いやすい、これもlibです: https://Gist.github.com/anonymous/e223abe8066b66c40332649404553385 <-これは1つのエラーを削除して簡単にするために編集した以外は、githubで見つけました。
$key="1682da5b920f4ceb74a542922f43b2a4"/* You need to keep this to decode */
$a = new JWT;
$jwt = $a->encode(json_encode(array(
"typ" => "JWT",
"alg" => "HS256"
)), json_encode(array(
"iss" => "http://yourwebsite.com/",
"iat" => time(),
"exp" => time() + (20 * 60),
"username" => "authenticated Username"
)), $key);
setcookie('jwt_token', $jwt, 0, '/');
JWTのデータセットは変更できません。キーが後で提供する署名によってこの方法が維持されるためです。
ユーザーがサインインしようとしているときに$ a-> decode()関数を実行すると、ユーザー名を変更して「管理者」としてサインインしようとした場合など、データが改ざんされている場合はfalseが返されます。
$jwt = $this->jwt->decode($_COOKIE['jwt_token'], $key);
if($jwt == false) {
echo 'Invalid JWT signature, tampered with!'
} else {
$json = json_decode($jwt, true);
if(time() > $json['exp']) { /* expired */ }
if(time() < $json['iat']) { /* invalid */ }
/*
VALIDATED, let them through as being the user:
$json['username']
*/
}
上記のようにfalseが返された場合、改ざんされているため、署名は無効です。次に、json_decoded配列を使用して「exp」などの情報を確認できます。time()> expの場合、期限切れです。 time()<iatの場合は、スプーフィングも行っています。すべてが検証されたら、ユーザー名を確認し、蜂がそのユーザーのアカウントにアクセスする権限を持っていることを100%確認できます。
クイックリマインダー:
function safePasswordHash($ password){ return password_hash( base64_encode( hash( 'sha384'、$ password、false) )、 PASSWORD_BCRYPT、array( 'cost' => 12) ); }
試してください: https://3v4l.org/R1ccr
この記事 に基づいて、ランダムセレクターとトークンを使用して、各ユーザーを個別のテーブル内の認証状態に関連付けることもできます(例: "token_auth")。
したがって、最初に12文字のランダムな文字列を2つ生成します。
次に、Cookieを「selector:validator」として設定します。 「FhpyQLjXYCc9:qXE6Bh417rYg」。
Cookieが有効であることを確認するには、まずデータベース内の「セレクター」と一致する「トークン」をフェッチしてから、Cookieに存在する「バリデーター」のSHA-256値と比較します。
hash_equals() 関数を使用して、潜在的なタイミング攻撃を回避します。
私はあなたがあなたのパスワードをハッシュしなければならないことを知っています、実際はここに私のコードがあります(それが十分に安全かどうか教えてください)
はい、安全です。 saltは渡さないでしょうが、password_hashはsaltを自動的に管理します。
$ _SESSIONにユーザー名とパスワードを設定しました(これはサーバー側に保存されていると理解しています)
はい、サーバー側に保存されます。それでも、回避できる場合は機密情報をセッションに保存しないでください。この場合は機密情報を保存できます(セッションでパスワードをまったく必要としません)。
これはセキュリティ上の問題であり、セッションデータが共有ホストで読み込まれたり、ファイルを含めたりして読み取られる可能性があるため、プレーンテキストのパスワードが漏洩する可能性があります。
彼らが「Remember me」ボタンをチェックした場合、ユーザー名とパスワード(ハッシュ化されていない)をCookieに保存します
繰り返しますが、これは良くありません。ハッシュされていないパスワード、特にCookieを保存したくない場合は、.
犠牲者のブラウザに一時的にアクセスできる人は誰でもプレーンテキストのパスワードにアクセスできるようになり、XSS経由でアクセスできます(少なくとも、CookieがhttpOnlyでない場合はそうする必要があります)など。
代わりに使用したいのは、生成してデータベースに保存するランダムな識別子です(理想的にはハッシュ化されています)。
私が確信しているセッションの部分は安全であり、私が見たいくつかのビデオよりもさらに安全です。ユーザーのIDをセッションに保存するだけで、ユーザーがパスワードを変更しても、まだログインしていると言う人もいます。しかし、Cookieの部分は、Cookieを盗む恐怖で私をつまずかせて、ハッシュ化せずにCookieに保存しています。
あなたはあなたがベストプラクティスに従わないことを知っているようです。では、なぜここで独自のものを構築するのでしょうか?あなたのアプローチは何の利点も提供していないようですが、いくつかのかなり深刻な欠点があります。
パスワードをプレーンテキストでCookieに保存するという直観は正しいです。そうすることはお勧めできません。また、より安全な代替策があります。パスワードをソルトおよびハッシュしていますが、それらをプレーンテキストで_$_SESSION
_変数に保存すると、一種の対抗策になります。つまり、攻撃者がサーバーにアクセスした場合、すべてのパスワードを取得できるということです。現在サインインしているユーザー。
私の知る限り、標準的な方法は、トークンを使用することとまったく同じです。これははるかに安全です。ユーザーのパスワードをプレーンテキストでどこにでも保存する必要はありません。一般的な考え方はこれです:
password_verify()
で確認します。username=xxxx&expiry=xxxx&digest=xxxx
_を使用してCookieをユーザーのコンピューターに保存します。トークンの持続時間はあなた次第です。 _admin=true
_などの他の変数を追加することもできます。digest=
_が他のCookieデータのhash_hmac()
と一致することを確認します。ユーザーがCookieを改ざんしようとした場合。別のユーザー名に変更すると、HMACは検証しません。これに関する非常に優れた論文があり、私が読むことをお勧めします。 Webでのクライアント認証の推奨事項と禁止事項 (PDFリンク)。