php站,访问量比较多的情况下,是否使用session不合适

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php站,访问量比较多的情况下,是否使用session不合适相关的知识,希望对你有一定的参考价值。

看到有的cms使用session类,就是模拟session的机制,用数据库存储一些用户信息,这是不是说明使用session会带来一些弊端,毕竟php的session都是现成的,谁也不会闲着没事儿搞个没用的东西,而且看到一个国外的博客,他就说自己除了必要的地方,如验证码,基本不用session,哪位大哥懂得,给小弟讲讲这是为什么

1、如果大点的网站使用 Session 是不是不合适?有什么损害? 优点 如果要在诸多Web页间传递一个变量,那么用Session变量要比通过QueryString传递变量可使问题简化。 要使WEb站点具有用户化,可以考虑使用Session变量。你的站点的每位访问者都有用户化的经验,基于此,随着LDAP和诸如MS Site Server等的使用,已不必再将所有用户化过程置入Session变量了,而这个用户化是取决于用户喜好的。 你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放。 缺点 Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量! 当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留20分钟!(事实上,这些变量一直可保留至“timeout”。“timeout”的时间长短由Web服务器管理员设定。一些站点上的变量仅维持了3分钟,一些则为10分钟,还有一些则保留至默认值20分钟。)所以,如果在Session中置入了较大的对象(如ADO recordsets,connections,等等),那就有麻烦了!随着站点访问量的增大,服务器将会因此而无法正常运行! 因为创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理,所以,过度使用session变量将会导致代码不可读而且不好维护。 虽然“你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放”。但是,“谁”想到那儿呢?变量的含义是什么?这些都变得不很清晰。 使用Session变量既有优点,又有缺点。就我个人的观点,最好少用,但在某些地方使用它们确实能使Web开发大大地简化。是否使用Session变量完全取决于个人的需要,无论使用与否,都要事先考虑其优缺点 2、如何截取Session超时 <?php session_start(); $_SESSION[loginTime] = time(); header('location:2.php'); ?> 保存为1.PHP,假设你的用户成功登陆,自动跳转到2.PHP <?php session_start(); if(time() > $_SESSION[loginTime] + 5) echo '超时'; else echo '未超时'; ?> 刷新2.PHP,会在5秒后显示超时,大体思路是这样的,具体情况具体分析,祝你好运~ 参考技术A 系统默认的session在访问较大的网站使用不太适合,原因有几个
1)SESSION默认是写文件,会导致session文件一致累加,同时也会受到硬盘空间的限制
2)SESSION默认写文件,没办法多台服务器共享,做分布就每没办法做~
3)服务器重启之后,SESSION文件被清空,意味着所有用户都会被踢下线~

所以,一般访问量比较大的网站,都考虑用其他实现方式,一般有
1)用数据库来存放session信息,这个是比较通用的做法
2)用memcached来存储session数据,这个需要有修改php配置和架设memcached的权限,配置完与普通SESSION使用方式一样,但是普通的空间明显没办法解决,因此不是适合于非托管站长
3)用NFS来做网络文件共享,将session挂在到网络硬盘,这个也需要服务器的配置权限,而且访问比较大的时候NFS的弊端很多~~

上面三种解决方案都解决了共享SESSION的问题,以及SESSION持久存储的问题,但是考虑到很多站长不会配置或者没有权限配置服务器,因此一些开源软件都采用第一种实现方式,既支持了分布式,又避免了系统配置的依赖~~追问

我主要想问下用数据库存储session,这种方法是怎么实现的,我的意思是,程序怎么区分哪个记录是属于哪个会员的,看过一些源码,记录了ip,但是ip这东西明显不靠谱吧,比如网吧或一些公司内部,IP都是一个

追答

用户访问的时候,会有一个SESSIONID,是通过这个session_id 来识别唯一用户的。

追问

这个东西的意义是什么呢?感觉cookie完全就够用了,再加一步这个干嘛呢?

