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 相关文章推荐
Android ProgressBar进度条和ProgressDialog进度框的展示DEMO
Jun 19 PHP
PHP连接SQLServer2005方法及代码
Dec 26 PHP
利用谷歌 Translate API制作自己的翻译脚本
Jun 04 PHP
通过php删除xml文档内容的方法
Jan 23 PHP
php中curl使用指南
Feb 05 PHP
PHP递归遍历指定目录的文件并统计文件数量的方法
Mar 24 PHP
PHP时间和日期函数详解
May 08 PHP
php遍历类中包含的所有元素的方法
May 12 PHP
php结合curl实现多线程抓取
Jul 09 PHP
Zend Framework入门教程之Zend_Config组件用法详解
Dec 09 PHP
PHP结合Ffmpeg快速搭建流媒体服务的实践记录
Oct 31 PHP
PHP中上传文件打印错误错误类型分析
Apr 14 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
实用函数3
2007/11/08 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
jQuery学习笔记之Helloworld
2010/12/22 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
javascript/jquery获取地址栏url参数的方法
2014/03/05 Javascript
Javascript中的几种URL编码方法比较
2015/01/23 Javascript
CSS或者JS实现鼠标悬停显示另一元素
2016/01/22 Javascript
Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
2017/01/20 Javascript
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
Koa从零搭建到Api实现项目的搭建方法
2019/07/30 Javascript
layui table复选框禁止某几条勾选的实例
2019/09/20 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
H5实现手机拍照和选择上传功能
2019/12/18 Javascript
vuejs中父子组件之间通信方法实例详解
2020/01/17 Javascript
基于Vue的侧边目录组件的实现
2020/02/05 Javascript
[02:44]DOTA2英雄基础教程 钢背兽
2013/12/19 DOTA
[40:16]TFT vs Mski Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
python编写的最短路径算法
2015/03/25 Python
高效测试用例组织算法pairwise之Python实现方法
2017/07/19 Python
使用Python爬取最好大学网大学排名
2018/02/24 Python
python使用matplotlib画饼状图
2018/09/25 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
2018/09/27 Python
在Python中构建增广矩阵的实现方法
2019/07/01 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
python中Ansible模块的Playbook的具体使用
2020/05/28 Python
html5实现完美兼容各大浏览器的播放器
2014/12/26 HTML / CSS
马德里运动鞋商店:Nigra Mercato
2020/02/16 全球购物
国贸专业的职业规划书
2014/03/15 职场文书
经销商订货会主持词
2014/03/27 职场文书
参加招聘会后的感想
2015/08/10 职场文书
2019各种保证书范文
2019/06/24 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
Python中非常使用的6种基本变量的操作与技巧
2022/03/22 Python
Mysql超详细讲解死锁问题的理解
2022/04/01 MySQL