HttpClient 不从 CookieContainer 发送 cookie

2024-02-24

我正在使用 Visual Studio 2012 开发带有 WPF (.NET 4.0) 客户端的 ASP WebAPI (ASP MVC 4) 应用程序。客户端需要登录到服务器。我使用带有身份验证 cookie 的 FormsAuthentication 来登录。登录已经在 ASP MVC 中正常工作。

问题在于,虽然在服务器上成功执行了登录并且将cookie发送回客户端,但在后续调用服务器时并没有发送cookie,即使CookieContainer与 auth cookie 集一起重用。

这是代码的简化版本:

CLIENT

public async Task<UserProfile> Login(string userName, string password, bool rememberMe)
{           
    using (var handler = new HttpClientHandler() { CookieContainer = this.cookieContainer })
    using (var httpClient = new HttpClient(handler))
    {
        httpClient.BaseAddress = new Uri("http://localhost:50000/");

        httpClient.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));

        var result = await httpClient.PostAsJsonAsync("api/auth/login", new
        {
            username = userName,
            password = password,
            rememberMe = rememberMe
        });

        result.EnsureSuccessStatusCode();

        var userProfile = await result.Content.ReadAsAsync<UserProfile>();

        if (userProfile == null)
            throw new UnauthorizedAccessException();

        return userProfile;
    }
}

public async Task<ExamSubmissionResponse> PostItem(Item item)
{
    using (var handler = new HttpClientHandler() { CookieContainer = this.cookieContainer })
    using (var httpClient = new HttpClient(handler))
    {
        httpClient.BaseAddress = new Uri("http://localhost:50000/");

        var result = await httpClient.PostAsJsonAsync("api/Items/", item);
    }
}

SERVER

[HttpPost]
public HttpResponseMessage Login(LoginModel model)
{
    if (this.ValidateUser(model.UserName, model.Password))
    {
        // Get user data from database

        string userData = JsonConvert.SerializeObject(userModel);

        var authTicket = new FormsAuthenticationTicket(
            1,
            model.UserName,
            DateTime.Now,
            DateTime.Now.AddMinutes(10 * 15),
            model.RememberMe,
            userData
        );              

        string ticket = FormsAuthentication.Encrypt(authTicket);
        var cookie = new CookieHeaderValue(FormsAuthentication.FormsCookieName, ticket);
        var response = Request.CreateResponse(HttpStatusCode.Created, userModel);
        response.Headers.AddCookies(new CookieHeaderValue[] { cookie });

        return response;
    }
    return null;
}

