【问题标题】:User and email friendly links in your communication with your users与用户交流中的用户和电子邮件友好链接
【发布时间】:2014-02-02 03:05:15
【问题描述】:

有时您需要向您的用户发送激活链接或指向其个人资料的链接或指向可能深埋在您的应用程序结构或文件夹结构中的某些资产的链接。

诱惑是快速创建一个像这样的链接:

http://example.com/index.php?controller=users&action=activate&profile_id=123023&token=a2ad2a1adaawda&goto=user_profile

如果您在 HTML 页面上显示该链接,在 <A> 元素后面,则一切正常,但如果您需要将此链接通过电子邮件发送给用户,您会遇到一些麻烦。

如果幸运并且用户的电子邮件客户端呈现 HTML,那么您可以将其隐藏在 <A> 后面。否则,您将不得不以纯文本的形式发送它,它可能会被分成多行或只能被电子邮件客户端部分点击,这使得用户点击它或将其复制/粘贴到他们的浏览器中感到沮丧。

有什么解决办法?

我在下面详细介绍了我最近是如何解决这个问题的,我也欢迎其他解决方案。

【问题讨论】:

    标签: php email cakephp url-rewriting


    【解决方案1】:

    这个问题的答案是考虑到 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 参数更困难
    • 这可以轻松扩展为永久链接和其他操作

    我希望您发现本文内容丰富且有用,并且它给了您一些想法!

    参考资料:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2014-12-28
      相关资源
      最近更新 更多