在 React App 中创建一个安全层以对未经身份验证的用户隐藏 Web 服务
Create a secure layer to hide web service from non-authenticated users, in an React App
我在一个 React 应用程序中工作,该应用程序基本上会为未经过身份验证的用户重置密码。问题是,为了用 Ajax 做到这一点,我公开了服务 url(这是不安全的,我无法解决这个问题,因为项目的那部分属于其他公司)。
我的想法是(我以前从未这样做过,所以我不确定这是要走的路)在中间创建某种 REST 服务,"hides" 来自用户,所以我调用它并 "he" 调用实际服务器,给我所需的数据。
但是,我需要确保这项新服务的安全,以便只有我的应用程序可以使用它,对吗?。如果这是一个很好的方法,我该如何与非认证用户一起实施呢?如果没有,我该怎么做才能解决这个问题?
我对任何想法持开放态度,我打算使用 Node.js 但我对这件事的经验为零。
非常欢迎任何帮助,在此先感谢!
如果您不能对现有服务进行任何更改并且它位于非安全环境中,那么您的想法是正确的。最好创建一个从 UI 调用的 REST 服务,而该 REST 服务又应该调用您现有的服务。
现在,如果您没有任何功能来验证用户身份,那么我不确定您如何才能使该 REST 服务安全。即使您创建了 REST 服务,如果您没有任何方法来验证用户身份,它也不会解决您的目的。即使是 REST 服务也会暴露出来,无法解决您的目的。
如果您具有验证用户身份的功能,例如在您调用此服务或登录屏幕之前创建会话或最初捕获一些详细信息等,这将作为一种在您访问其他服务之前验证用户的方式,那么您就有了解决方案。
如果您需要对用户进行身份验证,最新的做法是使用电子邮件 - 假设只有用户可以访问他的电子邮件。 (这也是最便宜的)
当你生成url的时候就是你需要小心的时候了。基本上,您需要确保它在短时间内是唯一的、未公开发布的并且与特定用户相关联。最常见且最直接的方法是将标记附加到 url。现在,有几个与令牌生成相关的加密要求,我建议不要为此功能创建自己的代码。作为一次性使用令牌的示例,我们可以检查 https://www.rfc-editor.org/rfc/rfc6750.
但是,当您在此线程上标记 Liferay 时,您可以考虑使用 UserLocalService 来生成电子邮件。
或从这段代码中获得灵感,用于 URL 代:
Date expirationDate = null;
if ((passwordPolicy != null) &&
(passwordPolicy.getResetTicketMaxAge() > 0)) {
expirationDate = new Date(
System.currentTimeMillis() +
(passwordPolicy.getResetTicketMaxAge() * 1000));
}
Ticket ticket = ticketLocalService.addDistinctTicket(
companyId, User.class.getName(), user.getUserId(),
TicketConstants.TYPE_PASSWORD, null, expirationDate,
serviceContext);
StringBundler sb = new StringBundler(6);
sb.append(serviceContext.getPortalURL());
sb.append(serviceContext.getPathMain());
sb.append("/portal/update_password?p_l_id=");
sb.append(serviceContext.getPlid());
sb.append("&ticketKey=");
sb.append(ticket.getKey());
passwordResetURL = sb.toString();
我在一个 React 应用程序中工作,该应用程序基本上会为未经过身份验证的用户重置密码。问题是,为了用 Ajax 做到这一点,我公开了服务 url(这是不安全的,我无法解决这个问题,因为项目的那部分属于其他公司)。
我的想法是(我以前从未这样做过,所以我不确定这是要走的路)在中间创建某种 REST 服务,"hides" 来自用户,所以我调用它并 "he" 调用实际服务器,给我所需的数据。
但是,我需要确保这项新服务的安全,以便只有我的应用程序可以使用它,对吗?。如果这是一个很好的方法,我该如何与非认证用户一起实施呢?如果没有,我该怎么做才能解决这个问题?
我对任何想法持开放态度,我打算使用 Node.js 但我对这件事的经验为零。
非常欢迎任何帮助,在此先感谢!
如果您不能对现有服务进行任何更改并且它位于非安全环境中,那么您的想法是正确的。最好创建一个从 UI 调用的 REST 服务,而该 REST 服务又应该调用您现有的服务。
现在,如果您没有任何功能来验证用户身份,那么我不确定您如何才能使该 REST 服务安全。即使您创建了 REST 服务,如果您没有任何方法来验证用户身份,它也不会解决您的目的。即使是 REST 服务也会暴露出来,无法解决您的目的。
如果您具有验证用户身份的功能,例如在您调用此服务或登录屏幕之前创建会话或最初捕获一些详细信息等,这将作为一种在您访问其他服务之前验证用户的方式,那么您就有了解决方案。
如果您需要对用户进行身份验证,最新的做法是使用电子邮件 - 假设只有用户可以访问他的电子邮件。 (这也是最便宜的)
当你生成url的时候就是你需要小心的时候了。基本上,您需要确保它在短时间内是唯一的、未公开发布的并且与特定用户相关联。最常见且最直接的方法是将标记附加到 url。现在,有几个与令牌生成相关的加密要求,我建议不要为此功能创建自己的代码。作为一次性使用令牌的示例,我们可以检查 https://www.rfc-editor.org/rfc/rfc6750.
但是,当您在此线程上标记 Liferay 时,您可以考虑使用 UserLocalService 来生成电子邮件。
或从这段代码中获得灵感,用于 URL 代:
Date expirationDate = null;
if ((passwordPolicy != null) &&
(passwordPolicy.getResetTicketMaxAge() > 0)) {
expirationDate = new Date(
System.currentTimeMillis() +
(passwordPolicy.getResetTicketMaxAge() * 1000));
}
Ticket ticket = ticketLocalService.addDistinctTicket(
companyId, User.class.getName(), user.getUserId(),
TicketConstants.TYPE_PASSWORD, null, expirationDate,
serviceContext);
StringBundler sb = new StringBundler(6);
sb.append(serviceContext.getPortalURL());
sb.append(serviceContext.getPathMain());
sb.append("/portal/update_password?p_l_id=");
sb.append(serviceContext.getPlid());
sb.append("&ticketKey=");
sb.append(ticket.getKey());
passwordResetURL = sb.toString();