首先,我使用 Fiddler2 调试了问题(我使用基地址作为“http://localhost.fiddler:50000/”查看本地流量)。然后我怀疑fiddler可能会干扰,所以我就用Visual Studio 2012进行调试。

我已经尝试和验证过的:

  • 通过 Login 方法到达服务器

  • 使用客户端发送的数据成功验证用户身份

  • cookie是在服务器上设置的

  • cookie在响应中(用fiddler验证)

  • 操作完成后,cookie 位于 CookieContainer 中。这里有一个奇怪的事情:容器中cookie的域设置为“localhost”(用VS2012调试器验证)。不应该是“http://localhost:50000"?当我尝试使用获取容器的cookie时cookieContainer.GetCookies(new Uri("http://localhost:50000"))它什么也不返回。当我尝试使用cookieContainer.GetCookies(new Uri("localhost"))它给了我一个无效的 Uri 错误。不知道这里发生了什么。

  • cookie 就在之前的容器中PostItem提出请求。当语句在 HttpClient 中正确设置容器时httpClient.PostAsJsonAsync到达了。

  • cookie 没有发送到服务器(我用 fiddler 检查了它并在Application_PostAuthenticateRequestGlobal.asax.cs 中的方法,验证this.Request.Cookies)

我怀疑由于域不匹配而未发送 cookieCookieContainer,但是为什么域没有按照应有的方式设置CookieContainer首先?


您的问题是您没有在从 Web Api 控制器发回的 cookie 上设置任何路径。

有两件事可以控制 cookie 的发送位置:

  1. cookie 的域
  2. cookie的路径

关于域,共识似乎是端口号不应再(但仍然可能)成为评估 cookie 域的一个因素。看这个问题 https://stackoverflow.com/questions/1612177/are-http-cookies-port-specific有关端口号如何影响域的更多信息。

关于路径:Cookie 与其域中的特定路径相关联。在您的情况下,Web Api 发送 cookie 时未指定其路径。默认情况下,cookie 将与创建 cookie 的请求/响应的路径相关联。

在你的情况下,cookie 将具有路径api/auth/login。这意味着 cookie 将被发送到子路径(由于缺乏更好的术语)这条道路,但不是parent or sibling paths.

要测试这一点,请尝试:

cookieContainer.GetCookies(new Uri("http://localhost/api/auth/login")

这应该会给你 cookie。所以应该这样:

cookieContainer.GetCookies(new Uri("http://localhost/api/auth/login/foo/bar")

另一方面,这些将找不到 cookie:

cookieContainer.GetCookies(new Uri("http://localhost/")
cookieContainer.GetCookies(new Uri("http://localhost/api/")
cookieContainer.GetCookies(new Uri("http://localhost/api/auth/")
cookieContainer.GetCookies(new Uri("http://localhost/api/auth/foo")
cookieContainer.GetCookies(new Uri("http://localhost/api/Items/")

要解决此问题,只需在发送响应之前将路径“/”(或者可能是“/api”)添加到 cookie:

...
string ticket = FormsAuthentication.Encrypt(authTicket);
var cookie = new CookieHeaderValue(FormsAuthentication.FormsCookieName, ticket);
cookie.Path = "/";
var response = Request.CreateResponse(HttpStatusCode.Created, userModel);
response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HttpClient 不从 CookieContainer 发送 cookie 的相关文章

  • 当用户再次访问同一页面时保持登录状态?

    目前我正在使用会话来登录用户 但是当我关闭浏览器并再次打开它时 我必须再次登录 你如何让用户在 2 周内保持登录状态 那么是通过cookie吗 那么您想要 在这台计算机上记住我 选项吗 这是一种与语言无关的方法 创建一个至少包含以下内容的数
  • idleTimeout 和 ShutdownTimeout 之间的区别

    我正在尝试放宽网站的会话过期策略 以便用户可以指定会话超时间隔 我需要弄清楚应该指定哪些网站相关设置 以免过多限制用户 例如 可能需要 1 天的间隔 我将使用门票来实现这一点 现在 我知道我可以在网站的 web config 文件中指定id
  • 如何在 https 连接上检索 cookie?

    我试图将 cookie 保存在使用 SSL 但始终返回 NULL 的 URL 中 private Map
  • 使用 sqlite 离线存储数据的 Web 表单应用程序

    我有一个 asp net Web 表单应用程序 它在远程服务器上使用 sql server 2005 所有控件均使用 linq to sql 绑定 我正在尝试提供完整的离线功能 所以我想知道是否可以像 sql server db 一样创建一
  • UpdatePanel 更新时 ASP 页面滚动到顶部

    我遇到一个问题 我有一个 UpdatePanel 它使用计时器来触发用新点更新 ASP 图表 本质上是位于https web archive org web 20201205213920 https www 4guysfromrolla c
  • 使用 jQuery 将参数从一个 ASP.NET 页面传递到另一页面

    我需要使用 jQuery 将 4 个参数 3 个字符串和一个逗号分隔列表 从 ASP NET 页面传递到另一个 ASP NET 页面 目标页面应该作为单独的窗口启动 这与以下 jQuery 片段配合良好 sourcePageBtn clic
  • 为 html5 输入类型渲染 asp.TextBox =“date”

    不知道以前有没有问过 也没找到 是否可以控制由 asp TextBox 呈现的输入文本的类型 我想把它改成
  • 无法加载 SQL Server Compact 的本机组件

    我已经在 Win7 x64 上安装了 SQL Server Compact Edition 4 0 它可以运行于 Asp Net 和桌面应用程序 此 PC 还安装了 Visual Studio 2010 SP1 但是我的 Server 20
  • 如何在新窗口中打开图像或pdf文件?

    我有一个 gridview 它包含文件名和文件路径 图像和 pdf 格式文件 其中我使用了模板字段 在该字段下放置了 1 个图像按钮 单击该图像按钮 即 查看 按钮 时 我想在新窗口中打开所选文件 这是我的代码 protected void
  • 良好的错误处理实践

    对于 ASP NET 站点来说 什么是良好的错误处理实践 例子 谢谢 与任何 net 项目一样 我发现最好的方法是仅捕获可能发生在给定页面上的特定错误类型 例如 您可以捕获用户给定输入的格式异常 以防 JavaScript 验证失败并且您没
  • 使用 PHP 对 ASP.NET 成员身份中的用户进行身份验证

    我在尝试使用 PHP 针对现有 ASP NET 成员资格数据库对用户进行身份验证时遇到一些问题 我在网上搜索过 发现现有的答案似乎对我不起作用 即 public static function Hash password salt deco
  • 存储在 Session 中的变量在整个页面生命周期中是否反序列化一次或多次?

    我想以类似的方式包装会话变量在 CodeProject 上讨论 http www codeproject com KB aspnet wrapthosesessionvariables aspx msg 2315287 public sta
  • Guid 应包含 32 位数字和 4 个破折号

    我有一个包含 createuserwizard 控件的网站 创建帐户后 验证电子邮件及其验证 URL 将发送到用户的电子邮件地址 但是 当我进行测试运行时 单击电子邮件中的 URL 时 会出现以下错误 Guid should contain
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 正则表达式最多匹配五个单词

    我有一个正则表达式 a zA Z 0 9 1 5 它验证该单词包含字母数字字符和少数特殊字符 并且长度不应超过5人物 如何使此正则表达式接受最多五个与上述正则表达式匹配的单词 a zA Z 0 9 1 5 s a zA Z 0 9 1 5
  • 名称在当前上下文中不存在

    所以 我正在我的笔记本电脑和台式机之间完成这个项目 该项目在笔记本电脑上运行 但现在将更新的源代码复制到桌面上后 我的项目中有超过 500 个错误 所有这些错误都是 该名称在当前上下文中不存在 这是一个例子 职位 aspx
  • 带有 Odata Next Page 和 Count 的 Web Api 未出现在 JSON 响应中

    我有一个 webapi 方法 我想打开 oData 分页等 我按照中的例子http www asp net web api overview odata support in aspnet web api supporting odata
  • 服务器到 Phonegap 推送:SignalR 与 Azure 通知中心

    好吧 我在继续开发 Phonegap 应用程序时陷入了两难境地 对于实时事件通知 我应该使用 Azure 通知中心还是 SignalR 据我了解 SignalR 通过使用 Web Sockets 非常适合实时 Web 应用程序 而通知中心可
  • oracle ExecuteNonQuery 在 ASP.Net 上冻结

    我正在尝试使用 ASP C 和 CLR 4 5 中的 Oracle 连接来运行非查询 这是我的代码 string connectionString ConfigurationManager ConnectionStrings OracleC

随机推荐

  • 同一函数的模板化版本和非模板化版本是否被视为重载?

    一个非常正式的问题 这被认为是过载吗 删除模板与仅重载参数有根本不同吗 template
  • 为客户端付费专区处理 isAccessibleForFree

    试图理解Google 付费内容指南 https developers google com search docs data types paywalled content 我的网站是这样工作的 没有付费订阅的用户每周将获得几次免费阅读 有
  • Django:添加之前检查对象是否已经存在

    如何检查对象是否已存在 并仅在存在时添加它not已经存在 这是代码 如果 follow role 已经存在 我不想在数据库中添加两次 我首先要如何检查 也许可以使用 get 但是如果 get 没有返回任何内容 Django 会抱怨吗 cur
  • 有“pip bundle”的不错的替代品吗?

    I use pip bundle对于我的生产系统 今天我收到了以下令人沮丧的消息 Due to lack of interest and maintenance pip bundle and support for installing f
  • Ubuntu 10.04 64 位上的 Android 开发使用哪个 JDK?

    Ubuntu 10 04 64 位作为 Android 开发环境看起来很有前途 我现在已经启动并运行了它 但我陷入了以下决策点 Synaptic 包管理器有 默认jdk 标准 Java 或 Java 兼容开发套件 sun com 有两个 J
  • C# 类型系统健全且可判定吗?

    我知道Java的类型系统是不健全的 它无法对语义上合法的构造进行类型检查 并且无法确定 它无法对某些构造进行类型检查 例如 如果您将以下代码片段复制 粘贴到类中并编译它 编译器将崩溃并显示StackOverflowException 多么贴
  • 当我使用“pip install mysql-connector”时,“无法找到 Protobuf include 目录”

    当我尝试使用 pip install mysql connector 加载时出现此错误 我也尝试过 pip install Protobuf 但没有解决方案 Python architecture 64 bit Python ARCH 64
  • React-native:node_modules\@react-native-community\masked-view 中缺少 index.js 文件

    我在构建反应本机应用程序时收到以下错误 react native community masked view and react navigation stack是最新的 但不确定为什么在构建时没有解决这个包 error Error Whi
  • 如何使用 matplotlib/python 绘制 ROC 曲线 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想绘制一条 ROC 曲线python with matplotlib并想像这样展示它 假设我们有 0 0 到 1 0 的预测y sc
  • 静态存储持续时间初始化

    在 C 中 静态存储持续时间对象以未指定的顺序初始化 同一编译单元中的除外 代码如下 include
  • jQuery Mobile 谷歌通用分析

    我很高兴使用这个最佳实践http roughlybrilliant com jquery mobile best practices 7 http roughlybrilliant com jquery mobile best practi
  • 定时器中断是否独立于系统处于内核模式还是用户模式?

    在Linux单处理器系统中 定时器中断是否与系统处于内核模式还是用户模式无关 当系统处于内核模式时 定时器中断有什么不同的行为吗 简单的答案是 硬件时钟中断服务例程的执行和动态定时器处理程序的调度都不受硬件时钟中断之前系统所处模式的影响 原
  • 如何观察服务类中的实时数据

    我想将从 API 获得的一些记录插入到我的数据库中 我正在使用服务类来执行此过程 我试图在服务类中使用实时数据的概念 但它要求我的服务类是生命周期所有者 我一直在思考如何让我的服务类观察者实时数据的变化 任何帮助都会很好 如果您的服务不应受
  • Haskell 中类似 OO 的接口实现

    尽管有这个标题 我不会仅仅询问 OO 世界和 Haskell 之间的翻译 但我想不出更好的标题 此讨论类似于但不等于this one https stackoverflow com questions 5474171 oo interfac
  • 按位运算如何提高 Asm.js 的性能?

    在 Asm js 定义的第一行有一个基于 Asm js 的代码示例 它解释了按位运算有助于获得更快的 JS 代码 HEAP32 p gt gt 2 0 or x y 0 我的问题是 这个操作如何提高性能 在 Asm js 或 Emscrip
  • Drools 知识库 已弃用

    我正在将 Drools 规则引擎集成到我的应用程序中 我发现的 99 的入门示例如下 KnowledgeBuilder kbuilder KnowledgeBuilderFactory newKnowledgeBuilder kbuilde
  • 如何验证 WTForms 中的日期字段

    在我的 Flask 应用程序中 我有一个 WTForm 其中有两个日期选择器 分别用于 开始日期 和 结束日期 验证 结束日期 不早于 开始日期 的最佳方法是什么 from flask wtf import FlaskForm from w
  • .NET 自定义事件组织帮助

    作为 C 的新手 我最近一直在研究自定义事件 虽然我认为我现在了解设置自定义事件所需的基本部分 但我无法确定where每件作品都属于 具体来说 这就是我正在尝试做的事情 我有一个表示内部数据结构布局的树控件 当数据在树中重新排列 通过拖放
  • 傅立叶级数数据与 numpy 的拟合:fft 与编码

    假设我有一些数据 y 我想对其进行傅立叶级数拟合 对此post https stackoverflow com questions 4258106 how to calculate a fourier series in numpy 解决方
  • HttpClient 不从 CookieContainer 发送 cookie

    我正在使用 Visual Studio 2012 开发带有 WPF NET 4 0 客户端的 ASP WebAPI ASP MVC 4 应用程序 客户端需要登录到服务器 我使用带有身份验证 cookie 的 FormsAuthenticat