You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Router+IIS+ASP.NET Core双参数URL访问400错误排查

忘记密码重置URL中Token丢失字符导致400错误的解决方案

基于React、React-Router、IIS和ASP.NET Core开发的忘记密码功能,通过邮件向用户发送包含userId和token的重置密码URL,但访问该URL时,第二个参数tokenId会丢失部分字符,进而触发「Bad Request - Invalid URL HTTP Error 400」错误。以下是相关代码信息及解决办法:


相关代码信息

1. 示例URL

http://www.example.com/update-password/d2ff3788-aa12-47b6-8759-8b52cca02a3b/Q2ZESjhQL1dOb0l3bGYxSW1XZktVbTN3ckx3SnAyNFB2Z2dhNXRBWVBlMWJyd3Jaa1ZEejV5WDA5TExtNi93djBPWUMwN1NyK1NrMG1VVnM5V1E2RmdsbXBkVXlUMFlXS0o1ZzlJVWxUQU9kSlJLWC9sUC9RRXdldEtRLzFZTnNOa216dXN5eEhub29MRi84Z1Q1SVVoc1c0MWFrWHkwVUN2YnAxa0VGWU1PenU4emFNc3hwNWN0K3BudDlmYktic2RPcVlpOSsraGo2RFc4d2EzOFdJUm1XMHc0L0dpeWNISG4vWUU4aU9FdGtmRlZh 

2. React项目index.html文件

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap-grid.min.css" /> -->
</head>

<body>
  <div id="root"></div>
  <script type="module" src="./src/main.jsx"></script>
</body>

</html> 

3. React路由配置

导入部分:

import {
  BrowserRouter as Router, // <-- import Router component
  Route,
  Routes
} from 'react-router-dom'

路由定义:

<Route path='/update-password' element={<UpdatePassword />}>
    <Route path="/update-password/:userId/:tokenId" element={<UpdatePassword />} />
</Route>

4. Token信息

未编码的Token:

CfDJ8EHnmcjBPm9MoR2xSCwmz5BloVGwo3ncXBxlFX7ygpB2ukH2K3huzfxvWxY4mgBb7LtKRoUzggOICsZpfFOCqXHN02zYQiIYSZwG8AVZkEnFt4lZo102aojOHgyMR1R/QfqlYzn5F5to8ydt/8GgtQpVGqVzz5fa853R/AH18EtOK5zow1akfZ4LIx6ZO39Z+iSmFbhUWfL27vx6vmJ5U9BxUn3bUgHpnJPJY6CzNlcboSCGist9knfxNWjgR8T2Cg==

编码后的Token:

Q2ZESjhFSG5tY2pCUG05TW9SMnhTQ3dtejVCbG9WR3dvM25jWEJ4bEZYN3lncEIydWtIMkszaHV6Znh2V3hZNG1nQmI3THRLUm9VemdnT0lDc1pwZkZPQ3FYSE4wMnpZUWlJWVNad0c4QVZaa0VuRnQ0bFpvMTAyYW9qT0hneU1SMVIvUWZxbFl6bjVGNXRvOHlkdC84R2d0UXBWR3FWeno1ZmE4NTNSL0FIMThFdE9LNXpvdzFha2ZaNExJeDZaTzM5WitpU21GYmhVV2ZMMjd2eDZ2bUo1VTlCeFVuM2JVZ0hwbkpQSlk2Q3pObGNib1NDR2lzdDlrbmZ4TldqZ1I4VDJDZz09

5. C#后端代码

public async Task MailOnaylamaAsync(string eMail)
{
AppUser user = await _UserManager.FindByEmailAsync(eMail);
if (user != null)
{
string mailToken = await _UserManager.GenerateEmailConfirmationTokenAsync(user);
byte[] tokenBytes = Encoding.UTF8.GetBytes(mailToken);
mailToken = WebEncoders.Base64UrlEncode(tokenBytes);
await _mailService.SendMailOnayAsync(eMail, user.Id, mailToken);
}

问题原因及解决办法

1. 路由配置错误

当前嵌套路由的子路径写了完整前缀,导致解析异常。修改为相对路径:

<Route path='/update-password' element={<UpdatePassword />}>
    <Route path=":userId/:tokenId" element={<UpdatePassword />} />
</Route>

或者直接定义为独立路由,避免嵌套问题:

<Route path='/update-password/:userId/:tokenId' element={<UpdatePassword />} />

2. IIS限制长URL或特殊字符

IIS默认的URL长度限制可能截断长Token,在项目的web.config中添加配置调整限制:

<system.webServer>
  <security>
    <requestFiltering>
      <!-- 根据实际Token长度调整maxUrl数值 -->
      <requestLimits maxUrl="8192" maxQueryString="4096" />
    </requestFiltering>
  </security>
</system.webServer>

3. Token编码/解码验证

确保后端接收Token时用对应的Base64UrlDecode还原:

// 接收重置请求时解码Token
byte[] tokenBytes = WebEncoders.Base64UrlDecode(receivedToken);
string originalToken = Encoding.UTF8.GetString(tokenBytes);

同时检查邮件模板中拼接URL时是否有换行、空格或截断,保证Token完整嵌入。

4. 改用QueryString传递Token

如果路径参数问题仍无法解决,将Token放在QueryString中传递:

http://www.example.com/update-password/d2ff3788-aa12-47b6-8759-8b52cca02a3b?tokenId=Q2ZESjhFSG5tY2pCUG05TW9SMnhTQ3dtejVCbG9WR3dvM25jWEJ4bEZYN3lncEIydWtIMkszaHV6Znh2V3hZNG1nQmI3THRLUm9VemdnT0lDc1pwZkZPQ3FYSE4wMnpZUWlJWVNad0c4QVZaa0VuRnQ0bFpvMTAyYW9qT0hneU1SMVIvUWZxbFl6bjVGNXRvOHlkdC84R2d0UXBWR3FWeno1ZmE4NTNSL0FIMThFdE9LNXpvdzFha2ZaNExJeDZaTzM5WitpU21GYmhVV2ZMMjd2eDZ2bUo1VTlCeFVuM2JVZ0hwbkpQSlk2Q3pObGNib1NDR2lzdDlrbmZ4TldqZ1I4VDJDZz09

然后在React组件中用useSearchParams获取Token:

import { useSearchParams } from 'react-router-dom';

function UpdatePassword() {
  const [searchParams] = useSearchParams();
  const tokenId = searchParams.get('tokenId');
  // 后续逻辑
}

内容的提问来源于stack exchange,提问作者Omar Dak Elbab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:02:10