java 如何验证用户点击了我发送给他/她的电子邮件中的链接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10545507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:30:18  来源:igfitidea点击:

how to verify user clicked on link in email that I sent him/her?

javaemailauthentication

提问by ggkmath

This is a more focused question triggered by an earlier posting here. I need to authenticate a user's email address by proving he/she has access to it. I've copied below a generic email authentication you'd expect to see when joining a developer forum or user group. As part of the registration process, you'd provide your email address, and then you'd get an email asking you to click on something to verify your email address.

这是一个更集中的问题,由此处较早的帖子引发。我需要通过证明他/她有权访问来验证用户的电子邮件地址。我在下面复制了您在加入开发者论坛或用户组时希望看到的通用电子邮件身份验证。作为注册过程的一部分,您需要提供您的电子邮件地址,然后您会收到一封电子邮件,要求您单击某些内容来验证您的电子邮件地址。

I need to code whatever happens when a user clicks on the link in the email. So my question is -- how do I do that?

我需要对用户单击电子邮件中的链接时发生的任何事情进行编码。所以我的问题是——我该怎么做?

What technologies are involved? Can anyone walk me through the steps? I prefer Java or Linux scripting language like bash. Better yet, is there any software developed for this purpose I can install on my Linux server and somehow integrate it to talk with my database? How is this done in practice? I don't want to reinvent something if it's already available.

涉及哪些技术?任何人都可以引导我完成这些步骤吗?我更喜欢像 bash 这样的 Java 或 Linux 脚本语言。更好的是,有没有为此目的开发的软件可以安装在我的 Linux 服务器上并以某种方式将它集成到我的数据库中?这在实践中是如何完成的?如果某个东西已经可用,我不想重新发明它。

To confirm your email address of: 

[email protected] 

please send a short reply to this address: 

users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com 

Usually, this happens when you just hit the "reply" button. 
If this does not work, simply copy the address and paste it into 
the "To:" field of a new message. 

or click here: 
mailto:users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com  

This confirmation serves two purposes. First, it verifies that I am able 
to get mail through to you. Second, it protects you in case someone 
forges a subscription request in your name. 

Some mail programs are broken and cannot handle long addresses. If you 
cannot reply to this request, instead send a message to 
<[email protected]> and put the 
entire address listed above into the "Subject:" line. 

采纳答案by Nickoli Roussakov

In your user database you need to have a staging users table (or in the main users table add a column indicating whether the user is active and default the indicator to "no"). When the user first registers, you generate a unique hash code from part of the user's info, e.g. Use md5 on user primary key and name (or some other set of user's variables which you can get back by decrypting) . Make this hash code a query string parameter in the link you send to the user. Finally, when the user clicks on the link, get the hashcode from the query string, decrypt it and match the decrypted values to the user row in your database. If a match is found, set the "active" indicator to true, and presto. Alternately, if you used a staging table, then move the user record to the "active users" table which you use to do your authorization on.

在您的用户数据库中,您需要有一个临时用户表(或在主用户表中添加一列指示用户是否处于活动状态并将指标默认为“否”)。当用户第一次注册时,你会从用户信息的一部分生成一个唯一的哈希码,例如在用户主键和名称上使用 md5(或一些其他的用户变量集,你可以通过解密取回)。在您发送给用户的链接中将此哈希码设为查询字符串参数。最后,当用户单击链接时,从查询字符串中获取哈希码,对其进行解密,并将解密后的值与数据库中的用户行进行匹配。如果找到匹配项,将“活动”指示器设置为 true,然后快速设置。或者,如果您使用了临时表,则将用户记录移动到“活动用户”

回答by jerrymouse

Replying to a unique email to verify someone's email has an inherent flaw, it can be faked (unless you check headers and ip). For example, I visit your site for registration. You tell me to reply at users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com. I use a mail()function using spam bot to reply. Game Over. Purpose defeated.

回复一个唯一的电子邮件来验证某人的电子邮件有一个固有的缺陷,它可以被伪造(除非你检查标题和 IP)。例如,我访问您的网站进行注册。你告诉我回复在users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com。我使用了一个mail()使用垃圾邮件机器人的功能来回复。游戏结束。目的失败。

Instead, you can send me a verification link on my register id. Something like example.com/verify?userid=1&hash=67gk65fs6714fgsHguj

相反,您可以在我的注册 ID 上向我发送验证链接。就像是example.com/verify?userid=1&hash=67gk65fs6714fgsHguj

In the users table:

在用户表中:

id|username|status|onetimehash
--+--------+------+-------------------------
 1|testuser|    0 |67gk65fs6714fgsHguj

Now, in your verify call check userid and hash. If they match against values in your db, you can safely verify the user. For generating hash, you can take md5 or sha1 value of username mixed with some salt like timestamp or some random number.

现在,在您的验证调用中检查用户 ID 和哈希。如果它们与您的数据库中的值匹配,您就可以安全地验证用户。为了生成哈希,您可以将用户名的 md5 或 sha1 值与一些盐(如时间戳或一些随机数)混合。

UPDATEIf you are going with the former solution, i.e, capturing user's reply to validate email, you will have to setup your own mail server. Fetchmailmay help you. You will have to programmatically read the email headers and extract required info from the <to>,<from> or <subject>fields. Like userid=1496854427 and hash=ckdpbmhncdlkjadkajfpecc. You mayneed regex in this process. Once you have these values, its pretty straightforward, check them against database values.

更新如果您使用前一种解决方案,即捕获用户的回复以验证电子邮件,您将必须设置自己的邮件服务器。Fetchmail可以帮到你。您必须以编程方式阅读电子邮件标题并从<to>,<from> or <subject>字段中提取所需信息。像 userid=1496854427 和 hash=ckdpbmhncdlkjadkajfpecc。在此过程中您可能需要正则表达式。获得这些值后,非常简单,根据数据库值检查它们。

Bottom-line is: Former method is not just more tedious, its also more vulnerable than the latter. Most webapps use the 2nd solution, as its cleaner and wiser.

底线是:前一种方法不仅更乏味,而且比后一种方法更容易受到攻击。大多数网络应用程序使用第二种解决方案,因为它更干净、更明智。

回答by Aniket Kulkarni

I knew one link which has the best answer given by BalusC
Here is link:better answer.
I have implemented that in my project. Hope this will help others.

我知道一个链接有BalusC给出的最佳答案
这里是链接:更好的答案
我已经在我的项目中实现了它。希望这会帮助其他人。