基于.NET后端+React前端的Google登录功能实现问题排查
.NET Core + React 集成Google第三方登录问题及解决
编辑(感谢@possum)
以下代码已可正常运行。
注意避坑
- 在
.AddGoogle()配置中可指定自定义回调,该回调是.AddGoogle与前端之间认证机制的内部回调,无需自行实现。 - 回调端点必须在
ConfigureExternalAuthenticationProperties("Google", *回调URL,用户登录后的端点*)中指定。
问题背景
我正在实现通过Google(及其他第三方提供商)登录后端的功能,这是我的第一个React项目。查阅相关文章和问题后,我写出了以下代码,但遇到了问题。
控制器代码
[HttpPost("google-login")] [AllowAnonymous] [OpenApiOperation("Login / Signup by an external provider.", "Connection with Google, Microsoft, etc")] public IActionResult GoogleLogin() { var redirectUrl = $"https://localhost:5001/api/authentication/google-login-callback"; var properties = _authenticationService.ConstructHandleForGoogleLogin("Google", redirectUrl); return Challenge( properties, "Google"); } [HttpGet("google-login-callback")] [AllowAnonymous] [OpenApiOperation("Callback of agent of login provider.", "Connection with Google, Microsoft, etc")] public async Task<ActionResult> GoogleLoginCallback() { var authenticateResult = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme); throw new Exception(); }
认证服务代码
public AuthenticationProperties ConstructHandleForGoogleLogin(string provider, string redirectUrl) { if (provider.ToLowerInvariant() != "google") throw new InvalidOperationException("Bad provider requested, this is only for Google"); var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); properties.AllowRefresh = true; return properties; }
配置代码
internal static class Startup { private static readonly ILogger _logger = Log.ForContext(typeof(Startup)); internal static IServiceCollection AddGoogleAuthentication(this IServiceCollection services, IConfiguration config) { _logger.Information("Third partie authentication enabled : {0}", "Google"); services.AddOptions<AuthenticationGoogleSettings>() .BindConfiguration($"SecuritySettings:{nameof(AuthenticationGoogleSettings)}") .ValidateDataAnnotations() .ValidateOnStart(); services .AddAuthorization() .AddAuthentication(authentication => { authentication.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; authentication.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddCookie() .AddGoogle(googleOptions => { googleOptions.ClientId = config["SecuritySettings:AuthenticationGoogleSettings:ClientId"]; googleOptions.ClientSecret = config["SecuritySettings:AuthenticationGoogleSettings:ClientSecret"]; //googleOptions.CallbackPath = "/api/authentication/google-login-callback"; <- TIMEWAST ALERT googleOptions.AuthorizationEndpoint += "?prompt=consent"; googleOptions.AccessType = "offline"; googleOptions.Scope.Add("profile"); googleOptions.SignInScheme = IdentityConstants.ExternalScheme; }); services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.Strict; }); return services; } }
前端代码
<form method='POST' action={`https://localhost:5001/api/authentication/google-login`} > <IconButton type='submit' name='provider' value='Google'> <Iconify icon="eva:google-fill" color="#DF3E30" /> </IconButton> </form>
内容的提问来源于stack exchange,提问作者Benoit
相关产品推荐
相关产品推荐

