同一台服务器Nginx防止未配置SSL证书的站点通过https访问跳转到配置了SSL(https)证书的站点

服务器:CentOS
环境:Nginx+MySQL+PHP

之前在这台服务器上配置了多个vhost站点,其中有一个还配好了SSL证书(https访问),其他站点都没配置。今天有个同事发现,当通过https访问其中一个未配置ssl证书的网站时,浏览器(谷歌、火狐都会)会提示证书风险,选择继续访问后,内容却是配置了ssl证书的那个站点。

后来查询得知,通过https协议访问未配置ssl证书的站点时,默认会跳转到一个(如果配置了的话)https站点,要禁止这种跳转,需要配置一个默认ssl(无效的也可以)server,具体如下:

server {
 listen 443 default_server;
 server_name _ ;
 ssl on;
 ssl_certificate crt/1_xxxx.com_bundle.crt; # 这里可以是无效的证书
 ssl_certificate_key crt/2_xxxx.com.key; # 这里可以是无效的证书
 return 301 http://$host$request_uri; # 跳转到http协议访问
}

最后一句(return)强制把未配置ssl证书的https访问都跳转到http协议上,问题解决。
这是目前得到的解决方案,如果还有更好的,欢迎大家指出!

追着Truman去探索世界(楚门的世界观后感)

影片的英文名是 The Truman Show,大概是True Man的另一种表达方式吧,主人公Truman就是虚拟世界里唯一真实的存在,其他一切都是人为构建的虚拟场景——桃源。

影片开始的十几分钟,我还有一点云里雾里,弄不明白Truman的世界是电视剧,还是真实的生活。随着剧情的推进,我开始意识到,Truman是那个唯一被蒙在鼓里的人,其他人都只是配合他在演戏。而电视荧幕前,是全世界无数的观众,他们把Truman的生活当做了一种节目,一种能激发他们持续关注的节目,而Truman是那个节目的Super Star。

已过而立之年的Truman,有一种意识慢慢在他脑子里萌芽。种种迹象表明,他的世界好像已经被人提前设定好了一样,无论如何,他都无法挣脱。影片最明显的表达就是,他想离开自己居住的地方去斐济岛,但机票订不到,大巴也出了故障(司机故意弄坏的)。身边所有的人都在演戏,包括他从小到大的玩伴。虽然他很怀疑,但想通过周边的人去证实却是行不通的。相比起来,反倒是物理的存在给了他可靠的提示。

意识到自己生活的世界是有问题的,Truman决定一探究竟。在人为的狂风骤雨之下,他毫不畏惧退缩,而是舍命向前。最终,他找到了那个写着 EXIT 字样的出口。“上帝”劝说Truman,告诉他外面的世界并没有想象中那么好,他现在生活的世界至少可以保证他不会有任何危险。

屏幕前的观众都为Truman捏着一把汗,“他到底会怎样选择?”毫无疑问,Truman选择了走出去,走出那个禁锢自己大半生的桃源之境,去探索那道 EXIT 之门外面的世界,哪怕是冒着失去生命的风险。

Truman最终找到了生命的出口,那我们呢?

和荧幕前的观众一样,我们自己生活的世界是不是也是被别人,或者被自己,设定了,禁锢了?我们的生活是不是只是在原地打转,毫无方向,毫无进展?我们有没有意识到自己的问题?如果找到了问题,我们能否鼓足勇气去改变?

The Truman Show 带给我们的思考是最重要的。

PHP单点登录SSO简单示例Demo

我本地建了三个测试站点,分别为:

  1. www.testa.com
  2. www.testb.com
  3. www.sso.com

其中,站点sso是用于集中验证的站点。

访问站点testa index.php

<?php
// testa: index.php
$url = urlencode("http://www.testa.com/");

if ($_GET['action'] == 'logout') {
    setcookie("islogged");
}

if (isset($_GET['token']) && !empty($_GET['token'])) {
    $token = $_GET['token'];
    $res = file_get_contents("http://www.sso.com/verify.php?token={$token}");
    if ($res == 'yes') {
        echo "verify success";
        setcookie('islogged', true);
    } else {
        echo "verify fail";
    }
    header("Location: index.php");
    exit;
}

