我是第一次测试,如何使用 net.core API + Angular 与 Google 身份验证,我已经实现了通过我的 UI 应用程序获取访问令牌,基本上我开发了一个使用
OAuthService
的 POC
一旦所有的握手都OK了,你就可以调用这个方法了:
this.oAuthService.getAccessToken()
这将产生一个有效的令牌(大概)
因此,现在是时候将其注入后端并验证从 UI 到后端的每个请求了。 为此,我创建了一个具有 Swagger 的 REST API,我添加了能够手动注入不记名令牌(用于测试目的)的语句,现在我正在尝试测试一个非常简单的端点来确认身份验证是否有效。
这是Swagger发送到后端的CURL,我们可以看到授权头已正确添加:
curl -X 'GET' \
'https://localhost:7103/AuthenticationMethod/GetAll' \
-H 'accept: text/plain' \
-H 'Authorization: ya29.a0AfB_byBis8NBGFASFeCEeMg4m9CJY0kusHndtCyMqHL8zBtpp8DsOaL26iuFhW2FpxrroNveQqoVCT5Ug2iPCM0uCTT5MYlBdDfGrjPsGyUR6L3mxwu2R9xlAzRJfZTOsp97swdMRJW2419H-kX5_6klnV27fXcvYlQaCgYKASESARMSFQHGX2MiuCAIYY4jhQkgsH2IwFKBFw0170'
令我惊讶的是,我总是收到 401 错误,并且无法以任何方式进行身份验证。
我创建了这个扩展方法来配置身份验证,所以基本上就是这样:
public static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://accounts.google.com",
ValidAudience = configuration["Authentication:Google:ClientId"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Authentication:Google:ClientSecret"]))
};
});
}
其他需要考虑的要点。
swagger 在“https://localhost:7103”中运行,因此为了以防万一,我将此 url 包含在授权 JavaScript 来源和授权重定向 URI 中
秘密和客户都可以。
当我尝试从 UI 复制/粘贴“GetAccessToken”的结果,并尝试在 jwt.io 中查看其内容时,此页面会抛出一个错误,这很奇怪,就像令牌无效一样。
对于 UI 部分,我使用“angular-oauth2-oidc”开发了 Oauth 握手,我尝试使用“social-login”,但厌倦了我所遇到的大量错误。
我在这里做错了什么? 我尝试了几个关于如何验证谷歌后端的示例,但似乎没有任何效果。
我找到了解决方案,这要归功于一周后弹出的堆栈溢出的“相关问题”。
首先,将“配置”方法更改为这个,这是我从另一篇文章的另一个建议中获取的,当时失败了:
public static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
var googleClientId = configuration["Authentication:Google:ClientId"];
var googleIssuer = "https://accounts.google.com";
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = googleIssuer;
options.Audience = googleClientId;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
ValidateIssuerSigningKey = false,
ValidIssuer = googleIssuer,
ValidAudience = googleClientId,
};
});
}
其次,这基本上是文档中的一个问题,不太清楚(或者至少对我来说不是)access_token 并不意味着在您自己的后端中验证您的用户,它用于在 GOOGLE 中验证您的用户APIS(如获取电子邮件或类似)
这解释了为什么当我添加令牌(来自 getAccessToken())并尝试在 JWT.IO 中解析它时,它抛出了错误。
解决方案,而不是使用:
this.oAuthService.getAccessToken()
我应该使用:
this.oAuthService.getIdToken()
找到这个解决方案感谢: https://developers.google.com/identity/openid-connect/openid-connect#exchangecode
但不是因为它得到了正确的解释,而是因为 id_token 突出显示它是一个 JWT 令牌,我尝试了该令牌,并且我的后端开始正常工作。