进步始于交流
收获源于分享

WordPress配合Nginx搭建私有化站点

WordPress 很多插件能够实现私有化,但都是基于默认的 Apache 服务器进行的配置,自动修改 .htaccess 的配置,从插件看配置生效的,实际上如果用的是其他服务器则没有任何用途,本文基于 Nginx 进行私有化站点搭建说明,包括nginx.conf文件配置、插件推荐、function.php文件配置等

先搭建公开站点

参考官方文档,进行基本配置即可

其中nginx可参考的核心配置:

server {
listen 14000 ssl default_server;
listen [::]:14000 ssl default_server;
server_name _;
cert.conf*;
ssl_prefer_server_ciphers on;
root "/xxxxxxx/wordpress";
index index.html index.htm index.cgi index.php index.php5 ;
location ~* \.(php[345]?|phtml)$ {
    fastcgi_pass unix:/run/xxxx/php.sock;
    fastcgi_connect_timeout 60s;
    fastcgi_read_timeout 30s;
    fastcgi_send_timeout 30s;
    include fastcgi.conf;
}
# 引入自定义配置 -- 后面的所有都只修改这个自定义文件
include /usr/xxxx/customize/user.conf*;
}

插件推荐

安全与用户管理

  • All In One WP Security:安全工具,可以限制注册,建议私有站点限制一下,所有注册账号都需要审核,而不是给一个最低权限的角色,毕竟登录进来了就可以做很多事情了。

  • Members:权限管理工具,这里可以配置开启私有站点限制用户必须登录,同时也可以创建自定义权限(可用于自定义代码片段里面针对特定文章类目的权限管理,这个需要再另一个插件编写)

  • Akismet Anti-Spam: Spam Protection:评论安全插件,可以过滤识别垃圾消息等,根据站点特征决定是否启用,如果是陌生人邀约制建议使用,不排除有人账号被盗等情况。

  • WP Mail SMTP:邮件SMTP工具,根据注册机制决定是否使用,如果允许自行注册需要安装这个插件给注册人发邮件,如果是管理员主动创建账号则可以省掉。

编辑器相关

  • 经典编辑器 + The Paste:不喜欢古登堡(块编辑器)的,可以通过这个插件使用以前的编辑方式。The Paste 是为了实现图片粘贴自动上传插入到文章的工具,省的每张图片费劲的上传、插入。

  • WP Editor.md:Markdown 语言编辑器,同时支持mermaid.js工具进行流程图、时序图绘制等。

  • Table of Contents Plus:目录自动生成工具,如果站点文章特点都是长篇文章可以使用此插件自动生成目录。

  • Mammoth .docx converter:支持 word 文档直接上传识别成文章的工具。

  • Shortcodes Ultimate:简码,很方便的工具,可以在文章中插入很多现成的组件,让内容更有组织层次感,根据站点文章特征选择是否需要此功能。

  • MarkText:这不是插件,一个独立的跨平台app,可以在本地进行MarkDown文档撰写,可与上面WP Editor配合,可替代已经成为收费软件的Typora,相比较VS code更轻量级。

其他工具

  • WPForms Lite:表单工具,如果想收集意见反馈 or 部分人可见的投票等功能,都可以使用这个表单。
  • Code Snippets:自定义代码片段。不建议直接修改functions.php文件,建议在这个插件里面操作,如果改错了网站挂了,也可以快速的去数据库找到此插件的表进行调整,原则上Wordpress官方框架不做任何改动。
  • WP Super Cache:按需使用,私有站点可能每个人看到的内容不一样,缓存不一定好。

functions.php 代码调整

建议使用上面提到的 Code Snippets 插件进行框架代码增补,而不是直接修改文件。

注册登录页面logo调整

私有站点免不了登录操作,对于新用户来说首次访问网站看到的大概率就是这个页面,这是让自己的网站的logo深入人心的时刻,建议改一下。

注意 把logo 放到当前选中主题的根目录下,因为 get_bloginfo('template_directory')获取的是当前主题的根目录,如果需要其他路径,请特别调整。

特别注意,如果放到了媒体库,请注意是否媒体库已经私有化了,如果按照后文的调整把媒体库私有化了非登录无法查看,此时图片不能放到媒体库,因为这个登录页面用户还没登陆(当然也可以在规则里面特别调整一下把这个logo文件设定为免登录查阅)。

<?php
//登录注册页面logo删除
function coologic_custom_loginlogo() {
echo '<style type="text/css">
h1 a {background-image: url('.get_bloginfo('template_directory').'/coologic_logo.png) !important; }
</style>';
}
add_action('login_head', 'coologic_custom_loginlogo');

//登录注册页面logo跳转连接改为当前站,也可以改成其他地址
function coologic_custom_login_url($url) {
    return get_bloginfo('url'); 
}
add_filter( 'login_headerurl', 'coologic_custom_login_url');

删除管理后台左上角的logo

这个logo点击等都会跳转到 WordPress网站,如果是内部站点且内网情况,可能网站都打不开,此时可以删除这个logo。

<?php
//删除管理后台左上角的logo
function coologic_remove_admin_site_wordpress_logo() {
    global $wp_admin_bar;
    $wp_admin_bar -> remove_menu('wp-logo');
}
add_action('wp_before_admin_bar_render', 'coologic_remove_admin_site_wordpress_logo');

提效脚本-上传图片默认全尺寸展示

如果是内部站点,内网访问,带宽任性,此时可以改成默认全尺寸,省的使用经典编辑器的时候默认中尺寸,有些图会模糊,还需要人工调整,影响文章撰写效率。

<?php
function coologic_image_size_names_choose($image_sizes){
  unset($image_sizes['medium']);
  unset($image_sizes['large']);
  unset($image_sizes['thumbnail']);
  return $image_sizes;
}
add_filter('image_size_names_choose', 'coologic_image_size_names_choose');