追答

cookie因为是保存在客户端,会有各种安全问题,容易伪造,所以一般客户端就保存一个id,然后其他数据都在服务端取~~

另外,服务端对cookie的处理,一般都有限制大小的,而且cookie占用着网络传输的流量~~

追问

cookie肯定都是加密存储的
现在我想权衡下,是否该用那种session类,因为涉及到一个实际的项目,希望你能给点意见

追答

看你实现的难度,如果要用的话,memcached最方便,mysql比较麻烦,但是比较靠谱~~

追问

特殊原因,不能用memcached等工具,只有最基本的php+mysql,现在我对使用数据库模拟session的实际作用理解的不深,现阶段想到的只有麻烦,但是如果这个东西肯定是意义的,要不那些cms也不会这么做

参考技术B 用户访问量比较大的网站如果用session会比较浪费硬盘的空间,因为session的默认方式是写文件的,可以使用数据库,memcache等方式,修改php.ini即可,如果记录的是用户的登录登录状态用session即可,用的网站记录用户的登录状态使用的是servermedia等

如何在 PHP 中没有硬编码密钥的情况下进行对称加密

【中文标题】如何在 PHP 中没有硬编码密钥的情况下进行对称加密【英文标题】:How to do symmetric cryptography without hardcoded key in PHP 【发布时间】:2016-11-14 03:46:49 【问题描述】:

我正在使用 PHP mcrypt 库使用 AES 加密和存储 (MySQL) 数据。

我想知道是否有一种好方法可以做到这一点,而无需在我的代码中使用硬编码的加密/解密密钥。

如果黑客访问了我的服务器,他将能够看到文件和我在代码中的密钥,从而访问数据库上的所有数据。

谢谢。

【问题讨论】:

你需要一个钥匙。最好将其存储在您的代码中,而不是存储在加密数据所在的数据库中。 是的,但我想知道是否有更安全的方法。将密码存储在代码中会破坏整点。唯一有效的情况是黑客只能访问数据库,而不是整个服务器。 没错。这通常是重点。如果他们获得了数据库转储或对数据库服务器的访问权,他们将无法使用该信息。如果他们能够访问网络服务器,那并不重要,因为他们将能够做任何事情,包括拦截呼叫/数据和逆向工程 一般来说,如果服务器被入侵,那么一切都会被入侵,所以在服务器上对称地加密你的数据库数据并没有真正的帮助,所以不要这样做。 使用 AES 加密数据是存储信用卡信息的常规做法。您无法绕过将密钥存储在网络服务器上。 【参考方案1】:

我正在使用 PHP mcrypt 库使用 AES 加密和存储 (MySQL) 数据。

You may wish to reconsider your choice in cryptography library.

我想知道是否有一种好方法可以做到这一点,而无需在我的代码中使用硬编码的加密/解密密钥。

将其存储在文档根目录之外的配置文件中?例如,defuse/php-encryption。

如果黑客访问了我的服务器,他将能够看到文件和我在代码中的密钥,从而访问数据库上的所有数据。

如果黑客可以访问您的服务器,symmetric-key encryption cannot save you。但是,公钥加密可以保护机密性。

使用Halite,这很容易解决:

    只能在服务器上加密;从不解密。 您的密钥必须保持离线状态并供人使用。

在线代码(假设 PHP 7.0 和 Halite 2.1)

<?php
declare(strict_types=1);
use ParagonIE\Halite\
    Asymmetric\Crypto as Asymmetric,
    KeyFactory
;

$publicKey = KeyFactory::loadEncryptionPublicKey("/path/to/public/key");
$encrypted = Asymmetric::seal("Whatever secret data we want", $publicKey);
// Now do whatever you need with $encrypted

离线代码(假设 PHP 7.0 和 Halite 2.1)

<?php
declare(strict_types=1);
use ParagonIE\Halite\
    Asymmetric\Crypto as Asymmetric,
    KeyFactory
