PHP实践教程之过滤、验证、转义与密码详解


Posted in PHP onJuly 24, 2017

本文主要给大家介绍的是关于PHP实践之过滤、验证、转义与密码等相关的内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍:

一、过滤、验证和转义

1).不要相信任何来自不受自己直接控制的数据源中的数据。包括但不限于:

  • $_GET
  • $_POST
  • $_REQUEST
  • $_COOKIE
  • $argv
  • php://stdin
  • php://input
  • file_get_contents()
  • 远程数据库
  • 远程API
  • 来自客户端的数据

2).解决办法:过滤输入。删除不安全的字符,在数据到达应用的存储层之前,必须过滤数据。需要过滤的数据包括不限于:HTML、SQL查询和用户资料信息。

  • HTML:使用htmlentities()函数过滤HTML成对应的实体。这个函数会转义制定字符的HTML字符,以便在存储层安全的渲染。正确的使用方式是使用htmlentities($input, ENT_QUOTES, 'UTF-8')过滤输入。或者使用HTML Purifier。缺点是慢
  • SQL查询: 有时必须根据数据构建SQL查询。这时要要使用PDO预处理语句过滤外部数据。
  • 用户资料信息:使用filter_var()filter_input()过滤用户资料信息

3).验证数据:也可以使用filter_var() ,验证成功返回要验证的值,失败返回false。但是这个函数无法验证所有数据,所以可以使用一些验证功能组件。例如aura/filter或者symfony/validator

4)转义输出:任然可以使用htmlentities这个函数,一些模板引擎也自带了转义功能。

密码

       1).绝对不能知道用户的密码。

       2).绝对不要约束用户的密码,要限制的话只限制最小长度。

       3).绝对不能使用电子邮件发送用户的密码。你可以发送一个修改密码的链接,上面带一个token验证是用户本人就行了。

       4).使用bcrypt计算用户密码的哈希值。加密和哈希不是一回事,加密是双向算法,加密的数据可以被解密。但是哈希是单项算法,哈希之后的数据无法被还原,想同的数据哈希之后得到的数据始终是相同的。使用数据库存储通过bcrypt哈希密码之后的值。

       5).使用密码哈希API简化计算密码哈希和验证密码的操作。下面的注册用户的一般操作

POST /register.php HTTP/1.1
Content-Length: 43
Content-type: application/x-www-form-urlencoded

email=xiao@hello.world&password=nihao

下面是接受这个请求的PHP文件

<?php
try {
 $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
 if (!$email) {
  throw new Exception('Invalid email');
 }
 $password = filter_iput(INPUT_POST, 'password');
 if (!$password || mb_strlen($password) < 8) {
  throw new Exception('Password must contain 8+ characters');
 }
 //创建密码的哈希值
 $passwordHash = password_hash(
  $password,
  PASSWORD_DEFAULT,
  ['cost' => 12]
  );

 if ($passwordHash === false) {
  throw new Exception('Password hash failed');
 }

 //创建用户账户,这里是虚构的代码
 $user = new User();
 $user->email = $email;
 $user->password_hash = $passwordHash;
 $user->save();
 header('HTTP/1.1 302 Redirect');
 header('Location: /login.php');
} catch (Exception $e) {
 header('HTTP1.1 400 Bad Request');
 echo $e->getMessage();
}

       6).根据机器的具体计算能力修改password_hash()的第三个值。计算哈希值一般需要0.1s-0.5s。

       7).密码的哈希值存储在varchar(255)类型的数据库列中。

       8).登录用户的一般流程

POST /login.php HTTP1.1
Content-length: 43
Content-Type: application/x-www-form-urlencoded

email=xiao@hello.wordl&pasword=nihao
session_start();
try {
 $email = filter_input(INPUT_POST, 'email');
 $password = filter_iinput(INPUT_POST, 'password');

 $user = User::findByEmail($email);

 if (password_verify($password, $user->password_hash) === false) {
  throw new Exception(''Invalid password);
 }

 //如果需要的话,重新计算密码的哈希值
 $currentHasAlgorithm = PASSWORD_DEFAULT;
 $currentHashOptions = array('cost' => 15);
 $passwordNeedsRehash = password_needs_rehash(
  $user->password_hash,
  $currentHasAlgorithm,
  $currentHasOptions
 );
 if ($passwordNeedsRehash === true) {
  $user->password_hash = password_hash(
   $password,
   $currentHasAlgorithm,
   $currentHasOptions
  );

  $user->save();
 }

 $_SESSION['user_logged_in'] = 'yes';
 $_SESSION['user_email'] = $email;

 header('HTTP/1.1 302 Redirect');
 header('Location: /user-profile.php');
} catch (Exception) {
 header('HTTP/1.1 401 Unauthorized');
 echo $e->getMessage();
}

      9).PHP5.5.0版本之前的密码哈希API无法使用,推荐使用ircmaxell/password-compat组件。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP.MVC的模板标签系统(三)
