这个问题的答案是考虑到 PHP、CakePHP 和 Apache mod_rewrite 编写的,但这里的原理也可以应用于其他 Web 平台。
我最终使用的解决方案是利用 CakePHP 中的路由器(或者如果缺少路由器,只需使用 Apace 的 mod_rewrite,通常通过编辑 .htaccess 文件)。
建议:使用短网址
这里的基本原则是在您与用户的交流中(尤其是在电子邮件中)使用非常短的链接,这些链接看起来不错并且少于 80 个字符(如果可能的话)以避免换行。
所以不要发送长而丑陋的 URL:
http://example.com/index.php?controller=users&action=activate&profile_id=123023&token=a2ad2a1adaawda&goto=user_profile
发送类似:
http://example.com/activate_a2dra2bc430a11af
这要短得多,并且很可能在电子邮件客户端中正确呈现,如果不是很容易复制/粘贴。
那么我们如何在两者之间来回转换呢。
解决方案因您选择的平台而异。
如果您没有 Router 实现,则必须依靠 .htaccess 配置将短 URL 转换为相应的长 URL。
但是,如果您使用像 CakePHP 之类的东西(或者如果您实现自己的 Router),您将获得更强大的功能来格式化您的链接(否则很难或无法配置Apache 的 mod_rewrite)。
这是我的实现方式
首先我连接了一条路线 (routes.php),它将拦截我的短激活链接:
Router::connect( '/activate_:token',
array( 'controller' => 'users', 'action' => 'activate' ),
array( 'pass' => array( 'token' ), 'token' => '(.*)' )
);
接下来在我的用户控制器中,我有这个功能(您需要做的一般概述):
public function activate( $token ){
//TODO: 1. validate $token has expected format
//TODO: 2. do a db backup to check this token is valid
//TODO: 3. do required action (like mark user as active)
//TODO: 4. if this is 'use once' then delete token from database to prevent further use of link
//TODO: 5. redirect user to the appropriate location in your app
}
以下是控制器动作的简要说明。
之前生成的令牌是唯一的并存储到数据库中。根据您的需要,您可以为此使用 Token 模型,或者只是在 User 表中使用 token 列(就像我一样)。
第 1 步:验证您的令牌。确保令牌看起来像令牌是个好主意。例如,如果您只需要数字或十六进制值,请验证!
第 2 步:进行 db 查找以找到带有您的令牌的行。这将有助于两件事:首先,您将确保这是您发送的令牌,其次:它还将找到它链接到的用户! (如果您已将令牌存储在用户表中或通过连接)。
第 3 步:做你需要做的事。就我而言,我已经激活了用户,但你可以做任何事情:重置密码、增加计数器、发送其他通知...
第 4 步:如果这是一个只能使用一次的链接,现在是从数据库中删除令牌的好时机。这将确保链接不会再次起作用。
第 5 步:根据您的操作类型,将用户重定向到您应用中的正确位置。在我的情况下,用户配置文件。
令牌生成
正如我所说,要使其工作,令牌需要是唯一的。有很多方法可以做到这一点,具体取决于您的令牌需要的安全程度,但在大多数情况下,像这样简单的东西会起作用(CakePHP 代码):
while( 1 ){
$token = substr( md5( Configure::read( 'Security.salt' ) . rand(1,10000) . time() ), 0, 16 );
//repeat until I get a unique token. You will most likely get a unique one from the first time!
if( !token_exists( $token ) ){
break;
}
}
结论
像这样使用令牌:
- 缩短 URL 使其电子邮件和用户友好
- 增加了一点安全性。猜测一个有效的令牌比摆弄原始长 URL 中的 GET 参数更困难
- 这可以轻松扩展为永久链接和其他操作
我希望您发现本文内容丰富且有用,并且它给了您一些想法!
参考资料: