问候,
我真的很难处理谷歌身份验证。我已经达到了这样的地步:通过将用户重定向到一个页面(将在下面提供代码),我可以为用户生成一个身份验证代码,这非常简单。但我找不到将该代码转换为访问令牌的方法。
我尝试使用 ExchangeCodeForTokenAsync,但这要么导致我遇到线程锁定或其他线程问题,因为该方法必须在页面加载时执行。
我找到了一个使用 HttpWebRequest 来调用 api 的解决方案,但这给我带来了错误的请求响应(也将为此提供代码)
我正在使用 DotNetNuke,如果我能够获取用户信息,我可以对他们进行身份验证(我有一个自定义登录,我没有使用 DNN),但为此我需要访问令牌。
重定向到谷歌登录页面:
string redirectUri = "https://url.com/google";
string[] Scopes = { "openid", "email" };
var flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "client_id",
ClientSecret = "client_secret "
},
Scopes = Scopes,
});
var authorizationUrl = flow.CreateAuthorizationCodeRequest(redirectUri).Build();
Response.Redirect(authorizationUrl.AbsoluteUri);
当前重定向页面的代码,经过google auth后获取代码:
public class GoogleToken
{
public string access_token { get; set; }
public string token_type { get; set; }
public int expires_in { get; set; }
public string id_token { get; set; }
public string refresh_token { get; set; }
}
public class GoogleInfo
{
public string id { get; set; }
public string email { get; set; }
public bool verified_email { get; set; }
public string name { get; set; }
public string given_name { get; set; }
public string family_name { get; set; }
public string picture { get; set; }
public string locale { get; set; }
public string gender { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
string ClientId = "client_id";
string ClientSecret = "client_secret";
string redirecturl = "https://url.com/google";
try
{
if (!IsPostBack)
{
string code = Request.QueryString["code"];
if (!string.IsNullOrEmpty(code))
{
string parameters = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code", code,
ClientId,
ClientSecret,
redirecturl);
string response = MakeWebRequest("https://oauth2.googleapis.com/token", "POST", "application/x-www-form-urlencoded", parameters);
GoogleToken tokenInfo = new JavaScriptSerializer().Deserialize<GoogleToken>(response);
if (tokenInfo != null)
{
if (!string.IsNullOrEmpty(tokenInfo.access_token))
{
var googleInfo = MakeWebRequest("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + tokenInfo.access_token, "GET");
GoogleInfo profile = new JavaScriptSerializer().Deserialize<GoogleInfo>(googleInfo);
ltrMSG.Text = googleInfo;
}
}
}
}
}
catch (Exception ex)
{
ltrMSG.Text += "<br/>" + ex.ToString();
}
}
public string MakeWebRequest(string destinationUrl, string methodName, string contentType = "", string requestJSON = "")
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);
request.Method = methodName;
if (methodName == "POST")
{
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(requestJSON);
request.ContentType = contentType;
request.ContentLength = bytes.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}
}
return null;
}
catch (WebException webEx)
{
return webEx.ToString();
}
}
}
如果有人能为我提供我应该做的事情的片段,告诉我我做错了什么或指出我正确的方向,我将不胜感激。 谢谢!
那是Oauth2授权码,不是登录码。更不用说 GoogleAuthorizationCodeFlow 是为已安装的应用程序设计的,如果您尝试将其托管在网络服务器上,它将无法工作。
您应该查看 ASP.NET Core 中的 Google 外部登录设置
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;
services.AddAuthentication().AddGoogle(googleOptions =>
{
googleOptions.ClientId = configuration["Authentication:Google:ClientId"];
googleOptions.ClientSecret = configuration["Authentication:Google:ClientSecret"];
});