Sep 05 PHP
使用PHP实现二分查找算法代码分享
Jun 24 PHP
php header Content-Type类型小结
Jul 03 PHP
php数组函数序列之array_slice() - 在数组中根据条件取出一段值,并返回
Nov 07 PHP
php中判断文件空目录是否有读写权限的函数代码
Aug 07 PHP
php抽奖小程序的实现代码
Jun 18 PHP
php中创建和调用webservice接口示例
Jul 25 PHP
PHP文件缓存内容保存格式实例分析
Aug 20 PHP
php生成百度sitemap站点地图类函数实例
Oct 17 PHP
php基于socket实现SMTP发送邮件的方法
Mar 05 PHP
PHP模拟asp中response类实现方法
Aug 08 PHP
浅谈PHP中的面向对象OOP中的魔术方法
Jun 12 PHP
php实现和c#一致的DES加密解密实例
Jul 24 #PHP
PHP读取CSV大文件导入数据库的实例
Jul 24 #PHP
Yii2.0多文件上传实例说明
Jul 24 #PHP
thinkphp分页集成实例
Jul 24 #PHP
PHP 实现页面静态化的几种方法
Jul 23 #PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 #PHP
php魔法函数与魔法常量使用介绍
Jul 23 #PHP
You might like
几种显示数据的方法的比较
2006/10/09 PHP
在PHP3中实现SESSION的功能(一)
2006/10/09 PHP
同台服务器使用缓存APC效率高于Memcached的演示代码
2010/02/16 PHP
phpphp图片采集后按原路径保存图片示例
2014/02/18 PHP
php readfile()修改文件上传大小设置
2017/08/11 PHP
JQuery团队打造的javascript单元测试工具QUnit介绍
2010/02/26 Javascript
如何防止回车(enter)键提交表单
2014/05/11 Javascript
html的DOM中document对象images集合用法实例
2015/01/21 Javascript
javascript结合fileReader 实现上传图片
2015/01/30 Javascript
JS+CSS实现的经典tab选项卡效果代码
2015/09/16 Javascript
JavaScript中的原型prototype完全解析
2016/05/10 Javascript
基于jQuery实现点击列表加载更多效果
2016/05/31 Javascript
JavaScript重定向URL参数的两种方法小结
2016/10/19 Javascript
JS实现的计数排序与基数排序算法示例
2017/12/04 Javascript
js 实现watch监听数据变化的代码
2019/10/13 Javascript
[03:27]《辉夜杯》线下训练营 导师CU和海涛指点迷津
2015/10/23 DOTA
Python中MYSQLdb出现乱码的解决方法
2014/10/11 Python
读取本地json文件,解析json(实例讲解)
2017/12/06 Python
详解python爬虫系列之初识爬虫
2019/04/06 Python
通过 Django Pagination 实现简单分页功能
2019/11/11 Python
Django对接支付宝实现支付宝充值金币功能示例
2019/12/17 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
10分钟入门CSS3 Animation
2018/12/25 HTML / CSS
HTML5实现页面切换激活的PageVisibility API使用初探
2016/05/13 HTML / CSS
世界最大的票务市场:viagogo
2017/02/16 全球购物
成人毕业生自我鉴定
2013/10/18 职场文书
航空大学应届生求职信
2013/11/10 职场文书
贷款担保申请书
2014/05/20 职场文书
欢迎领导标语
2014/06/27 职场文书
三八节祝酒词
2015/08/11 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
大学军训口号大全
2015/12/24 职场文书
SQL SERVER中常用日期函数的具体使用
2021/04/08 SQL Server
django注册用邮箱发送验证码的实现
2021/04/18 Python
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
2021/05/17 Python
Python requests用法和django后台处理详解
2022/03/19 Python