## 复杂权限控制

使用Member插件可以新建角色、给角色赋权,但是 wp 只实现了默认的权限,复杂的逻辑就需要定制权限了,可以用 Member 创建自定义权限,通过下述代码实现权限的用途。

理论上是可以针对用户id、针对角色直接进行控制,但仍然建议使用相对正规的自定义权限、角色赋权、实现自定义权限控制的方式进行全站权限管控。否则人员变动、角色增减等可能导致信息泄露,后台只能配置用户与角色的关系,不可能随着人员随时调整代码。

下面是一个针对自定义权限 coologic_read_all_special_category权限的控制逻辑,目标是:只有拥有这个权限的角色,才能查看 16、17、18类目的文章,没有权限的人打开这类文章会直接跳转到网站首页。实现置顶类目文章对指定角色可见。

coologic_read_all_special_category 权限是在 Memeber 插件创建的,创建后还需要编辑各个角色,确定哪些角色有这个权限。

<?php
//这里换一个写法,直接把函数置入
add_action('template_redirect',function(){
    //没有coologic_read_all_special_category权限的用户,禁止查看 16   17   18  类目的内容
    //is_single 是否为文章
    //类目必须穿类目id,16不是类目名称,id可以编辑类目,在url里找到
    if(in_category(array( 16,17,18 )) && !current_user_can('coologic_read_all_patents_category') && !is_home() && is_single()) {
        $url = home_url();
        wp_safe_redirect($url);
        exit();
    }
});

Nginx 私有化配置调整

固定链接配置-伪静态

当前所有文章的链接都是 xxx/?id=xx 这类查询语句路径,如果想要改成一种固定格式,会发现网页会 404,因为 nginx 查不到文件位置,因此需要实现伪静态能力,Wordpress 自身已提供对应php文件,我们只需要把固定链接指向即可

特别注意 nginx 的注释标记是 # 号,别用 // 否则解析失败

# 引导所有链接,尝试直接访问文件如果不存在,就访问根目录的 /index.php 文件并附带参数
location / {
  try_files $uri $uri/ /index.php?$args;
}
# 针对管理后台进行重写,避免伪静态以后管理页异常
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

媒体库私有化

经过上述的操作,我们可以体验到,不登录是无法查看任何文章页面了。

但不要忽视一个特殊的地方:媒体库。可以尝试一下不登录的情况下是否可以直接访问、下载一个媒体文件?正茬是可以访问,此时如果想要全站私有化,需要限制媒体库文件访问必须是用户已登录状态。

这时候使用 functions.php 文件调整已经无法做到了,因为静态文件是服务器直接路由的,没有走到任何 php 代码,直接由 Nginx 查到了文件就返回了,因此我们需要配置在访问媒体库路径时,通过php文件进行处理

首先进行nginx 配置

location ~ ^/wp-content/uploads/(.*) {
    # 把所有请求都带到这个指定php执行文件,若执行失败或异常都返回403,文件放在根目录即可
    try_files /coologic_uploads_file_read.php =403;
    root "/xxxxx/wordpress"; # 指向根目录
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; # 必须要有这个否则拿不到参数
    include fastcgi_params;
    # 这个值一定要和上面的核心配置值一样,不要用不同的sock,否则会可能导致网站错乱
    fastcgi_pass unix:/run/xxxx/php.sock;
}

下面是 coologic_uploads_file_read.php 逻辑,其中特别注意要处理url里中文被编码的问题。如果自己的链接中对中文进行了更复杂的编码,请根据情况调整解码逻辑,确保能找到文件。

<?php
require_once('wp-load.php');

//判断是否登录,未登录则跳到登录页
If (!is_user_logged_in()){
    $upload_dir = wp_upload_dir();
    wp_redirect( wp_login_url( $upload_dir['baseurl'] . '/' . $_GET[ 'file' ]));
    exit();
}


//获取目录路径地址
list($basedir) = array_values(array_intersect_key(wp_upload_dir(), array('basedir' => 1)))+array(NULL);

//开始获取文件名($_GET[ 'file' ] 是文件名,若未取到需要用$_SERVER['REQUEST_URI'] 但这样就是完整的路径了
$getFile = isset($_GET[ 'file' ]) ? $_GET[ 'file' ] : $_SERVER['REQUEST_URI'];
//如果是完整的路径就去掉前缀
$getFile = str_replace('..', '', $getFile);
$getFile = str_replace('wp-content/uploads/', '', $getFile);

//拼接处最终的文件地址
$file =  trailingslashit($basedir) . $getFile;

//判断文件存在性
if (!$basedir || !is_file($file)) {
    //尝试解码url查询,有的url存在中文的问题,中文文件名会被自动编码为 %xx%xx,但硬盘里文件名是中文,需要解码
    if(is_file(urldecode($file))) {
        //存在就修改为解析后的路径
        $file = urldecode($file);
    } else {
        //仍然没找到返回404+内容,如果需要调试请使用注释的一行,但不建议长期使用,会透出自己的目录结构
        status_header(404);
        die('455 coologic File not found.');
        //die('455 File not found. file_path:'.$file.'#######'.urldecode($file));
    }
}

//构建返回结果
$mime = wp_check_filetype($file);
if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
    $mime[ 'type' ] = mime_content_type( $file );
if( $mime[ 'type' ] )
    $mimetype = $mime[ 'type' ];
else
    $mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 );
header( 'Content-Type: ' . $mimetype );

//返回文件
readfile( $file );

可能还有其他遗漏,欢迎大家补充。

赞(0) 打赏
未经允许不得转载:Coologic » WordPress配合Nginx搭建私有化站点

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