;

$salt = ""; // Generate from random_bytes(16) once, then persist.
$password = ""; // Create a strong password

$keyPair = KeyFactory::deriveEncryptionKeyPair($password, $salt);
$secretKey = $keyPair->getSecretKey();
$publicKey = $keyPair->getPublicKey();

// To have the public key to a file to upload to the server:
   KeyFactory::save($publicKey, '/path/to/public/key');

$decrypted = Asymmetric::unseal($encrypted, $secretKey);

【讨论】:

谢谢,这是一个很好的答案!我决定使用公钥来加密数据。这样,如果我被黑客入侵,黑客将无法访问私钥。太棒了! 我正在使用 PHP 的 openssl_public_encrypt。这是个好主意吗? Only if you use it very carefully. 也许这是一个单独的问题,但是一旦设置了密码,有没有办法更改密码?否则我能看到的唯一方法是解密所有内容然后重新加密。 示例代码从密码派生密钥。 Protecting a key with a password without deriving the key from the password 可以通过 Defuse 的 PHP 加密库实现。【参考方案2】:

这取决于你愿意走多远,以及你的环境。

将解密密钥保存在数据库中绝对是个坏主意 - 如果有人掌握了数据库,他们将同时拥有解密密钥和数据。通过将其存储在应用程序服务器上,您可以确定不会发生上述情况。但是如果有人可以访问应用程序服务器,然后通过应用程序服务器访问数据库呢?现在他们又拥有了密钥和数据。不过你已经说了这么多。

由于您没有提及您的环境,我们假设:

标准 LAMP 堆栈 PHP 作为 Apache 模块运行 您有一个部署工具/脚本来部署您的应用程序

你可以有一个简单的 Apache 配置文件:

将环境变量设置为加密密钥的值 从主要 apache 配置中包含 以加密方式存储在磁盘/存储库/部署工具可以访问的任何位置

然后在部署期间:

您的部署工具在其部署步骤中会尝试解密加密的配置文件并要求部署用户提供密钥 部署用户从完全未连接到正在运行的生产应用程序的系统/方法中提供密钥(例如离线安全密码存储等) 部署工具将文件复制到生产系统并解密 部署工具(重新)在生产系统上启动 Apache Apache加载解密后的配置文件,设置环境变量 一旦 Apache 运行,部署工具就会删除/覆盖/碎片/等。包含安全加密密钥的解密配置文件

在这之后,事情的当前状态将是:

Apache 已将配置加载到内存中,解密后的密钥可通过环境变量供 PHP 使用 安全密钥不存储在生产系统的任何位置,它仅在内存中可用 您可以重新加载/重新启动 Apache 的唯一方法是通过您的部署工具(这可能是您想要的)

你如何仍然容易受到攻击:

当您直接写入支持的文件系统上的磁性硬盘驱动器时,粉碎文件是安全的;它在 VM 或 SSD 环境中可能没有那么安全 有权访问应用程序服务器的攻击者可以转储 Apache 使用的内存并试图找出如何获取那里某处的解密密钥 在部署过程中的几秒钟内,当 Apache 加载时,文件在服务器上是未加密的;如果攻击者具有不间断的访问权限并且知道要查找的内容,他们可能会很幸运并找到该文件

不过,它比将未加密的密钥存储在应用程序服务器上要安全得多,而且它需要非常复杂且高度复杂的攻击者才能利用。所以,正如我在开头所说的,这取决于你想走多远。

【讨论】:

以上是关于php站,访问量比较多的情况下,是否使用session不合适的主要内容,如果未能解决你的问题,请参考以下文章

在不更改 url 的情况下访问脚本

如果把很多代码都写在同一个PHP文件里面加载的时候会卡吗

主机宝等主机面板不能跨站访问文件,不能访问父路径文件问题

访问量大的网站被攻击怎么办?

win7如何在局域网中发布网站

常用Java集合类总结