if ($_COOKIE['islogged'] == true) {
    echo "a success";
} else {
    echo "fail";
    header("Location: http://www.sso.com/index.php?redirect={$url}");
}

程序判断用户是否登录站点testa,如果没有,则跳转到站点sso进行验证。

- 阅读剩余部分 -

PHP自定义session处理方法,保存到MySQL数据库中

我们都知道,session是为了解决因特网的无状态属性而创造出来的。我们可以用session这种会话管理机制来构建购物车、监控站点网络访问,甚至还可以跟踪某一个用户具体是如何使用你的应用的。PHP默认的session处理行为已经能应付大部分的场景,但有时候我们还是希望能够主动一点来控制session的处理方式,比如存储到数据库中而不是文件系统。下面我将以保存session到MySQL数据库给大家讲解如何自定义session处理方法。

解构session存储

在我们开始构建自己的session处理及存储方法之前,理解PHP默认如何存储session数据是很有帮助的。session数据被保存在服务器上一个很小的文件中,并关联了一个唯一的ID,随后被浏览器以cookie的形式保存在客户端。如果cookie没被起用,那么ID就会随着URL被当做参数进行传递。无论是哪种方式,在随后的请求中,PHP都是通过这个唯一的ID对session数据进行读取、更新或者删除等操作。为了便于理解这是怎么一回事,我们可以先从session数据保存的位置开始分析。对于文件形式保存的session数据,可以通过检查php.ini中的session.save_path得知,也可以用session_save_path()函数进行输出,如:

<?php
echo session_save_path();

输出结果就是session数据保存的位置。如果你想更改存储位置,可以修改php.ini配置,或者执行session_save_path()函数,参数就是新的存储路径。

session_save_path("/path/to/session/data");
最佳实践:如果你自定义了session存储路径,那么建议把路径选择在网站根目录之外,这样可以最大限度避免非法获取session数据。当然,你需要保证PHP程序能够正常读写session文件。

现在我们已经知道了session数据存储在哪,那我们就很容易找到对应当前访问的session文件。session文件的命名以“sess_”为前缀,加上唯一的ID。session_id()可以获取唯一ID值(是32位的字符串)。文件内容是以类似serialize()函数编码的方式处理过的数据。

提醒:无论session是保存在默认路径,还是自定义路径或数据库中,内容都是一样的。我们能改变的是存储位置,而不是存储的内容。

session的生命周期

所有的session从session_start()开始,session文件被打开,数据已数组的形势保存在$_SESSION变量中。当脚本执行完成之后,数据又被重新保存到session文件中。所以,当你设置了一个session值的时候,它并不是马上就会进行存储的。但是,你可以通过执行session_write_close()函数强制进行session数据的保存。

session_set_save_handler() 函数提供了自定义session数据存储的机制。它需要个参数,每个参数都是一个可回调的函数,对应了session生命周期的每个阶段:

  1. 打开session文件open
  2. 关闭session文件close
  3. 读取session数据read
  4. 写入session数据write
  5. 销毁session destroy
  6. 垃圾回收 gc

    PHP5.4之后,可以只传递两个参数,第一个参数是实现了SessionHandlerInterface接口的对象,第二个参数控制是否将函数 session_write_close() 注册为 register_shutdown_function() 函数。

- 阅读剩余部分 -

PHP新增、删除xml节点

假设有如下xml文件(/path/to/index.xml):

<?xml version="1.0" encoding="utf-8"?>
<sitemapindex>
    <sitemap>
        <loc>100.xml</loc>
        <lastmod>2020-05-06</lastmod>
    </sitemap>
    <sitemap>
        <loc>101.xml</loc>
        <lastmod>2020-05-06</lastmod>
    </sitemap>
    <sitemap>
        <loc>102.xml</loc>
        <lastmod>2020-05-06</lastmod>
    </sitemap>
</sitemapindex>

新增loc为103.xml的节点

使用SimpleXMLaddChild方法:

$xml = simplexml_load_file("/path/to/index.xml");
$sitemap = $xml->addChild('sitemap');
$sitemap->addChild('loc', '103.xml');
$sitemap->addChild('lastmod', '2020-05-07');
echo $xml->asXML();

- 阅读剩余部分 -