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来自动调用不同服务器上的flash
Oct 09 PHP
树型结构列出指定目录里所有文件的PHP类
Oct 09 PHP
PHP中文件上传的一个问题
Sep 04 PHP
PHP imagecreatefrombmp 从BMP文件或URL新建一图像
Jul 16 PHP
PHP管理内存函数 memory_get_usage()使用介绍
Sep 23 PHP
php excel reader读取excel内容存入数据库实现代码
Dec 06 PHP
php查找指定目录下指定大小文件的方法
Nov 28 PHP
PHP获取youku视频真实flv文件地址的方法
Dec 23 PHP
Yii学习总结之数据访问对象 (DAO)
Feb 22 PHP
Docker 如何布置PHP开发环境
Jun 21 PHP
PHP单例模式定义与使用实例详解
Feb 06 PHP
PHP 信号管理知识整理汇总
Feb 19 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
单点登录 Ucenter示例分析
2013/10/29 PHP
laravel unique验证、确认密码confirmed验证以及密码修改验证的方法
2019/10/16 PHP
JQuery读取XML文件数据并显示的实现代码
2009/12/16 Javascript
js图片向右一张张滚动效果实例代码
2013/11/23 Javascript
jQuery中:focus选择器用法实例
2014/12/30 Javascript
JavaScript实现将数组中所有元素连接成一个字符串的方法
2015/04/06 Javascript
jquery衣服颜色选取插件效果代码分享
2015/08/28 Javascript
纯js实现手风琴效果
2020/04/17 Javascript
JavaScript禁止用户多次提交的两种方法
2016/07/24 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
2017/02/08 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
2017/06/26 jQuery
JavaScript面向对象精要(下部)
2017/09/12 Javascript
详解webpack中的hash、chunkhash、contenthash区别
2018/01/05 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
微信小程序引入模块中wxml、wxss、js的方法示例
2019/08/09 Javascript
vue iview的菜单组件Mune 点击不高亮的解决方案
2019/11/01 Javascript
Vue+axios封装请求实现前后端分离
2020/10/23 Javascript
[06:36]吞吞映像top1
2014/06/20 DOTA
[03:00]DOTA2-DPC中国联赛1月18日Recap集锦
2021/03/11 DOTA
Python的Django应用程序解决AJAX跨域访问问题的方法
2016/05/31 Python
Python类的继承和多态代码详解
2017/12/27 Python
Python实现自动上京东抢手机
2018/02/06 Python
python 实现调用子文件下的模块方法
2018/12/07 Python
python:按行读入,排序然后输出的方法
2019/07/20 Python
python 单线程和异步协程工作方式解析
2019/09/28 Python
Python tkinter实现图片标注功能(完整代码)
2019/12/08 Python
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
阿里巴巴美国:Alibaba美国
2019/11/24 全球购物
法国隐形眼镜网站:VisionDirect.fr
2020/03/03 全球购物
入党自我鉴定范文
2013/10/04 职场文书
教师研修随笔感言
2014/01/23 职场文书
社区学习党的群众路线教育实践活动心得体会
2014/11/03 职场文书
简单的离婚协议书范本
2014/11/16 职场文书
MATLAB 全景图切割及盒图显示的实现步骤
2021/05/14 Python
vite+vue3.0+ts+element-plus快速搭建项目的实现
2021/06/24 Vue.js