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 相关文章推荐
浅析51个PHP处理字符串的函数
Aug 02 PHP
PHP输出英文时间日期的安全方法(RFC 1123格式)
Jun 13 PHP
PHP中使用sleep函数实现定时任务实例分享
Aug 21 PHP
PHP中require和include路径问题详解
Dec 25 PHP
如何使用纯PHP实现定时器任务(Timer)
Jul 31 PHP
php数据访问之查询关键字
May 09 PHP
PHP使用内置函数生成图片的方法详解
May 09 PHP
Zend Framework分发器用法示例
Dec 11 PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
Jul 03 PHP
PHP排序算法之归并排序(Merging Sort)实例详解
Apr 21 PHP
PHP回调函数简单用法示例
May 08 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 字符串 小常识
2009/06/05 PHP
php xml 入门学习资料
2011/01/01 PHP
Destoon实现多表查询示例
2014/08/21 PHP
PHP使用CURL模拟登录的方法
2015/07/08 PHP
php抽象方法和抽象类实例分析
2016/12/07 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
2016/12/29 PHP
详解强大的jQuery选择器之基本选择器、层次选择器
2012/02/07 Javascript
jQuery垂直多级导航菜单代码分享
2015/08/18 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
2016/02/15 Javascript
Angular中$cacheFactory的作用和用法实例详解
2016/08/19 Javascript
VueJs与ReactJS和AngularJS的异同点
2016/12/12 Javascript
js for循环倒序输出数组元素的实例
2017/03/01 Javascript
详解vue-router 2.0 常用基础知识点之router-link
2017/05/10 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
2017/08/15 Javascript
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
2017/09/18 NodeJs
微信小程序之GET请求的实例详解
2017/09/29 Javascript
讲解vue-router之什么是编程式路由
2018/05/28 Javascript
JavaScript设计模式之装饰者模式定义与应用示例
2018/07/25 Javascript
js中this的指向问题归纳总结
2018/11/28 Javascript
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
python中import reload __import__的区别详解
2017/10/16 Python
Python实现XML文件解析的示例代码
2018/02/05 Python
Python基于多线程实现抓取数据存入数据库的方法
2018/06/22 Python
对Python使用mfcc的两种方式详解
2019/01/09 Python
python3 pygame实现接小球游戏
2019/05/14 Python
对python中的*args与**kwgs的含义与作用详解
2019/08/28 Python
Python socket聊天脚本代码实例
2020/01/02 Python
一款基于css3和jquery实现的动画显示弹出层按钮教程
2015/01/04 HTML / CSS
基于CSS3制作立体效果导航菜单
2016/01/12 HTML / CSS
安全的后院和健身蹦床:JumpSport
2019/07/15 全球购物
质检部经理岗位职责
2014/02/19 职场文书
课外活动总结
2015/02/04 职场文书
七年级英语教学反思
2016/02/15 职场文书
SQL Server2019数据库之简单子查询的具有方法
2021/04/27 SQL Server
python和Appium的移动端多设备自动化测试框架
2022/04/26 Python
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android