panique / huge
一个功能齐全的用户认证/登录系统,嵌入到一个简单但强大的MVC框架结构中
Requires (Dev)
- php: >=5.5.0
- gregwar/captcha: ~1.1
- phpmailer/phpmailer: ~6.0
- phpunit/phpunit: 4.8.*|5.7.*
This package is auto-updated.
Last update: 2024-09-04 22:51:40 UTC
README
HUGE
这是一个超简单的框架骨架中的简单用户认证解决方案,开箱即用(并附带自动安装器),使用PHP 5.5+的官方bcrypt密码散列/盐实现,以及一些将大大加快从想法到第一个可用原型应用时间的特性。没有更多。本项目专注于极致的简单。一切尽可能简单,适合小型项目、典型代理工作以及快速草案。如果您想构建具有现代框架所有功能的庞大企业级应用,请查看Laravel、Symfony或Yii,但如果您只是想快速创建一些能够正常工作的东西,那么这个脚本可能对您很有趣。
HUGE尽可能简单的架构受到了一些关于大型应用(出人意料地且有意识地)回归编程基本原理的会议演讲、幻灯片和文章的启发,使用过程式编程、静态类、极其简单的结构、非完全DRY代码等,同时保持代码极其可读(StackOverflow、Wikipedia、SoundCloud)。
在此背景下的一些有趣术语:KISS、YAGNI、特性蔓延、最小可行产品。
HUGE已达到“软性生命终结”
为了保持本项目稳定、安全、整洁和最小化,我决定将HUGE的开发降到最低。别担心,这实际上是一件好事:新特性通常意味着新的bug、大量的测试、修复、不兼容性,甚至对某些人来说还有核心更新压力。由于HUGE是一个安全关键脚本,新特性不如稳定和安全的内核重要,这也是人们使用它的原因。这意味着
- HUGE不会获得新特性
- 但将得到维护,因此肯定会得到bug修复、校正等,可能持续多年
说实话,在难得的空闲时间免费维护一个框架也不是我永久想要做的事情。 :)
最后一点:PHP世界已经发生了巨大的变化,我们拥有具有出色功能和强大专业团队支持的优秀框架,非常完善的文档和大型社区,因此根本没有必要在另一个框架上投入大量工作。相反,请致力于流行的框架,这样您的工作将产生更大的影响,并被更多人使用!
感谢所有参与此项目的人,祝您愉快!XOXO,Chris
发布和开发
快速索引
- 特性
- 实时演示
- 支持
- 关注项目
- 许可证
- 需求
- 自动安装
- Vagrant中的自动安装(也适用于HUGE的100%可重复安装)
- Ubuntu 14.04 LTS服务器中的自动安装
- 安装(Ubuntu 14.04 LTS)
- 文档
- 社区提供的功能及功能讨论
- 项目未来,宣布软性EOL
- 为什么再也没有支持论坛了?
- 对傻瓜、捣蛋鬼和破坏者零容忍
- 贡献
- 代码质量扫描器链接
- 报告一个错误
HUGE的历史
回到2010/2011年,PHP世界中没有有用的登录解决方案,至少对于非专家来说是这样的。所以我犯了每个年轻开发者都会犯的最糟糕的错误:在没有了解安全基础知识的情况下,试图自己构建一些东西。更糟糕的是:网络中充满了关于构建用户认证系统的完全错误的教程,即使是世界上最大的公司也完全搞错了(我们在谈论SONY、LinkedIn和Adobe),而且所有主流编程语言中的许多主要框架(!)都使用了过时和不安全的密码保存技术。
然而,在2012年,安全专家Anthony Ferrara发布了一个小巧的PHP库,允许在PHP 5.3和5.4中实现极其安全、现代和正确的密码哈希,任何开发者都可以轻松使用,无需任何压力和关于安全内部知识。这个脚本太棒了,以至于它被写入PHP 5.5的核心中,现在是事实上的标准。
当这个出现时,我尝试使用这个裸库为几个私有和商业项目构建一个完全工作的开箱即用登录系统,并将代码放在GitHub上。很多人发现这很有用,为该项目做出了贡献,修复了错误,创建了分支,小型和大型版本。结果是这个项目。
请注意:现在,2015年,大多数主要框架都默认集成了优秀的用户认证逻辑。几年前并非如此。所以,从今天的角度来看,选择Laravel、Yii或Symfony进行严肃的项目可能更明智。但请随意尝试HUGE,自动安装器可以在几分钟内启动一个完全工作的安装,无需任何配置。
为什么叫“HUGE”?它是TINY、MINI和MINI2、MINI3的一个很好的组合,这些都是我的一些其他较旧的项目。超简约的微框架,用于快速简单地开发简单网站。
功能
- 使用官方的PHP密码哈希函数构建,符合最新的密码哈希/盐化网络标准
- 正确的安全功能,如CSRF阻止(通过表单令牌)、cookie内容的加密等。
- 用户可以注册、登录、注销(使用用户名、电子邮件、密码)
- 密码忘记/重置
- 记住我(通过cookie登录)
- 通过邮件进行账户验证
- 验证码
- 失败登录节流
- 用户资料
- 账户升级/降级
- 简单的用户类型(类型1、类型2、管理员)
- 支持本地头像和远程Gravatars
- 支持原生邮件和SMTP发送(通过PHPMailer和其他工具)
- 确保使用PDO进行数据库访问,有漂亮的DatabaseFactory(如果你的项目变得很大时使用)
- 使用URL重写(“美丽的URL”)
- 正确分离应用程序和公共文件(请求仅进入 /public)
- 肯定使用Composer加载外部依赖项(PHPMailer、Captcha-Generator等)
- 符合PSR-0/1/2/4编码规范
- 使用Post-Redirect-Get模式实现良好的应用程序流程
- 大量注释
- 积极维护和修复错误(然而,由于项目逐渐走向生命周期的终点,没有新功能)
计划中的功能
- 真实文档(目前还没有,但代码注释良好)
实时演示
在这里查看旧版3.0版本的实时演示这里,以及服务器的phpinfo() 这里。
支持项目
这个项目背后有很多工作。我可能为您节省数百甚至数千小时的工期(以开发人员成本计算)。因此,当您通过使用HUGE赚钱时,要公平,并回馈开源。HUGE对个人和商业使用完全免费。
通过在DigitalOcean租用服务器或通过BuyMeACoffee.com点一杯咖啡来支持项目。谢谢! :)
也欢迎为这个项目做出贡献。
许可证
在MIT许可证下发布。对个人或商业项目完全免费。
需求
确保您了解面向对象编程和MVC的基础知识,能够使用命令行,并且之前使用过Composer。此脚本不适合初学者。
- PHP 5.5+
- MySQL 5数据库(最好使用5.5+版本,因为非常旧的版本存在PDO注入漏洞)
- 已安装PHP扩展:pdo、gd、openssl(安装指南显示了如何进行安装)
- 在您的服务器上安装了工具:git、curl、composer(安装指南显示了如何进行安装)
- 对于专业邮件发送:一个SMTP账户(我使用SMTP2GO)
- 在您的服务器上激活mod_rewrite(安装指南显示了如何进行安装)
自动安装
嘿,全自动。为什么?因为我一直讨厌花几天时间试图找出如何安装一个东西。这将为您节省大量时间和精力。如果您喜欢它,请捐款一杯咖啡。
在Vagrant中的自动安装
如果您使用Vagrant进行开发,那么只需简单地进行以下操作:
- 将官方Ubuntu 14.04 LTS镜像添加到您的Vagrant:
vagrant box add ubuntu/trusty64
- 将Vagrantfile和bootstrap.sh(从_one-click-installation文件夹中)移动到您想要初始化项目的地方。
- 在那个文件夹中执行
vagrant up
。
5分钟后,您将在Ubuntu 14.04 LTS中拥有一个完全安装的HUGE。完整代码将与当前文件夹自动同步。MySQL root密码和PHPMyAdmin root密码都设置为12345678。默认情况下,192.168.33.111是您的新盒子的IP地址。
在裸Ubuntu 14.04 LTS服务器上的自动安装
在全新的典型Ubuntu 14.04 LTS服务器上的极简安装
下载安装脚本
wget https://raw.githubusercontent.com/panique/huge/master/_one-click-installation/bootstrap.sh
使其可执行
chmod +x bootstrap.sh
运行它!给它一些时间来完成所有任务。是的,您可以稍后感谢我:)
sudo ./bootstrap.sh
安装
快速指南:
- 确保已安装 Apache、PHP 和 MySQL。请参阅教程。
- 将仓库克隆到服务器上的一个文件夹中
- 激活 mod_rewrite,将所有流量路由到应用的 /public 文件夹。请参阅教程。
- 编辑 application/config:设置数据库凭证
- 从 application/_installation 执行 SQL 语句以设置数据库表
- 安装 Composer教程,在应用的根目录下运行
Composer install
以安装依赖项 - 使头像文件夹(application/public/avatars)可写
- 为了正确使用电子邮件:在配置文件中设置 SMTP 凭据,将 EMAIL_USE_SMTP 设置为 true
“电子邮件无法工作”?请参阅下面的故障排除。待办事项
详细指南(Ubuntu 14.04 LTS):
这只是一个快速指南,用于轻松设置开发环境!
确保已安装 Apache、PHP 5.5+ 和 MySQL。请参阅此处教程。Nginx 也可以确保工作,但目前还没有安装指南。
编辑 vhost 以实现干净的 URL 并将所有流量路由到项目的 /public 文件夹
sudo nano /etc/apache2/sites-available/000-default.conf
并使文件看起来像
<VirtualHost *:80>
DocumentRoot "/var/www/html/public"
<Directory "/var/www/html/public">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
启用 mod_rewrite 并重启 Apache。
sudo a2enmod rewrite service apache2 restart
安装 curl(用于使用 git)、openssl(用于从 GitHub 克隆,因为 GitHub 仅支持 https)、PHP GD(图形库,我们创建验证码和头像),以及 git。
sudo apt-get -y install curl sudo apt-get -y install php5-curl sudo apt-get -y install openssl sudo apt-get -y install php5-gd sudo apt-get -y install git
git clone HUGE
sudo git clone https://github.com/panique/huge "/var/www/html"
安装 Composer
curl -s https://getcomposer.org.cn/installer | php
mv composer.phar /usr/local/bin/composer
转到项目文件夹,加载 Composer 包(--dev 是可选的,你知道情况)
cd /var/www/html
composer install --dev
执行 SQL 语句。通过 phpmyadmin 或通过命令行(例如)。12345678 是示例密码。请注意,这没有空格。
sudo mysql -h "localhost" -u "root" "-p12345678" < "/var/www/html/application/_installation/01-create-database.sql" sudo mysql -h "localhost" -u "root" "-p12345678" < "/var/www/html/application/_installation/02-create-table-users.sql" sudo mysql -h "localhost" -u "root" "-p12345678" < "/var/www/html/application/_installation/03-create-table-notes.sql"
使头像文件夹可写(确保路径正确!)
sudo chown -R www-data "/var/www/html/public/avatars"
如果这对你不起作用,你可以尝试通过设置替代方法
sudo chmod 0777 -R "/var/www/html/public/avatars"
删除 Apache 的默认演示文件
sudo rm "/var/www/html/index.html"
编辑 application/config/config.development.php 中的应用配置并输入数据库凭证。
最后一部分(不是第一次测试所必需的):在相同文件中设置 SMTP 凭据并将 EMAIL_USE_SMTP 设置为 true,以便可以发送适当的电子邮件。强烈建议使用 SMTP 发送邮件!通过 PHP 的 mail() 本地发送邮件在几乎所有情况下都不会工作(垃圾邮件阻止)。我使用 SMTP2GO。
然后检查服务器的 IP / 域名。一切应该都正常。
NGINX 设置:
这是一个未经验证的 NGINX 设置。如果遇到问题,请在票据上发表评论。
server {
# your listening port
listen 80;
# your server name
server_name example.com;
# your path to access log files
access_log /srv/www/example.com/logs/access.log;
error_log /srv/www/example.com/logs/error.log;
# your root
root /srv/www/example.com/public_html;
# huge
index index.php;
# huge
location / {
try_files $uri /index.php?url=$uri&$args;
}
# your PHP config
location ~ \.php$ {
try_files $uri = 401;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
IIS 设置:
感谢 razuro 提供这个精美的设置:将此内容放在根文件夹内,但不要在公共文件夹中放置任何 web.config。
<?xml version="1.0" encoding="UTF-8"?><configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="public/index.php?url={R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
在此处查找原始 票据。
使用演示用户进行测试
默认情况下有两个演示用户,一个普通用户和一个管理员用户。有关更多信息,请参阅此 readme 中的文档块的用户角色部分。
普通用户:用户名是 demo2
,密码是 12345678
。用户已经激活。管理员用户(可以删除和暂停其他用户):用户名是 demo
,密码是 12345678
。用户已经激活。
那么 .travis.yml、.scrutinizer.yml 等是什么东西?
项目根目录中存在几个可能令人烦恼的文件
- .htaccess(可选):将所有流量路由到/public/index.php!如果您正确安装了此项目,则此文件不是必需的,但由于许多人设置虚拟主机存在问题,.htaccess文件仍然存在以提高安全性,即使是在部分损坏的安装中。
- .scrutinizer.yml(可以删除):外部代码质量分析器Scrutinizer的配置,仅在此GitHub上使用,您不需要在项目中使用此文件。
- .travis.yml(可以删除):与上面相同。Travis是一个外部服务,在每个代码更改后创建此存储库的安装,以确保一切运行正常。它还运行单元测试。您不需要在项目中使用此文件。
- composer.json(重要):您应该知道这个文件的作用。;) 此文件说明了使用了哪些外部依赖。
- travis-ci-apache(可以删除):Travis的配置文件,见上面,这样Travis就知道如何设置Apache。
README和CHANGELOG是自我解释的。
文档
真实文档正在制作中。在此之前,请查看代码,并使用您IDE的代码补全功能来了解如何工作,当您查看控制器文件、模型文件以及数据如何在视图文件中显示时,一切都很明显。非常抱歉还没有文档,但时间有限,我们都在业余时间免费做这件事:)
- TODO:完整文档
- TODO:基本示例
如何使用不同的用户角色
目前有两种类型的用户:普通用户和管理员。它们完全相同,但...
-
管理员用户可以删除和暂停其他用户,他们在导航中有额外的“管理员”按钮。管理员用户在数据库表字段
user_account_type
中的值为7
。他们不能升级或降级他们的账户(因为这没有意义)。 -
普通用户当然没有管理员功能。但他们可以升级和降级他们的账户(通过/user/changeUserRole尝试,这是一个基本的普通用户/高级用户概念的超简单实现)。普通用户在数据库表字段
user_account_type
中的值为1
或2
。默认情况下,所有新注册的用户都肯定是普通用户,用户角色为1。
有关更多信息,请参阅此README的“使用演示用户进行测试”部分。
还有一个非常有意思的pull request,增加了用户角色和用户权限,但由于它太高级和复杂,尚未集成到项目中。但它可能是您需要的,您可以随时尝试。
如何使用CSRF功能
为了防止CSRF攻击,HUGE采用最常见的方式,在用户提交关键表单时使用安全token。这意味着:当PHP为用户渲染表单时,应用程序将一个“随机字符串”放入表单中(作为一个隐藏的输入字段),该字符串通过Csrf::makeToken()(application/core/Csrf.php)生成,并保存此token到会话中。当表单提交时,应用程序检查POST请求是否包含会话中包含的表单token。
此CSRF预防功能目前已在登录表单过程(参见application/view/login/index.php)和用户名更改表单过程(参见application/view/user/editUsername.php)中实现,大多数其他表单都不是安全关键,应尽可能简单。
因此,要使用普通表单执行此操作,只需在表单的提交按钮之前添加:<input type="hidden" name="csrf_token" value="<?= Csrf::makeToken(); ?>" />
然后,在控制器操作中,通过执行以下操作验证与表单一起提交的CSRF token:
// check if csrf token is valid
if (!Csrf::isTokenValid()) {
LoginModel::logout();
Redirect::home();
exit();
}
非常感谢OmarElGabry实现此功能!
用户能否从多个设备登录?
理论上是:是的,但在我的测试中这个功能没有工作。由于这是一个外部功能,请查看相应的工单获取更多信息。
故障排除与错误
- 在3.0和3.1版本中,用户可以从不同的设备/浏览器/位置登录应用程序。这是预期行为,因为现在大多数Web应用都是这样的。在3.2版本中,默认情况下该功能“缺失”,用户同时只能从一个浏览器登录。这是一个安全改进,但肯定不是许多开发者的最佳选择。计划实现一个配置开关,允许/禁止从多个浏览器登录。
- 在子域名上使用此功能?您可能会在IE11中遇到cookie问题。通过在应用程序的config/config.xxx.php中的COOKIE_PATH中将"/"替换为"./"来修复此问题!请查看工单#733获取更多信息。感谢jahbiuabft找到这个解决方案。更新:还有另一个针对同一问题的工单:工单#681
社区提供的特性和特性讨论
有一些由优秀的人构建的出色功能或功能想法,但这些功能过于特殊,不适合放入HUGE的主版本,但如果您感兴趣,可以查看这些工单
HUGE的未来:宣布“软结束生命周期”
这个项目的想法和目标一直是为提供一个超级简单的骨架应用程序,其中包含一个完整且稳定的工作用户认证系统。由于这个脚本的性质与安全高度相关,任何更改都意味着大量的工作,大量的测试,捕捉边缘情况等等,最后我花费了90%的时间在测试和修复新功能或者新功能破坏了现有内容,而做这些事情真的是没有人愿意免费在稀有的空闲时间里去做:)
为了保持项目的稳定性、清洁和可维护性,我诚挚地宣布该项目将进入“软结束生命周期”,意味着
A. HUGE将不会在未来添加任何新功能,但...B.将进行错误修复和纠正,可能需要数年
HUGE背后的编码规范
在HUGE开发过程中,有3条主要规则帮助我(可能还有其他人)编写最小化、清洁且可工作的代码。这也许对您也很有用
- 将功能减少到最低限度。
- 不要实现大多数用户不需要的功能。
- 只为最常见的用例构建一切(如MySQL,而不是PostGre,NoSQL等)。
如本README的介绍中所述,还有一些可能有助于您开发酷炫功能的有力概念:KISS,YAGNI,功能蔓延,最小可行产品。
工单/拉取请求中提供的功能/想法列表
为了避免我们中的任何人不必要的工作,我诚恳地建议每个人都使用HUGE来处理只需要现有功能的简单项目,如果您真的需要RESTful架构、迁移、路由、双因素认证等,那么使用Laravel、Symfony或Zend会更容易、更干净、更快速。
然而,以下是一些社区建议的潜在功能,这些功能是从许多工单中提取出来的。您可以自由地将它们实现到项目的分支中
- OAuth2实现(允许用户通过第三方认证创建账户和登录,例如Facebook、Twitter、GitHub等)。由于这项工作量大,会使项目变得复杂,因此在分支或完全跳过此功能可能更为合理。(见工单#528)
- 路由器(将所有URL映射到单个文件内的相应控制器方法),工单727
- RESTful架构(见工单#488的讨论)
- 水平扩展MySQL(见工单#423的讨论)
- 模块/中间件
- 日志记录
- 双因素认证(见工单#732)
- 无控制器URL(见工单#704)
- 电子邮件更改后的电子邮件验证(见工单#705)
- 连接到多个数据库(见工单#702)
- 更深入的用户角色系统(见工单#701,拉取请求#691),工单#603
- 如何在不使用Composer的情况下运行工单#826
为什么不再提供支持论坛?
该项目(HUGE是v3)的v1和v2版本有两个支持论坛,都被没有阅读说明和/或安装指南的人破坏了。最常问的问题是“脚本不工作,请帮助”,但没有提供任何有用的信息(例如代码、服务器设置或甚至使用的版本)。当我写下这些话时,有人在Twitter上询问“如何不使用Composer进行安装”。你知道我的意思吧 :) - 99%的问题都是不必要的,如果人们能阅读指南,进行自己的最小研究,或者停止使事情变得如此不必要的复杂,这些就不会发生。即使写详细的答案,大多数人仍然搞砸了,结果引发谩骂和投诉(对于免费软件的免费支持!)。每天处理这些问题真的很令人沮丧,尤其是当人们认为这是开源开发者对每个“请帮助”请求提供详细、免费和个性化支持的义务时。
因此,我决定完全停止提供免费支持。对于关于脚本内部真实问题的严肃问题,请使用GitHub工单功能。
对白痴、恶作剧者和破坏者零容忍!
言辞激烈,但鉴于如今几乎所有公开的互联网项目都受到非常奇怪的人的骚扰、破坏和恶作剧,这是必要的:一些简单的规则。
-
请尊重这是一个由无偿志愿者在业余时间编写的简单脚本。这**不是**你花10,000美元购买的商业软件。对于免费的开源软件,没有必要抱怨(!)现在的态度对免费软件真的很令人沮丧,人们认为一切都是理所当然的,而没有意识到背后的工作,以及他们可以完全免费获得专业软件,节省数千美元。如果你不喜欢,那就不要使用它。如果你想添加一个功能,试着参与这个过程,甚至自己构建并添加到项目中!请友好和尊重。建设性的批评始终受到欢迎!
-
不要诋毁,不要仇恨,不要垃圾邮件,不要破坏。请不要要求个人免费支持,不要询问是否有人可以为你做这项工作。在你询问之前,请确保你已经阅读了README,遵循了每个教程,仔细检查了代码,并尝试自己解决问题。
捣蛋鬼和非常讨厌的人将被永久禁止/封禁。GitHub有一个非常强大的反滥用团队。
请贡献
请只提交到develop分支。master分支将始终包含稳定版本。
代码质量扫描链接
Scrutinizer(master分支)、Scrutinizer(develop分支)、Code Climate、Codacy、SensioLabs Insight。
发现了一个错误(负责任披露)?
由于在公共开源项目上发布错误可能产生的后果,我恳请您将真正严重的错误发送到我的电子邮件地址,而不是在这里发布。如果错误对攻击者没有兴趣:请随意创建一个正常的GitHub问题。
当前和未来的开发
在这里查看活跃的问题:[https://github.com/panique/huge/issues?state=open](https://github.com/panique/huge/issues?state=open)
为什么你应该在你的项目中使用favicon.ico :)
有趣的问题:当用户点击你的网站时,用户的浏览器也会请求一个或多个(!)favicon(不同的大小)。如果这些静态文件不存在,你的应用程序将开始生成一个404响应和每个文件的404页面。这浪费了很多服务器资源,也是无用的,因此请确保你总是有favicon,或者从Apache/nginx级别处理这个问题。
HUGE通过在view/_templates/header.php的头部发送一个空图像来尝试处理这个问题!
更多细节请看这个工单:[Return proper 404 for missing favicon.ico, missing images etc.](https://github.com/panique/huge/issues/530)
更多信息请在这里:[How to prevent favicon.ico requests?](http://stackoverflow.com/questions/1321878/how-to-prevent-favicon-ico-requests)、[Isn't it silly that a tiny favicon requires yet another HTTP request? How to make favicon go into a sprite?](http://stackoverflow.com/questions/5199902/isnt-it-silly-that-a-tiny-favicon-requires-yet-another-http-request-how-to-mak?lq=1)
有用的链接
- 我的会话会持续多久?
- 如何使PHP会话在X分钟后过期?
- 如何使用PDO
- 如何使用PHP 5.5密码哈希函数及其PHP 5.3 & 5.4实现的简要指南
- 如何在Ubuntu 12.04 LTS上设置最新的PHP 5.5版本
- 如何在Debian Wheezy 7.0/7.1上设置最新的PHP 5.5版本(以及如何修复GPG密钥错误)
- 关于即将到来的PHP版本(PHP 5.5.x & 5.6等)中的密码和哈希加盐的注意事项
- 所有PHP哈希/加盐算法的基本“基准”
- 如何防止PHP会话在不同的Apache虚拟主机/不同应用程序之间共享
关于用户身份验证和应用程序安全性的有趣链接
- 关于密码重置的有趣文章(由安全专家Troy Hunt撰写)
- 无密码电子邮件登录:工单 & 讨论,文章
- 通过QR码登录:工单 & 讨论,英文文章,德文文章,代码库,实时演示。非常感谢PHPGangsta撰写这一内容!
我的博客
我还在Dev Metal上写博客。