我被这个问题卡住了。后端api是用Node.js
编写的,我在React.js
的前端处理这些api。后端和前端代码具有独立的存储库结构。因此,所有登录,注册和忘记密码功能将通过客户端请求完成。
api端点部署在具有以下URL结构的服务器上。
POST - https://133.44.163.89:5000/user/forgetPassword
GET - https://133.44.163.89:5000/user/56546dsfsd
现在我在前端本地环境中使用这些端点,该环境具有以下URL。
http://localhost:3000
我正面临一个忘记密码端点的问题,基本上它是一个post请求,并在正文中接受用户电子邮件。
POST - https://133.44.163.89:5000/user/forgetPassword
body: { email: 'example@example.com' }
如果成功响应,它将发送一封带有链接的电子邮件。链接的结构如下:
https://133.44.163.89:5000/user/56546dsfsd/forgetPassword/ddeef95c508
user-id token
后端开发人员想从我这里得到的是,当你点击这个URL时,一个页面应该在前端打开一个密码重置表单。但是链接HOST
是不同的,我怎么能把这个链接HOST
(https://133.44.163.89:5000)映射到前端的HOST
(http://localhost:3000)打开页面。
这个问题的解决方案应该是什么?
对于开发人员来说,后端开发人员应该使用localhost向您发送链接,当您的应用程序处于生产模式时,BE Dev应该使用prod域发送链接。
应该有两个端点:
- 第一个发送带有用户令牌的电子邮件的端点。
- 第二秒接收新密码和令牌以验证用户帐户。我认为userId是不需要的,你可以得到userId,如果你正在做一个令牌和用户之间的链接。
在react中,你需要创建一个路由来重置密码如果你使用react-router-dom,你的代码看起来像这样
<Switch>
<Route path="/login" component={<Login />} exact />
<Route path="/user/:userId/forgetPassword/:token" component={<ResetPassword />} exact />
<Redirect to="/login" from="*" />
</Switch>
在你的ResetPassword组件中,如果你使用钩子,你可以使用
import { useParams } from 'react-router-dom';
const {userId, token} = useParams();
这取决于你正在使用的react-router。
我真的不明白你的密码重置过程的结构。通常情况下,它的工作方式如下
-
发送密码重置请求。
的用法POST - https://133.44.163.89:5000/user/forgetPassword body: { email: 'example@example.com' }
-
服务器发送一封带有密码重置表单链接的电子邮件。在您的情况下,这可能类似于以下内容
http://localhost:3000/passwordResetForm?userid=abc&token=xyz
当你点击那个链接时,你的浏览器会打开密码重置表单,你可以输入你的新密码
-
在提交密码重置表单时,向服务器发送如下请求
POST - https://133.44.163.89:5000/user/abc/forgetPassword/xyz body: { newpassword: 'foobar'}
要获得电子邮件的正确URL,您可以在第一个请求
中添加一个额外的returnUrl
参数。POST - https://133.44.163.89:5000/user/forgetPassword
body: { email: 'example@example.com', returnUrl: 'http://localhost:3000' }
如果对新密码的请求只能从前端发送,您也可以利用与请求一起发送的Origin
头(由浏览器自动设置)
app.post("/user/forgetPassword", (req, res) => {
//let returnurl = req.body.returnUrl; //use whatever fits
//let returnurl = req.get("origin"); //your usecase more ...
sendEmail(returnurl); //insert the correct url in the email
res.sendStatus(200);
}
另一种处理方法是在电子邮件中根本不使用链接,而只是通过电子邮件发送令牌,如下所示
用户点击"忘记密码"在前端,输入他的电子邮件,然后前端将请求提交给服务器
POST - https://133.44.163.89:5000/user/forgetPassword body: { email: 'example@example.com' }
一旦请求被服务器接受,显示重置令牌和新密码
的额外输入服务器发送只包含请求令牌的电子邮件
用户在已经打开的(从步骤1和2)密码重置表单中输入此令牌和新密码。在提交表单时,将请求令牌和新密码发送到服务器
POST - https://133.44.163.89:5000/forgetPassword/xyz body: { newpassword: 'foobar'}
在此请求中甚至不需要userid,因为使用重置令牌,您可以轻松确定是哪个用户发送了请求。
您需要提供来自同一域的后端路由和前端路由。
Use domain address instead of IP
根据你的链接结构
https://<domain>/user/<userId>/forgetPassword/<token>
在<Route >
中从客户端创建一个端点[参见react-router npm]
<Switch>
<Route exact path="/login" component={<Login />} />
<Route exact path="/user/:userId/forgetPassword/:token" component={<ResetPassword />} />
.
....
...
.
<Redirect to="/login" />
</Switch>
现在,您需要为reset password创建组件import React from 'react';
import { useParams } from 'react-router-dom';
function ResetPassword (props) {
// get your userId, token using useParams
const { userId, token } = useParams();
// now you can use this userId, and token as per your requirement
return (
// your reset password code
<YourComponent>
)
}
开发人员应该在应用程序中添加环境变量,并将正确的链接和正确的域名地址发送到电子邮件
REACT_APP_URL=https://localhost:3000