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 ss7.5的数据调用 (笔记)
Mar 08 PHP
在MongoDB中模拟Auto Increment的php代码
Mar 06 PHP
php简单开启gzip压缩方法(zlib.output_compression)
Apr 13 PHP
如何使用php输出时间格式
Aug 31 PHP
php计算数组不为空元素个数的方法
Jan 27 PHP
php获取当前页面完整URL地址
Dec 30 PHP
PHP开发中常用的十个代码样例
Feb 02 PHP
将PHP程序中返回的JSON格式数据用gzip压缩输出的方法
Mar 03 PHP
PHP简单获取多个checkbox值的方法
Jun 13 PHP
PHP判断一个数组是另一个数组子集的方法详解
Jul 31 PHP
搭建自己的PHP MVC框架详解
Aug 16 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
Feb 15 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
万能的php分页类
2017/07/06 PHP
浅谈laravel-admin的sortable和orderby使用问题
2019/10/03 PHP
ThinkPHP 框架实现的读取excel导入数据库操作示例
2020/04/14 PHP
javascript replace()正则替换实现代码
2010/02/26 Javascript
jquery 模拟类搜索框自动完成搜索提示功能(改进)
2010/05/24 Javascript
ajax更新数据后,jquery、jq失效问题
2011/03/16 Javascript
基于jquery的大众点评,分类导航实现代码
2011/08/23 Javascript
javascript操作html控件实例(javascript添加html)
2013/12/02 Javascript
jquery.post用法示例代码
2014/01/03 Javascript
基于Javascript倒计时效果
2016/12/22 Javascript
Easyui Tree获取当前选择节点的所有顶级父节点
2017/02/14 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
详解搭建es6+devServer简单开发环境
2018/09/25 Javascript
ES6基础之字符串和函数的拓展详解
2019/08/22 Javascript
element-ui和vue表单(对话框)验证提示语(残留)清除操作
2020/09/11 Javascript
简介Django中内置的一些中间件
2015/07/24 Python
Python3 处理JSON的实例详解
2017/10/29 Python
Python生成验证码、计算具体日期是一年中的第几天实例代码详解
2019/10/16 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
Python Json数据文件操作原理解析
2020/05/09 Python
基于django micro搭建网站实现加水印功能
2020/05/22 Python
PyCharm2020.1.2社区版安装,配置及使用教程详解(Windows)
2020/08/07 Python
Python如何批量生成和调用变量
2020/11/21 Python
CSS3中的opacity属性使用教程
2015/08/19 HTML / CSS
利用纯CSS3实现动态的自行车特效源码
2017/01/20 HTML / CSS
HTML5+CSS3实现机器猫
2016/10/17 HTML / CSS
英国第一职业高尔夫商店:Clickgolf.co.uk
2020/11/18 全球购物
英文演讲稿
2014/05/15 职场文书
特教教师先进事迹
2014/05/21 职场文书
领导干部遵守党的政治纪律情况思想汇报
2014/09/14 职场文书
违反单位工作制度检讨书
2014/10/25 职场文书
2016三八妇女节校园广播稿
2015/12/17 职场文书
HR必备:超全面的薪酬待遇管理方案!
2019/07/12 职场文书
CSS实现单选折叠菜单功能
2021/11/01 HTML / CSS
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis
PYTHON使用Matplotlib去实现各种条形图的绘制
2022/03/22 Python