前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >邮件退订的设计与实现

邮件退订的设计与实现

作者头像
xcsoft
修改2022-05-17 20:01:34
1.3K0
修改2022-05-17 20:01:34
举报
文章被收录于专栏:星辰日记

何为邮件退订

在平常的验证码, 推广邮件中, 我们通常会在最下角找到 退订链接。通常访问它, 我们就不会再收到他们发送的邮件。

但是, 如何以最简单, 最节省性能的方式去实现这一功能呢?

一开始

其实最简单的方式, 貌似就是在 发送邮件时, 生成一段随机字符, 存储在数据库或缓存中(已经缓存, 可直接读取), 然后拼接成一个网址, 附在邮件底部. 用户打开后 将字符串传递给后端, 从数据库或缓存中找到这段字符串所对应的邮箱.

获取到请求对定的邮箱后, 将其存储至数据库, 后续发信时, 只需查找一次便可.

这个过程其实很简单, 有没有办法让其更加简单, 发信时不去依赖服务端的持久化存储呢?

了解jwt

其实我们可以借鉴一下 jwt (json web token) 的验证思路. jwt 是由 header, payload, signature 通过小数点间隔 组成的一段字符串.

header

其中 header是由 typ和alg 组成的json 经过base64得出

代码语言:json
复制
{
  "typ": "JWT",
  "alg": "HS256"
}

typ是固定的, 指出这段字符为 jwt. 而 alg 则指出了签名的生成方式. 这里使用的是 sha256

payload

payload是有效负荷, 其中存储了jwt的签发单位, 签发时间, 有效时间, 公开信息 等, 它同样也是由这些信息的json 再经过base64得出.

通常情况下, payload建议包含以下字符, 但也不是必须的:

  • iss: jwt签发者
  • sub: jwt所面向的用户
  • aud: 接收jwt的一方
  • exp: jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf: 定义在什么时间之前,该jwt都是不可用的.
  • iat: jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

如, 在此处场景下, 我们可以这样

代码语言:json
复制
{
  "iss": "website",
  "aud": "email@example.com",
  "iat": "timestamp"
}
signature

签名用于对这串 jwt 进行合法性校验. 来判断它是否经过伪造. 进行签名我们需要一个密钥, 这个密钥只能存储在服务端, 并严格保密. 这串密钥也是通常所称的 salt.

签名方式便是header中给出的alg, 如此处 我们通过 SHA256(header + payload + salt) 生成签名.

最终jwt的格式应为 header.payload.sha256(header+payload+salt)

使用

我们只需在发送邮件时, 生成这段jwt. 发送给用户, 所有的信息仅存储在用户的邮件中, 也不用担心伪造. 我们需要做的只是保证密钥的安全.

此时当用户需要退订时, 服务器接收到这段jwt后, 需先对齐进行验签, 判断其是否经过伪造. 如果通过, 接着从payload中取出用户邮箱. 将其加入不发送的名单内即可.

参考
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 何为邮件退订
  • 一开始
  • 了解jwt
    • header
      • payload
        • signature
          • 使用
            • 参考
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档