基于 Laravel6.x 构建的博客应用,支持 Markdown,支持图片拖拽上传,基于 RBAC 权限管理系统
首页
基于 RBAC 的权限管理后台,Dashboard 页面统计了用户总数、文章发布总数、评论率、评论总数、文章支持按天、按月、按年统计、支持按分类、按标签统计……
登录页面
注册页面
支持 GitHub 授权登录
支持邮箱重置密码
同时兼容 HTML 编辑器和 Markdown 编辑器
Markdown 编辑器:支持拖拽粘贴上传图片、预览、全屏、分屏预览
支持代码高亮
项目概述
- 项目名称:larablog
- 项目简介:基于 laravel6.x 开发的博客项目
- 访问地址:https://www.pudongping.com/
功能如下
- 用户认证 —— 注册、登录、退出;
- 个人中心 —— 用户个人中心,编辑资料;
- 用户授权 —— 作者才能删除自己的内容;
- 上传图片 —— 修改头像和编辑文章时上传图片;
- 表单验证 —— 使用表单验证类;
- 重置密码 —— 通过邮箱找回密码
- 文章支持分类、多标签、访问量统计;
- 编辑文章支持 markdown 编辑器 、html 编辑器;
- markdown 编辑器支持拖拽上传图片、截屏粘贴上传图片、语法高亮、预览、全屏、分屏实时预览;
- 文章发布时自动 Slug 翻译,支持使用队列方式以提高响应;
- 站点『活跃用户』计算,一小时计算一次;
- 多角色权限管理 —— 允许站长,管理员权限的存在;
- 后台管理 —— 基于 RBAC 后台数据模型管理;
- 邮件通知 —— 发送新回复邮件通知,队列发送邮件;
- 站内通知 —— 文章有新回复;
- 自定义 Artisan 命令行 —— 自定义活跃用户计算命令;
- 自定义 Trait —— 活跃用户的业务逻辑实现;
- 自定义中间件 —— 记录用户的最后登录时间;
- XSS 安全防御;
- 第三方授权登录,目前支持 GitHub,兼容 Facebook,Twitter,LinkedIn,Google,GitHub,GitLab 和 Bitbucket 的身份验证;
- 支持自定义 meta title、description、keywords;
- 支持友链
- 站点地图
- RSS 订阅
运行环境要求
- Nginx 1.8+
- PHP 7.0+
- Mysql 5.7+
- Redis 3.0+
开发环境部署和安装
本项目代码使用 PHP 框架 laravel6.x 开发,本地开发环境使用 Laravel Homestead。
基础安装
- 克隆源代码
克隆 larablog
源代码到本地:
// gitee
git clone git@gitee.com:pudongping/larablog.git
// GitHub
git clone git@github.com:pudongping/larablog.git
- 安装扩展包依赖
// 先切换到 larablog 项目根目录
cd larablog
// 执行安装命令
composer install
- 生成配置文件
cp .env.example .env
你可以根据情况修改 .env 文件里的内容,如数据库连接、缓存、邮件设置、第三方授权登录等:
DB_HOST=localhost
DB_DATABASE=larablog
DB_USERNAME=homestead
DB_PASSWORD=secret
- 生成数据表及生成测试数据
// 需要生成测试数据则执行:
php artisan migrate --seed
// 不需要生成测试数据则执行:
php artisan migrate
- 生成秘钥
php artisan key:generate
- 创建 storage 软连接
php artisan storage:link
- 赋予 storage 相应权限
// 建议在 Linux 系统中新建一个 www 用户,并设置该用户不可登录系统
useradd -s /sbin/nologin www
// 将项目目录所有权赋予 www 用户
chown -Rf www:www larablog
// 给 storage 目录赋权限
chmod -Rf 0755 larablog/storage/
- 配置 hosts 文件 (如果直接想部署在线上环境,则跳过此步骤)
如果开发环境没有采用 Laravel Homestead 则 ip 映射以你实际为主,一般为 127.0.0.1。我这里使用的 Laravel Homestead 虚拟机的 ip 地址为:192.168.10.10
// Linux 或 MacOS 环境
echo "192.168.10.10 larablog.test" | sudo tee -a /etc/hosts
// Windows 环境
需要打开 C:/Windows/System32/Drivers/etc/hosts 文件,然后新增一行
192.168.10.10 larablog.test
前端安装
- 安装 npm 和 yarn
CentOS / Fedora / RHEL 环境下
文档地址:https://yarn.bootcss.com/docs/install/#centos-stable
- 配置相应的 yum 源
curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
- 之后执行以下任意一条命令,就可以了
sudo yum install yarn
## OR ##
sudo dnf install yarn
Windows 环境下
- 安装 node.js
直接去官网 https://nodejs.org/en 下载安装最新版本。
- 安装 Yarn
请安装最新版本的 Yarn —— http://yarnpkg.cn/zh-Hans/docs/install
- 为 NPM 和 Yarn 配置淘宝镜像,加速安装包下载
npm config set registry=https://registry.npm.taobao.org
yarn config set registry https://registry.npm.taobao.org
- 使用 Yarn 安装前端依赖包
yarn install
或者
npm install
- 监控 resources 文件夹下的资源文件是否有发生改变。在 watch-poll 命令运行的情况下,一旦资源文件发生变化,Webpack 会自动重新编译。
npm run watch-poll
// 如果遇到报错,尝试先执行以下命令更新 npm 到最新版本,之后再次执行监控命令
npm install -g npm
- 编译前端内容
// 运行所有 Mix 任务...
npm run dev
// 运行所有 Mix 任务并缩小输出..
npm run production
访问入口
管理员账号密码如下:
username: 1414818093@qq.com
password: 123456
默认网站第一位用户为站长角色,第二位用户为管理员角色。如果填充了测试数据,则默认所有用户的密码为:123456
==至此,安装完成^_^。enjoy yourself……==
后端扩展包使用情况
扩展包 | 简介描述 | 本项目应用场景 |
---|---|---|
laravel/ui | laravel 6.x UI 脚手架 | 前端页面框架 |
barryvdh/laravel-ide-helper | 能让你的 IDE (PHPStorm, Sublime) 实现自动补全、代码智能提示和代码跟踪等功能 | 代码补全和智能提示 |
barryvdh/laravel-debugbar | 页面调试工具栏 (对 phpdebugbar 的封装) | 开发环境中的 DEBUG |
overtrue/laravel-lang | 支持 52 个国家的语言包 | 翻译 Laravel 自带模板 |
mews/captcha | 图片验证码 | 注册页面图片验证码 |
intervention/image | 图片处理功能库 | 用于图片裁剪 |
summerblue/laravel-active | 方便设置 active 类 | 文章排序添加 active 类 |
mews/purifier | 用户提交的 Html 白名单过滤 | 文章内容的 Html 安全过滤,防止 XSS 攻击 |
guzzlehttp/guzzle | HTTP 请求套件 | 请求百度翻译 API,翻译文章标题,做 SEO 优化 |
overtrue/pinyin | 基于 CC-CEDICT 词典的中文转拼音工具 | 翻译文章标题的备用方案 |
predis/predis | Redis 官方首推的 PHP 客户端开发包 | 缓存驱动 Redis 基础扩展包 |
laravel/horizon | 队列监控 | 队列监控命令与页面控制台 /horizon |
spatie/laravel-permission | 角色权限管理 | 角色和权限控制 |
viacreative/sudo-su | 用户切换 | 调试环境中快速切换登录账号 |
erusev/parsedown | markdown 转换 html 工具 | 文章模块解析 markdown 语法 |
thephpleague/html-to-markdown | html 转换成 markdown 工具 | 文章编辑采用 markdown 编辑器时 |
laravel/socialite | laravel 官方推荐社会化登录 | Github 登录 |
suin/php-rss-writer | rss 订阅生成 | 生成 rss 订阅代码 |
hhxsv5/laravel-s | LaravelS 是 Swoole 和 Laravel/Lumen 之间开箱即用的适配器 | 优化访问速度 |
前端扩展包使用情况
扩展包 | 简介描述 | 本项目应用场景 | |
---|---|---|---|
yarn add @fortawesome/fontawesome-free | Font Awesome 提供了可缩放的矢量图标 | 字体图标库 | |
npm i startbootstrap-sb-admin-2 | 界面简洁美观的皮肤 | cms 后台模板 | |
npm install simplemde | markdown 编辑器 | 文章编辑器 | |
npm install highlight.js | 语法高亮工具 | markdown 编辑器代码语法高亮 | |
npm install inline-attachment | 文本框拖动上传图片工具 | markdown 文本框图片拖动上传 | |
multiselect.js | 多选下拉框 | 文章多选标签 | |
chartjs | 图表插件 | 后台管理界面图表 |
邮箱认证
开发环境时将
.ENV
文件设置为如下所示,将邮箱认证邮件发送至当前日志中,以便调试MAIL_DRIVER=log
生产环境时,建议将
.ENV
文件中相关邮件设置为自己所需配置,以下为默认配置MAIL_DRIVER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null
翻译队列
- 修改
.ENV
文件设置为
# 如果是开发环境的话,就把队列驱动改回 sync 同步模式,也就是说不使用任何队列,实时执行:
QUEUE_CONNECTION=redis
REDIS_CLIENT=predis
- 启动队列系统,队列在启动完成后会进入监听状态
php artisan queue:listen
或者使用
php artisan horizon
文章标题翻译
使用了百度翻译 api,请将 .ENV
中的百度 api 相关信息换成你自己的开发者信息
如果不采用百度翻译翻译文章标题的话,那么不用配置 .ENV
文件中以下配置项
# 百度翻译 APP ID
BAIDU_TRANSLATE_APPID=
# 百度翻译密钥 KEY
BAIDU_TRANSLATE_KEY=
并且也不需要更改
QUEUE_CONNECTION=redis
默认保持为
QUEUE_CONNECTION=sync
这样将会每发一篇文章时,将文章标题直接翻译成拼音达到 slug 的效果。
邮件通知
如果不想要,发表文章评论时有邮件通知,可以不用配置,直接忽略,功能上没有任何影响
- 需要先开启 QQ 邮箱的 SMTP 支持
- 邮箱发送配置 (请将以下配置换成你自己的邮箱配置)
如果你是使用的阿里云 ECS,那么一定要注意,阿里云的 ECS 默认禁用了 25 端口,需要单独申请解封25端口,点我解封阿里云 ECS 25端口,如果你不知道如何解封,请查看 解封步骤。当然替代方案,你可以采用 465 端口,如果你打算采用 465 端口,那么需要将以下配置中的MAIL_PORT
修改为 465,并且也需要将加密类型MAIL_ENCRYPTION
修改为 ssl 即可,这里我使用的是 qq 邮箱,可能其他的邮箱服务有差异,视情况而定吧。
# 使用支持 ESMTP 的 SMTP 服务器发送邮件
MAIL_DRIVER=smtp
# QQ 邮箱的 SMTP 服务器地址,必须为此值
MAIL_HOST=smtp.qq.com
# QQ 邮箱的 SMTP 服务器端口,必须为此值
MAIL_PORT=25
# 请将此值换为你的 QQ + @qq.com
MAIL_USERNAME=xxxxxxxxxxxxxx@qq.com
# 密码是我们第一步拿到的授权码
MAIL_PASSWORD=xxxxxxxxx
# 加密类型,选项 null 表示不使用任何加密,其他选项还有 ssl,这里我们使用 tls 即可,如果出现报错的话,多半是因为这个 smtp 主机不支持 TLS,那么只需要将此项设置为 null 即可。
MAIL_ENCRYPTION=tls
# 此值必须同 MAIL_USERNAME 一致
MAIL_FROM_ADDRESS=xxxxxxxxxxxxxx@qq.com
# 用来作为邮件的发送者名称
MAIL_FROM_NAME=番茄炖土豆的个人博客
- 如果需要支持队列,请将
.ENV
配置文件中,设置成
QUEUE_CONNECTION=redis
用户切换调试
默认只在调试模式 .ENV
文件中
APP_DEBUG=true
时启用,且 config/sudosu.php
文件中
// 允许使用的顶级域名
'allowed_tlds' => ['dev', 'local', 'test'],
顶级域名(Top Level Domain)加入你域名的顶级域名
第三方授权登录
目前项目中只支持 github 授权登录,因为只申请了 GitHub 的 OAuth application,如果你也需要使用 GitHub 作为第三方授权登录,那么需要按照以下步骤进行:
- 在 GitHub 上注册一个 OAuth application
- Application name:你可以填写你自己的应用名称,比如:myWebBlog
- Homepage URL:首页连接地址需要添加你自己的,比如:http://larablog.test
- Application description:应用描述可以随便填写,比如:自己的博客
- Authorization callback URL:授权回调地址,一定要填写成: <Your domain>/login/github/callback ,比如,我这里则需要填写成:http://larablog.test/login/github/callback
- 注册成功之后,需要在
.ENV
配置文件中填写申请成功的 Client ID 和 Client Secret。填写好之后,直接访问 http://larablog.test/login/github 即可支持 GitHub 第三方授权登录,如果不设置.ENV
配置文件,则登录、注册页面不会显示 GitHub 第三方授权登录入口。
# Github Client ID
GITHUB_CLIENT_ID=
# Github Client Secret
GITHUB_CLIENT_SECRET=
扩展其它第三方授权登录。
Socialite 目前支持 Facebook,Twitter,LinkedIn,Google,GitHub,GitLab 和 Bitbucket 的身份验证。本项目已经对以上支持的第三方登录做了兼容性处理,如果我们需要支持以上除 GitHub 以外的应用(因为目前已经设置好了 GitHub 相关的配置),那么我们只需要按照以下的步骤配置即可。这里以 Google 为例子。
- 第一步:申请
google
的 Client ID 和 Client Secret。 - 第二步:将申请的 Client ID 和 Client Secret 填写入
.ENV
配置文件中
GOOGLE_CLIENT_ID="your google client id"
GOOGLE_CLIENT_SECRET="your google client secret"
- 第三步:配置 app/services.php
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'), // google 客户端授权 ID
'client_secret' => env('GOOGLE_CLIENT_SECRET'), // google 客户端授权密钥
'redirect' => '/login/google/callback', // 授权回调链接 如果 redirect 配置项包含的是相对路径,系统会自动将其转化为完整 URL
],
- 第四步:将第三方服务添加到
app/Models/Auth/User.php
=>$allowedProviders
数组中
public static $allowedProviders = ['github', 'google'];
- 第五步:直接访问 <your domain>/login/google 即可
自定义 Artisan 命令
命令 | 说明 | Cron |
---|---|---|
php artisan larablog:calculate-active-user | 生成活跃用户 | 一个小时运行一次 |
php artisan larablog:sync-article-view-count | 同步文章的访问量 | 每天早上 0 点准时 |
php artisan larablog:sync-user-actived-at | 从 Redis 中同步最后登录时间到数据库中 | 每天早上 0 点准时 |
计划任务
当前计划任务主要是计算主页右侧 「活跃用户」
artisan
命令为:
php artisan larablog:calculate-active-user
同步文章的访问量
artisan
命令为:
php artisan larablog:sync-article-view-count
和同步 「用户最后活跃时间」 到数据库
artisan
命令为:
php artisan larablog:sync-user-actived-at
并且已经在 调度器
中设置好了相关代码。(调度器在 app/Console/Kernel.php 文件的 schedule 方法中定义)
使用 Linux 系统的 Cron 计划任务需执行
export EDITOR=vi && crontab -e
然后填入以下内容(注意将项目根目录换成你自己的)
这里我的项目根目录为:/home/vagrant/Code/larablog
* * * * * php /home/vagrant/Code/larablog/artisan schedule:run >> /dev/null 2>&1
如果不设定计划任务的话,直接执行以上 Artisan 命令的话会是如下情况:
「活跃用户」将每 65 分钟重新生成一次,设定计划任务的话,默认一个小时重新生成一次。
「用户最后活跃时间」将不会同步到数据库中,将会直接从 Redis 中获取,如果 Redis 中不存在,则以用户注册时间替代。
队列清单
文件路径 | 说明 | 调用时机 |
---|---|---|
app\Notifications\ArticleReplied.php | 通知文章作者有新评论回复 | 文章被评论以后 App\Observers\Portal\Article\ReplyObserver@created |
app\Jobs\TranslateSlug.php | 将文章标题翻译为 Slug | 文章保存时 App\Observers\Portal\Article\ArticleObserver@saved |
线上部署
如果需要优化网站打开速度,可依次进行如下步骤:
- 压缩前端代码
npm run prod
缓存路由
# 缓存路由 php artisan route:cache # 清空路由缓存 php artisan route:clear
缓存配置文件
# 缓存配置文件 php artisan config:cache # 清空配置文件缓存 php artisan cache:clear
composer 优化
sudo composer dump-autoload --optimize
- 类映射加载优化
在 laravel 6.x
中,会生成 bootstrap/cache/config.php
和 bootstrap/cache/packages.php
和 bootstrap/cache/routes.php
和 bootstrap/cache/services.php
这四个文件。
php artisan optimize
# 清空类映射
php artisan optimize:clear
- 使用 swoole 加速网站
在项目根目录下执行以下命令,以守护进程的方式运行 laravelS
php bin/laravels start -d
参考以下内容配置 nginx 配置
upstream swoole {
# 如果是使用 laradock ,请将 127.0.0.1 更改为 workspace
server 127.0.0.1:5200 weight=5 max_fails=3 fail_timeout=30s;
keepalive 16;
}
server {
listen 80;
server_name pudongping.com www.pudongping.com;
root /www/wwwroot/larablog/public;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri @laravels;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /www/wwwlogs/pudongping.com.log;
error_log /www/wwwlogs/pudongping.com.error.log;
sendfile off;
client_max_body_size 100m;
location @laravels {
# proxy_connect_timeout 60s;
# proxy_send_timeout 60s;
# proxy_read_timeout 120s;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-PORT $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header Server-Protocol $server_protocol;
proxy_set_header Server-Name $server_name;
proxy_set_header Server-Addr $server_addr;
proxy_set_header Server-Port $server_port;
# “swoole”是指upstream
proxy_pass http://swoole;
}
location ~ /\.ht {
deny all;
}
}
如果是使用 laradock 的话,还需要将 .env
添加监听地址为 workspace
LARAVELS_LISTEN_IP=workspace
# 设置后台启动 laravelS 服务,如果需要查看则执行 ps -ef|grep laravels 命令
LARAVELS_DAEMONIZE=true
代码规范
遵循 PSR-2 编码风格规范
遵循 PSR-12 编码规范扩充
其他
代码中涵盖了丰富的注释,如果仍有不清楚之处,可以给我留言。
如果你觉得还不错,请帮我点一下 Star,不胜感激 !❤(❤´艸`❤)
License
源代码基于 MIT 协议发布。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。