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 相关文章推荐
基于mysql的bbs设计(一)
Oct 09 PHP
php中将汉字转换成拼音的函数代码
Sep 08 PHP
PHP时间戳 strtotime()使用方法和技巧
Oct 29 PHP
php实现的DateDiff和DateAdd时间函数代码分享
Aug 16 PHP
php获取本周开始日期和结束日期的方法
Mar 09 PHP
PHP中使用hidef扩展代替define提高性能
Apr 09 PHP
PHP中PDO连接数据库中各种DNS设置方法小结
May 13 PHP
php正则提取html图片(img)src地址与任意属性的方法
Feb 08 PHP
Yii框架实现记录日志到自定义文件的方法
May 23 PHP
详解PHP中mb_strpos的使用
Feb 04 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
Oct 15 PHP
PHP使用JpGraph绘制折线图操作示例【附源码下载】
Oct 18 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
德生S2000南麂列岛台湾FM收听记录
2021/03/02 无线电
如何在PHP中使用Oracle数据库(3)
2006/10/09 PHP
php懒人函数 自动添加数据
2011/06/28 PHP
YII Framework框架教程之使用YIIC快速创建YII应用详解
2016/03/15 PHP
php实现socket推送技术的示例
2017/12/20 PHP
PHP bin2hex()函数基础实例讲解
2019/02/11 PHP
使用原生js写的一个简单slider
2014/04/29 Javascript
简介AngularJS中使用factory和service的方法
2015/06/17 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
最好用的Bootstrap fileinput.js文件上传组件
2016/12/12 Javascript
vue.js指令v-model使用方法
2017/03/20 Javascript
vue中如何实现变量和字符串拼接
2017/06/19 Javascript
详解vue组件通信的三种方式
2017/06/30 Javascript
Express+Nodejs 下的登录拦截实现代码
2017/07/01 NodeJs
实现jquery放大镜的两种方法
2018/02/22 jQuery
vue 组件的封装之基于axios的ajax请求方法
2018/08/11 Javascript
浅入深出Vue之组件使用
2019/07/11 Javascript
[03:22]DAC最前线(第二期)—DOTA2亚洲邀请赛主赛场周边及线路探访
2015/01/24 DOTA
利用python写个下载teahour音频的小脚本
2017/05/08 Python
用 Python 连接 MySQL 的几种方式详解
2018/04/04 Python
与Django结合利用模型对上传图片预测的实例详解
2019/08/07 Python
Python OpenCV读取显示视频的方法示例
2020/02/20 Python
记录模型训练时loss值的变化情况
2020/06/16 Python
通过实例解析Python RPC实现原理及方法
2020/07/07 Python
CSS3媒体查询(Media Queries)介绍
2013/09/12 HTML / CSS
阿玛尼美妆英国官网:Giorgio Armani Beauty英国
2019/03/28 全球购物
一套Java笔试题
2016/08/20 面试题
信号量和自旋锁的区别?如何选择使用?
2015/09/08 面试题
软件部经理岗位职责范本
2014/02/25 职场文书
夫妻婚内购房协议书
2014/10/05 职场文书
作文评语集锦
2014/12/25 职场文书
新员工辞职信范文
2015/05/12 职场文书
2015年法务工作总结范文
2015/05/23 职场文书
pytorch 如何把图像数据集进行划分成train,test和val
2021/05/31 Python
浅谈Python数学建模之整数规划
2021/06/23 Python
解决xampp安装后Apache无法启动
2022/03/21 Servers