c# - Oauth2 使用 ASP .net 核心 MVC 登录到 Google api
问题描述
我一直在关注Web 应用程序 (ASP.NET MVC) 尝试连接到其中一个 Google API。
using System;
using System.Web.Mvc;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Mvc;
using Google.Apis.Drive.v2;
using Google.Apis.Util.Store;
namespace Google.Apis.Sample.MVC4
{
public class AppFlowMetadata : FlowMetadata
{
private static readonly IAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "PUT_CLIENT_ID_HERE",
ClientSecret = "PUT_CLIENT_SECRET_HERE"
},
Scopes = new[] { DriveService.Scope.Drive },
DataStore = new FileDataStore("Drive.Api.Auth.Store")
});
public override string GetUserId(Controller controller)
{
// In this sample we use the session to store the user identifiers.
// That's not the best practice, because you should have a logic to identify
// a user. You might want to use "OpenID Connect".
// You can read more about the protocol in the following link:
// https://developers.google.com/accounts/docs/OAuth2Login.
var user = controller.Session["user"];
if (user == null)
{
user = Guid.NewGuid();
controller.Session["user"] = user;
}
return user.ToString();
}
public override IAuthorizationCodeFlow Flow
{
get { return flow; }
}
}
}
该示例似乎不适用于 .net 核心,因为它找不到 FlowMetadata
解决方案
问题是上述示例不是为 .net 核心设计的。
客户端信息.cs
/// <summary>
/// Client auth information, loaded from a Google user credential json file.
/// Set the TEST_CLIENT_SECRET_FILENAME environment variable to point to the credential file.
/// </summary>
public class ClientInfo
{
public static ClientInfo Load()
{
const string ClientSecretFilenameVariable = "TEST_CLIENT_SECRET_FILENAME";
string clientSecretFilename = Environment.GetEnvironmentVariable(ClientSecretFilenameVariable);
if (string.IsNullOrEmpty(clientSecretFilename))
{
throw new InvalidOperationException($"Please set the {ClientSecretFilenameVariable} environment variable before running tests.");
}
var secrets = JObject.Parse(Encoding.UTF8.GetString(File.ReadAllBytes(clientSecretFilename)))["web"];
var projectId = secrets["project_id"].Value<string>();
var clientId = secrets["client_id"].Value<string>();
var clientSecret = secrets["client_secret"].Value<string>();
return new ClientInfo(projectId, clientId, clientSecret);
}
private ClientInfo()
{
Load();
}
private ClientInfo(string projectId, string clientId, string clientSecret)
{
ProjectId = projectId;
ClientId = clientId;
ClientSecret = clientSecret;
}
public string ProjectId { get; }
public string ClientId { get; }
public string ClientSecret { get; }
}
程序.cs
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
var clientInfo = ClientInfo.Load();
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureServices(services =>
{
services.AddSingleton(clientInfo);
})
.Build();
}
}
startup.cs 配置服务
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "Google";
})
.AddCookie("Cookies")
.AddGoogleOpenIdConnect("Google", options =>
{
var clientInfo = (ClientInfo)services.First(x => x.ServiceType == typeof(ClientInfo)).ImplementationInstance;
options.ClientId = clientInfo.ClientId;
options.ClientSecret = clientInfo.ClientSecret;
options.Scope.Add("profile");
});
}
添加以下配置以及 app.UseAuthentication();
控制器
[GoogleScopedAuthorize("https://www.googleapis.com/auth/analytics.readonly")]
public async Task<IActionResult> GoogleAnalyticsReport([FromServices] IGoogleAuthProvider auth, [FromServices] ClientInfo clientInfo, long ViewId)
{
var cred = await auth.GetCredentialAsync();
var service = new AnalyticsReportingService(new BaseClientService.Initializer
{
HttpClientInitializer = cred
});
登出
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync();
return RedirectToAction("Index");
}
它现在正在登录我的用户,我可以请求数据。
推荐阅读
- c# - 如何为 ListBox 和 ComboBox 选择相同的索引?
- wordpress - 如何在重定向页面上访问联系表格 7 提交的数据?
- pandas - 无法使用索引就地删除熊猫行
- python - 如何在不停止程序的情况下从正在编辑的 CSV 更新 python 程序?
- tensorflow - 为图像处理生成数据
- python - 如何比较python中2个日期集的值?
- mongodb - Mongodb查询计算每个文档的两个日期之间的天数
- python - 缺少的列不会失败.filter?
- ios - 如何在 React Navigation 中动态禁用gestureEnabled?
- c - 错误:在 C 中的 switch 语句中定义二维数组时,“{”之前的预期表达式