authentication - Google Auth:“oauth 状态丢失或无效。位置未知”
问题描述
我正在尝试在 ASP.NET Core 3 上设置 Google Auth,但出现此错误:
oauth 状态丢失或无效。位置不明
我的 Startup.cs 文件如下所示:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllersWithViews()
.AddRazorRuntimeCompilation();
services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddSingleton<IPaddleSettingsService, PaddleSettingsService>();
services.AddScoped<IPaymentProviderService, PaddlePaymentProviderService>();
services.Configure<AppConstants>(Configuration);
services
.AddAuthentication(o =>
{
o.DefaultScheme = "Application";
o.DefaultSignInScheme = "External";
})
.AddCookie("Application")
.AddCookie("External")
.AddGoogle(o =>
{
o.ClientId = Configuration["GoogleClientId"];
o.ClientSecret = Configuration["GoogleClientSecret"];
o.CallbackPath = new PathString("/a/signin-callback");
o.ReturnUrlParameter = new PathString("/");
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpsRedirection();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
控制器:
[Route("a")]
/*[Route("Account")]*/ //Adding additional Account route to controller solves the problem. Why?
public class AccountController : Controller
{
private readonly IOptions<AppConstants> _appConstants;
private readonly IPaymentProviderService _paymentProvider;
public AccountController(IOptions<AppConstants> appConstants, IPaymentProviderService paymentProvider)
{
_appConstants = appConstants;
_paymentProvider = paymentProvider;
}
[Route("signin-google")]
public IActionResult Signin(string returnUrl)
{
return new ChallengeResult(
GoogleDefaults.AuthenticationScheme,
new AuthenticationProperties
{
RedirectUri = Url.Action(nameof(GoogleCallback), new { returnUrl })
});
}
[Route("signin-callback")]
public async Task<IActionResult> GoogleCallback(string returnUrl)
{
var authenticateResult = await HttpContext.AuthenticateAsync("External");
if (!authenticateResult.Succeeded) return LocalRedirect("/#signinerr");
var emailClaim = authenticateResult.Principal.FindFirst(ClaimTypes.Email);
var activeSubscriptions = await _paymentProvider.GetUserActiveSubscriptions(emailClaim.Value);
if (activeSubscriptions.Length != 0)
{
var activeSubscription = activeSubscriptions.First(a => a.State == "active");
SetCookies(emailClaim.Value, activeSubscription.UserId, activeSubscription.SubscriptionId);
return LocalRedirect("/");
}
ClearCookies();
return LocalRedirect("/#signinerr");
}
}
google 中的授权网址如下,与我的本地网址完美匹配:
http://localhost:5000/a/signin-callback
当我选择一个帐户来授权表单谷歌时,我收到错误,但如果我添加
[Route("Account")]
到控制器的路由然后一切正常。我不明白为什么添加 Account 路由会有所不同?知道引擎盖下发生了什么吗?
解决方案
我有同样的问题,最后,我设法解决了它。问题是登录后将继续执行的googleOptions.CallbackPath
不是API 端点。它是用于某些内部身份验证逻辑的内部端点。如果要更改回调端点,则必须以另一种方式进行。
更多细节在这里发布https://github.com/dotnet/aspnetcore/issues/22125
但长话短说 -googleOptions.CallbackPath
保持不变并将返回 url 作为参数传递AuthenticationProperties
推荐阅读
- json - VS Code 中 settings.json 中的尾随逗号错误
- flutter - Flutter RawKeyboardListener 不适用于条形码扫描仪设备
- java - 使 class.getResource("/some.properties") 工作
- java - 是否需要关闭 Java 打开的进程?
- go - 为什么 Go 中的 bool 类型是 16 字节长?
- c# - Setting target to x86 in Visual studio code for 'Microsoft.Jet.OLEDB.4.0' provider is not registered on the local machine error
- javascript - jspdf 强制 pdf 放在一个位置,但我的 pdf 有大量数据,因此在一页中几乎看不到
- python - 如果比较 numpy 数组的语句引发 ValueError
- javascript - 函数内的 axios.get()
- python - 根据另一列中的类 (1,2,3) 将 NaN 值替换为一列中的所需值