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小技巧搜集,每个PHPer都来露一手
Jan 02 PHP
php结合飞信 免费天气预报短信
May 07 PHP
提高PHP编程效率 引入缓存机制提升性能
Feb 15 PHP
php漏洞之跨网站请求伪造与防止伪造方法
Aug 15 PHP
ECSHOP在PHP5.5及高版本上报错的解决方法
Aug 31 PHP
PHP生成各种常见验证码和Ajax验证过程
Jan 10 PHP
详解PHP的Yii框架中组件行为的属性注入和方法注入
Mar 18 PHP
php构造方法中析构方法在继承中的表现
Apr 12 PHP
PHP中抽象类和抽象方法概念与用法分析
May 24 PHP
php版银联支付接口开发简明教程
Oct 14 PHP
PHP上传图片、删除图片简单实例
Nov 12 PHP
php实现QQ小程序发送模板消息功能
Sep 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
PHP去除数组中重复的元素并按键名排序函数
2008/08/18 PHP
php数组函数序列之array_unshift() 在数组开头插入一个或多个元素
2011/11/07 PHP
PHP浮点比较大小的方法
2016/02/14 PHP
PHP 7.0新增加的特性介绍
2017/06/08 PHP
详解PHP防止直接访问.php 文件的实现方法
2017/07/28 PHP
Laravel实现定时任务的示例代码
2017/08/10 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
Aster vs Newbee BO5 第二场2.19
2021/03/10 DOTA
ajax 缓存 问题 requestheader
2010/08/01 Javascript
JQuery模板插件 jquery.tmpl 动态ajax扩展
2011/11/10 Javascript
关于递归运算的顺序测试代码
2011/11/30 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
2014/10/30 Javascript
动态加载JavaScript文件的两种方法
2016/04/22 Javascript
Javascript删除指定元素节点的方法
2016/06/21 Javascript
jQuery中Nicescroll滚动条插件的用法
2016/11/10 Javascript
JavaScript中浅讲ajax图文详解
2016/11/11 Javascript
用jQuery旋转插件jqueryrotate制作转盘抽奖
2017/02/10 Javascript
JavaScript实现获取远程的html到当前页面中
2017/03/26 Javascript
Bootstrap进度条与AJAX后端数据传递结合使用实例详解
2017/04/23 Javascript
Vue.js 2.0 移动端拍照压缩图片预览及上传实例
2017/04/27 Javascript
微信小程序模板(template)使用详解
2018/01/31 Javascript
JS实现随机生成10个手机号的方法示例
2018/12/07 Javascript
vue使用混入定义全局变量、函数、筛选器的实例代码
2019/07/29 Javascript
python Socket之客户端和服务端握手详解
2017/09/18 Python
Python绘制的二项分布概率图示例
2018/08/22 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
2020/03/10 Python
Python列表如何更新值
2020/05/27 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
Html5之webcoekt播放JPEG图片流
2020/09/22 HTML / CSS
Public Desire美国/加拿大:全球性的在线鞋类品牌
2018/12/17 全球购物
linux面试题参考答案(3)
2012/09/13 面试题
技校生自我鉴定
2013/12/08 职场文书
大学生志愿者感言
2014/01/15 职场文书
Django中的JWT身份验证的实现
2021/05/07 Python
SQL注入篇学习之盲注/宽字节注入
2022/03/03 MySQL
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL