如何在ASP.NET Core API中配置Google身份验证
ASP.NET + React 实现Google第三方登录指南
一、修正后端认证配置
你当前的配置存在核心问题:默认认证和挑战Scheme设为了JwtBearer,而Google OAuth登录依赖Cookie处理回调会话,需要调整Scheme配置:
builder.Services.AddAuthentication(options => { // 默认认证用JwtBearer(供API接口验证) options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; // 触发登录挑战时用Google的Scheme options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme; // 临时会话用Cookie保存登录状态(处理Google回调) options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) // 添加Cookie中间件处理临时会话 .AddCookie() .AddJwtBearer(options => { var key = Encoding.UTF8.GetBytes(builder.Configuration["AuthSettings:Key"]); options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidAudience = builder.Configuration["AuthSettings:Audience"], ValidIssuer = builder.Configuration["AuthSettings:Issuer"], RequireExpirationTime = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuerSigningKey = true }; }) .AddGoogle(googleOptions => { googleOptions.ClientId = builder.Configuration["Authentication:Google:ClientId"]; googleOptions.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"]; // 指定回调地址,要和Google开发者控制台配置的一致 googleOptions.CallbackPath = "/api/auth/google-callback"; }); // 注意要在中间件管道中启用认证和授权 app.UseAuthentication(); app.UseAuthorization();
二、添加Google登录回调接口
创建一个AuthController,处理Google登录成功后的逻辑,生成自定义JWT返回给React前端:
[ApiController] [Route("api/auth")] public class AuthController : ControllerBase { private readonly IConfiguration _config; public AuthController(IConfiguration config) { _config = config; } [HttpGet("google-callback")] public async Task<IActionResult> GoogleCallback() { // 获取Google登录后的用户信息 var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); if (!result.Succeeded) { return BadRequest("Google登录验证失败"); } // 从用户信息中提取必要字段(如邮箱、姓名) var email = result.Principal.FindFirstValue(ClaimTypes.Email); var name = result.Principal.FindFirstValue(ClaimTypes.Name); // 生成自定义JWT Token var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.UTF8.GetBytes(_config["AuthSettings:Key"]); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Email, email), new Claim(ClaimTypes.Name, name) }), Expires = DateTime.UtcNow.AddHours(2), Issuer = _config["AuthSettings:Issuer"], Audience = _config["AuthSettings:Audience"], SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); // 可跳转到React前端页面并传递Token,或直接返回Token return Ok(new { Token = tokenString, Email = email, Name = name }); } // 触发Google登录的接口 [HttpGet("google-login")] public IActionResult GoogleLogin() { var properties = new AuthenticationProperties { RedirectUri = "/api/auth/google-callback" }; return Challenge(properties, GoogleDefaults.AuthenticationScheme); } }
三、前端React登录实现
在React中添加登录按钮,触发后端的Google登录接口,处理回调获取Token:
import { useEffect, useState } from 'react'; function Login() { const [token, setToken] = useState(localStorage.getItem('authToken')); // 处理回调页面的Token参数 useEffect(() => { const urlParams = new URLSearchParams(window.location.search); const tokenParam = urlParams.get('token'); if (tokenParam) { localStorage.setItem('authToken', tokenParam); setToken(tokenParam); window.location.href = '/'; } }, []); const handleGoogleLogin = () => { // 跳转到后端的Google登录接口 window.location.href = 'http://your-aspnet-domain/api/auth/google-login'; }; if (token) { return <div>已登录,Token:{token}</div>; } return ( <div> <button onClick={handleGoogleLogin}>使用Google登录</button> </div> ); } export default Login;
四、关键注意事项
- Google开发者控制台配置:确保回调地址(
/api/auth/google-callback)已在Google开发者控制台的OAuth 2.0客户端ID配置中添加,且域名和端口一致。 - 跨域问题:如果React和ASP.NET后端不在同一域名,需在ASP.NET中配置CORS,允许前端域名的请求。
- 配置文件:确保
appsettings.json中的参数正确填写:{ "AuthSettings": { "Key": "your-strong-secret-key-at-least-16-characters", "Issuer": "http://your-aspnet-domain", "Audience": "http://your-react-domain" }, "Authentication": { "Google": { "ClientId": "your-google-client-id", "ClientSecret": "your-google-client-secret" } } }
内容的提问来源于stack exchange,提问作者Semir Hamid
相关产品推荐
相关产品推荐

