目录
介绍
背景
Cookie身份验证事件
Cookie记录中间件
预防措施
结论
介绍有时,我们必须在开发站点或生产站点中登录Cookie以进行调试。我们有过这样的情况。
背景在我们为Android客户端提供数据的大型Web API中,我们对客户端和服务器通信使用了身份验证。应用程序的身份验证基于唯一生成的身份验证令牌。只要需要登录,它就会自动发生。有一次,我们遇到了一个问题,该问题是从我们的客户端请求的,该问题通过了一个请求的身份验证,但在对同一URI的第一个请求之后立即提出的下一个请求失败了。我们在其他任何应用程序中都没有遇到过这种情况。该错误仅发生在超过200台设备的一两台设备中。
然后我们开始调试会话。首先,我们验证登录令牌是否有效,即有效,然后我们进入流程的下一步。从任何角度来看,我们在业务方面所做的一切看起来都很好。我们不知道发生了什么。如果API端确实存在这个问题,为什么选择一两个设备有问题,而不是全部?
最后,我们进入了我们作为cookie获取的调试会话,因为身份验证仅基于cookie,对。如果提交的cookie有效,则问题出在API端。如果cookie不是我们给他们的,那么问题出在应用程序端。为了进行这个调试会话,我们开始分析如何记录cookie。要了解/记录cookie,我们必须了解以下详细信息:
- 服务器在登录时生成的Cookie
- 客户端在每次请求时提交的Cookie
对于这个大问题,ASP.NET Core提供了最佳解决方案。我们采取了:
- Cookie身份验证事件以了解生成的cookie
- 中间件知道提交的cookie
允许订阅cookie身份验证期间引发的事件。通过订阅cookie身份验证事件,我们可以知道cookie及其值。这个cookie认证事件主要有以下几个事件:
- RedirectToAccessDenied
- RedirectToLogin
- RedirectToLogout
- RedirectToReturnURL
- SigningIn
- SignedIn
- SignedOut
- ValidatePrincipal
我们使用了RedirectToAccessDenied, SignedIn,SigningIn事件。
最后我们的CookieAuthenticationEvents类看起来像这样:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Threading.Tasks;
namespace Web
{
public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
{
public override Task RedirectToAccessDenied
(RedirectContext context)
{
//Logging the required details
//Request Body has the client submitted cookie, if submitted
//Request available in the context. `context.HttpContext.Request`
return base.RedirectToAccessDenied(context);
}
public override Task SigningIn(CookieSigningInContext context)
{
//Logging the required details
return base.SigningIn(context);
}
public override Task SignedIn(CookieSignedInContext context)
{
//Logging the required details
//Generated new cookie information available here. In the request Body.
//Request available in the HttpContext. `context.HttpContext.Request`
return base.SigningIn(context);
}
}
}
我们不得不提一下,这是某个地方的cookie身份验证事件侦听器,对吧。这是在我们定义cookie身份验证方案的地方完成的。在我们的方法中,这是startup.cs类。此身份验证配置在startup.cs类的ConfigureServices部分下完成。在startup类上的某个地方,我们肯定使用了以下内容:
public void ConfigureServices(IServiceCollection services)
{
...
services
.AddAuthentication()
.AddCookie("", options =>
{
...
});
...
}
提到CookieAuthenticationEvents,我们将对上面的代码块进行以下更改:
public void ConfigureServices(IServiceCollection services)
{
...
services
.AddAuthentication()
.AddCookie("", options =>
{
...
options.Events =
new MyCookieAuthenticationEvents(); // this is newly added line
});
...
}
现在,这将告诉我们生成了什么cookie和相关详细信息。
Cookie记录中间件我们分析的第二大部分是记录cookie。为此,我们决定使用中间件。我们的cookie记录中间件看起来像:
using System.Threading.Tasks;
namespace Web
{
public class MyCookieLogMiddleware
{
private readonly RequestDelegate _next;
public MyCookieLogMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await _next.Invoke(context);
//Logging the required details
//Submitted Cookies available in the request. `context.Request.Cookies`
//Generated or response cookies available in the response header.
// `context.Response.Headers["Set-Cookie"]`
)
}
}
要使用这个中间件,我们必须将它添加到我们的应用程序的ApplicationBuilder中,这也可以通过startup.cs类完成。这个Startup.cs类有Configure方法。这可以通过中间件扩展轻松完成。
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMyCookieLogMiddleware
(this IApplicationBuilder instance)
{
return instance.UseMiddleware();
}
}
最后,在startup.cs中:
public void Configure(IApplicationBuilder app,
IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseAuthentication();
app.UseCookieLogMiddleware(); //this is the line we have to include.
...
app.UseMvc();
}
这个cookie日志记录中间件应该出现在UseAuthentication和UseMvc中间件定义之间。完毕!现在尝试记录cookie。
预防措施身份验证cookie是更敏感的信息。如果有人得到这些信息,那么我们就会有麻烦,所以请注意这一点。不要永久启用它,也不要在第三方访问的任何公共场所记录/写入cookie。
结论这个技巧可以帮助那些寻找解决方案来记录由服务器生成并由客户端应用程序提交的cookie的人。
https://www.codeproject.com/Tips/5306783/Cookie-Logging-In-Middleware-of-ASP-NET-Core-Web-A