<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Cookie Path 设置缺失导致的登录重定向循环问题]]></title><description><![CDATA[<h1>Cookie Path 设置缺失导致的登录重定向循环问题</h1>
<h2>问题描述</h2>
<p dir="auto">在 staging 环境（<code>staging-admin.loda.online</code>）下，有 3 个站点出现登录后的无限重定向循环：</p>
<ul>
<li><code>customer-order-web</code> (虚拟目录: <code>/orders</code>)</li>
<li><code>article-web</code> (虚拟目录: <code>/cms</code>)</li>
<li><code>basedata-web</code> (虚拟目录: <code>/basic</code>)</li>
</ul>
<p dir="auto">循环路径：</p>
<pre><code>/orders/default.aspx 
  → /passport/Home/Login.aspx?ReturnUrl=.../orders/default.aspx
  → /orders/Home/Login.aspx?key=xxx&amp;info=xxx&amp;ReturnUrl=.../orders/default.aspx
  → /orders/default.aspx (再次认为未登录)
  → 循环...
</code></pre>
<h2>根本原因</h2>
<h3>1. Cookie Path 的浏览器行为规则 (RFC 6265)</h3>
<p dir="auto">当服务端设置 Cookie 时，如果<strong>没有显式指定 <code>Path</code> 属性</strong>：</p>
<ul>
<li>浏览器会自动将 Cookie 的 <code>Path</code> 设为<strong>当前请求 URL 的目录路径</strong></li>
<li>例如：在 <code>/orders/Home/Login.aspx</code> 设置 Cookie → Path 默认为 <code>/orders/Home/</code></li>
</ul>
<p dir="auto">浏览器发送 Cookie 的规则：</p>
<ul>
<li><strong>只有当请求路径是 Cookie Path 的前缀时，才会发送该 Cookie</strong></li>
<li><code>/orders/Home/Default.aspx</code> → 会发送 (因为 <code>/orders/Home/Default.aspx</code> 以 <code>/orders/Home/</code> 开头)</li>
<li><code>/orders/default.aspx</code> → <strong>不会发送</strong> (因为 <code>/orders/</code> 不以 <code>/orders/Home/</code> 开头)</li>
</ul>
<h3>2. 问题站点的特殊性</h3>
<p dir="auto">这 3 个站点的首页位置：</p>
<pre><code>/orders/default.aspx  ← 在虚拟目录根
/cms/default.aspx
/basic/default.aspx
</code></pre>
<p dir="auto">登录页位置：</p>
<pre><code>/orders/Home/Login.aspx  ← 在 Home 子目录
/cms/Home/Login.aspx
/basic/Home/Login.aspx
</code></pre>
<h3>3. 问题代码</h3>
<p dir="auto"><strong>修改前的代码</strong>（<a target="_blank" rel="noopener noreferrer nofollow ugc">CookieHelper.cs</a> 第 42-48 行）：</p>
<pre><code class="language-csharp">HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
cookie.Value = FormsAuthentication.Encrypt(ticket);
cookie.Expires = DateTime.Now.AddDays(1);
cookie.HttpOnly = false;
// ❌ 没有设置 Path，浏览器默认为当前目录

System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
</code></pre>
<h3>4. 执行流程与失败点</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>步骤</th>
<th>URL</th>
<th>Cookie Path</th>
<th>Cookie 是否发送</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>访问 <code>/orders/default.aspx</code></td>
<td>-</td>
<td>无 Cookie</td>
<td>302 跳转到 Passport</td>
</tr>
<tr>
<td>2</td>
<td>Passport 登录</td>
<td>-</td>
<td>-</td>
<td>302 返回应用</td>
</tr>
<tr>
<td>3</td>
<td><code>/orders/Home/Login.aspx</code></td>
<td>写入 Cookie</td>
<td>-</td>
<td><strong>Cookie Path = <code>/orders/Home/</code></strong></td>
</tr>
<tr>
<td>4</td>
<td>302 跳转到 <code>/orders/default.aspx</code></td>
<td><code>/orders/Home/</code></td>
<td><img src="https://talk.loda.net/assets/plugins/nodebb-plugin-emoji/emoji/android/274c.png?v=7ba14356ba6" class="not-responsive emoji emoji-android emoji--x" style="height:23px;width:auto;vertical-align:middle" title="❌" alt="❌" /> <strong>不发送</strong></td>
<td>认为未登录</td>
</tr>
<tr>
<td>5</td>
<td>再次 302 到 Passport</td>
<td>-</td>
<td>-</td>
<td><strong>循环开始</strong></td>
</tr>
</tbody>
</table>
<h2>修复方案</h2>
<h3>修改内容</h3>
<p dir="auto"><strong>只修改一行代码</strong>，在第 47 行添加：</p>
<pre><code class="language-csharp">HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
cookie.Value = FormsAuthentication.Encrypt(ticket);
cookie.Expires = DateTime.Now.AddDays(1);
cookie.HttpOnly = false;
cookie.Path = "/";  // ✅ 显式设置为根路径

System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
</code></pre>
<h3>修复后的行为</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>步骤</th>
<th>URL</th>
<th>Cookie Path</th>
<th>Cookie 是否发送</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>访问 <code>/orders/default.aspx</code></td>
<td>-</td>
<td>无 Cookie</td>
<td>302 跳转到 Passport</td>
</tr>
<tr>
<td>2</td>
<td>Passport 登录</td>
<td>-</td>
<td>-</td>
<td>302 返回应用</td>
</tr>
<tr>
<td>3</td>
<td><code>/orders/Home/Login.aspx</code></td>
<td>写入 Cookie</td>
<td>-</td>
<td><strong>Cookie Path = <code>/</code></strong></td>
</tr>
<tr>
<td>4</td>
<td>302 跳转到 <code>/orders/default.aspx</code></td>
<td><code>/</code></td>
<td><img src="https://talk.loda.net/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=7ba14356ba6" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /> <strong>发送</strong></td>
<td>识别登录状态</td>
</tr>
<tr>
<td>5</td>
<td>显示首页</td>
<td>-</td>
<td>-</td>
<td><strong>正常完成</strong> <img src="https://talk.loda.net/assets/plugins/nodebb-plugin-emoji/emoji/android/2705.png?v=7ba14356ba6" class="not-responsive emoji emoji-android emoji--white_check_mark" style="height:23px;width:auto;vertical-align:middle" title="✅" alt="✅" /></td>
</tr>
</tbody>
</table>
<h2>为什么只有这 3 个站点有问题？</h2>
<p dir="auto">对比分析：</p>
<p dir="auto"><strong>问题站点</strong>：</p>
<ul>
<li>登录页在子目录：<code>/orders/Home/Login.aspx</code></li>
<li>首页在根目录：<code>/orders/default.aspx</code></li>
<li>路径不匹配 → Cookie 无法送达</li>
</ul>
<p dir="auto"><strong>正常站点</strong>：</p>
<ul>
<li>登录页在子目录：<code>/wms/Home/Login.aspx</code></li>
<li>首页也在子目录：<code>/wms/Home/Default.aspx</code></li>
<li>路径匹配 → Cookie 可以送达</li>
</ul>
<h2>验证方法</h2>
<p dir="auto">修复后，在浏览器 DevTools → Application → Cookies 查看：</p>
<p dir="auto"><strong>修复前</strong>：</p>
<pre><code>Name: YeeCustomerOrders2
Value: [encrypted]
Domain: staging-admin.loda.online
Path: /orders/Home/          ← 错误
</code></pre>
<p dir="auto"><strong>修复后</strong>：</p>
<pre><code>Name: YeeCustomerOrders2
Value: [encrypted]
Domain: staging-admin.loda.online
Path: /                      ← 正确
</code></pre>
<h2>相关代码对比</h2>
<p dir="auto">同一个文件中的 <a target="_blank" rel="noopener noreferrer nofollow ugc">SaveSid</a> 方法（第 56-64 行）<strong>已经正确设置了 Path</strong>：</p>
<pre><code class="language-csharp">static public void SaveSid(Guid sid)
{
    HttpCookie cookie = new HttpCookie("SID", sid.ToString());
    cookie.Path = "/";  // ✅ 这里有设置
    cookie.Expires = DateTime.Today.AddDays(1).AddHours(2);
    HttpContext.Current.Response.Cookies.Add(cookie);
}
</code></pre>
<p dir="auto">而 <a target="_blank" rel="noopener noreferrer nofollow ugc">StoreLocalCookie</a> 方法之前缺少这一行，导致了不一致的行为。</p>
<h2>影响范围</h2>
<ul>
<li><strong>修改文件</strong>：<a target="_blank" rel="noopener noreferrer nofollow ugc">Yee.Web.Security\CookieHelper.cs</a></li>
<li><strong>影响站点</strong>：所有继承 <a target="_blank" rel="noopener noreferrer nofollow ugc">LoginPage</a> 基类的站点（25 个）</li>
<li><strong>实际受益</strong>：<code>customer-order-web</code>、<code>article-web</code>、<code>basedata-web</code></li>
<li><strong>其他站点</strong>：无副作用（从默认行为改为显式设置，行为一致）</li>
</ul>
<h2>部署要求</h2>
<ol>
<li>重新编译 <code>Yee.Web.Security.dll</code></li>
<li>更新所有 UI 站点的依赖</li>
<li>重启 IIS 应用池清除旧 DLL 缓存</li>
</ol>
]]></description><link>https://talk.loda.net/topic/32/cookie-path-设置缺失导致的登录重定向循环问题</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 08:32:06 GMT</lastBuildDate><atom:link href="https://talk.loda.net/topic/32.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 08 Dec 2025 02:28:13 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Cookie Path 设置缺失导致的登录重定向循环问题 on Mon, 08 Dec 2025 07:57:32 GMT]]></title><description><![CDATA[<p dir="auto">WindSurf的Claude Sonnect 4.5药到病除，一点弯路都没有。</p>
<pre><code>&lt;machineKey validationKey="..." decryptionKey="..." validation="SHA1" /&gt;
</code></pre>
<p dir="auto">虽然对 Cookie Path 没有直接影响，但如果 Passport 传来的 key/info 需要用特定的 machineKey 解密，可能会导致登录失败。</p>
<p dir="auto">签入代码以后，老挝准正式站ERP后台，25个站点，全部再没有重定向循环的bug了。</p>
<p dir="auto"><img src="/assets/uploads/files/1765180647601-7.png" alt="7.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://talk.loda.net/post/37</link><guid isPermaLink="true">https://talk.loda.net/post/37</guid><dc:creator><![CDATA[zhongfangxiong]]></dc:creator><pubDate>Mon, 08 Dec 2025 07:57:32 GMT</pubDate></item></channel></rss>