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 相关文章推荐
火车头discuz6.1 完美采集的php接口文件
Sep 13 PHP
php入门教程 精简版
Dec 13 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
Jun 20 PHP
Linux下PHP安装mcrypt扩展模块笔记
Sep 10 PHP
php+mysql实现简单的增删改查功能
Jul 13 PHP
PHP技术开发微信公众平台
Jul 22 PHP
PHPCMS手机站伪静态设置详细教程
Feb 06 PHP
PHP里面把16进制的图片数据显示在html的img标签上(实现方法)
May 02 PHP
PHP环形链表实现方法示例
Sep 15 PHP
php 删除一维数组中某一个值元素的操作方法
Feb 01 PHP
PHP实现带进度条的Ajax文件上传功能示例
Jul 02 PHP
thinkphp5.1框架模板赋值与变量输出示例
May 25 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短域名转换为实际域名函数
2011/01/17 PHP
PHP小技巧之函数重载
2014/06/02 PHP
php连接odbc数据源并保存与查询数据的方法
2014/12/24 PHP
Zend Framework实现具有基本功能的留言本(附demo源码下载)
2016/03/22 PHP
PHP基于递归实现的约瑟夫环算法示例
2017/08/27 PHP
PHP 使用二进制保存用户状态的实例
2018/01/29 PHP
jquery下组织javascript代码(js函数化)
2010/08/25 Javascript
js读取cookie方法总结
2014/10/31 Javascript
JavaScript识别网页关键字并进行描红的方法
2015/11/09 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
2016/06/12 Javascript
浅谈JavaScript的闭包函数
2016/12/08 Javascript
解析微信JS-SDK配置授权,实现分享接口
2016/12/09 Javascript
jquery横向纵向鼠标滚轮全屏切换
2017/02/27 Javascript
vue axios 表单提交上传图片的实例
2018/03/16 Javascript
关于Angularjs中跨域设置白名单问题
2018/04/17 Javascript
在vue中v-bind使用三目运算符绑定class的实例
2018/09/29 Javascript
策略模式实现 Vue 动态表单验证的方法
2019/09/16 Javascript
vue.config.js常用配置详解
2019/11/14 Javascript
vue 查看dist文件里的结构(多种方式)
2020/01/17 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
2020/07/21 Javascript
Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
2008/09/06 Python
python处理cookie详解
2014/02/07 Python
详解tensorflow训练自己的数据集实现CNN图像分类
2018/02/07 Python
Python实现读取Properties配置文件的方法
2018/03/29 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
django表单中的按钮获取数据的实例分析
2020/07/31 Python
介绍一下如何优化MySql
2016/12/20 面试题
家庭教育先进个人事迹材料
2014/01/24 职场文书
质量提升方案
2014/06/16 职场文书
学生实习证明范文
2014/09/28 职场文书
业务员辞职信范文
2015/03/02 职场文书
致短跑运动员加油稿
2015/07/21 职场文书
教你怎么用Python监控愉客行车程
2021/04/29 Python
如何在向量化NumPy数组上进行移动窗口
2021/05/18 Python
vue中使用mockjs配置和使用方式
2022/04/06 Vue.js