在 Winforms 浏览器控件中查看 Google 日历
Viewing Google Calendar in Winfroms Browser Control
我想在 winforms 的网络浏览器控件中显示我的 Google 日历。
我尝试按照教程进行操作 https://www.daimto.com/google-api-and-oath2/
但不幸的是,我仍然没有获得访问我的 google 日历的授权,“浏览器不安全......”。
我知道我必须以某种方式使用访问权限,但我不知道如何使用。
代码:
public partial class Kalender : UserControl
{
public string clientId = "897492813624-glvfpm6heik1fqr7s2mjtl6eme5ad8bq.apps.googleusercontent.com";
public string redirectUri = "https://calendar.google.com/";
public string clientSecret = "HYGFBEd_BZPcWcrPopsX4uZr";
public string redirectURI = "https://calendar.google.com/";
public AuthResponse access;
public Kalender()
{
InitializeComponent();
webKalender.Navigate(AuthResponse.GetAutenticationURI(clientId, redirectUri));
}
private void webKalender_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
string Mytitle = ((WebBrowser)sender).DocumentTitle.ToLower();
if (Mytitle.IndexOf("success code=") > -1)
{
webKalender.Visible = false;
// searching the body for our code
string AuthCode = webKalender.DocumentTitle.Replace("Success code=", "");
string webText = ((WebBrowser)sender).DocumentText;
int start = webText.IndexOf("id=\"code\"");
start = webText.IndexOf(AuthCode, start);
int end = webText.IndexOf('"', start);
string authCode = webText.Substring(start, end - start);
//Exchange the code for Access token and refreshtoken.
access = AuthResponse.Exchange(authCode, clientId, clientSecret, redirectURI);
//processAccess();
}
}
教程中的 class:
public class AuthResponse
{
private string access_token;
public string Access_token
{
get
{
// Access token lasts an hour if its expired we get a new one.
if (DateTime.Now.Subtract(created).Hours > 1)
{
refresh();
}
return access_token;
}
set { access_token = value; }
}
public string refresh_token { get; set; }
public string clientId { get; set; }
public string secret { get; set; }
public string expires_in { get; set; }
public DateTime created { get; set; }
//"{\n \"access_token\" : \"ya29.kwFUj-la2lATSkrqFlJXBqQjCIZiTg51GYpKt8Me8AJO5JWf0Sx6-0ZWmTpxJjrBrxNS_JzVw969LA\",\n \"token_type\" : \"Bearer\",\n \"expires_in\" : 3600,\n \"refresh_token\" : \"1/ejoPJIyBAhPHRXQ7pHLxJX2VfDBRz29hqS_i5DuC1cQ\"\n}"
public static AuthResponse get(string response)
{
AuthResponse result = (AuthResponse)JsonConvert.DeserializeObject(response);
result.created = DateTime.Now; // DateTime.Now.Add(new TimeSpan(-2, 0, 0)); //For testing force refresh.
return result;
}
public void refresh()
{
var request = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
string postData = string.Format("client_id={0}&client_secret={1}&refresh_token={2}&grant_type=refresh_token", this.clientId, this.secret, this.refresh_token);
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var refreshResponse = AuthResponse.get(responseString);
this.access_token = refreshResponse.access_token;
this.created = DateTime.Now;
}
public static AuthResponse Exchange(string authCode, string clientid, string secret, string redirectURI)
{
var request = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
string postData = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code", authCode, clientid, secret, redirectURI);
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var x = AuthResponse.get(responseString);
x.clientId = clientid;
x.secret = secret;
return x;
}
public static Uri GetAutenticationURI(string clientId, string redirectUri)
{
string scopes = "https://www.googleapis.com/auth/calendar";
if (string.IsNullOrEmpty(redirectUri))
{
redirectUri = "urn:ietf:wg:oauth:2.0:oob";
}
string oauth = string.Format("https://accounts.google.com/o/oauth2/auth?client_id={0}&redirect_uri={1}&scope={2}&response_type=code", clientId, redirectUri, scopes);
return new Uri(oauth);
}
}
对不起德国人,但它说的是:“浏览器或应用程序我不安全。使用不同的浏览器。”
I want to show my Google Calendar in a webbrowser control from winforms.
您应该了解的第一件事是,如果您尝试做的是在您的应用程序中显示 Google 日历 Web 应用程序,那么如果不使用该代码或任何代码,它就无法工作。
您可以使用 Google 日历 api 访问 Google 日历数据,然后在您的 Web 表单中创建您自己的数据显示。
这就是您使用的代码的设计目的。然而它已经九岁多了。
如果可能的话,您应该使用 Google .net 客户端库。话虽如此,您使用的代码最初是在九年前为 .Net 3.5 编写的。 google .net 客户端库不支持 .net 3.5。 (我指的不是 .Net core 3.1,我们说的要老得多。)
从那时起,安全性发生了很多变化。如果 Google 检测到您正在 web 视图中打开它,那么它可能无法正常工作。这些天授权屏幕工作的唯一方法是在机器上安装的浏览器中打开 oauth window。
.net 客户端库正是为此而设计的。
这是一些可以帮助您入门的授权代码。
public static class Oauth2Example
{
/// <summary>
/// ** Installed Aplication only **
/// This method requests Authentcation from a user using Oauth2.
/// </summary>
/// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
/// <param name="userName">Identifying string for the user who is being authentcated.</param>
/// <param name="scopes">Array of Google scopes</param>
/// <returns>CalendarService used to make requests against the Calendar API</returns>
public static CalendarService GetCalendarService(string clientSecretJson, string userName, string[] scopes)
{
try
{
if (string.IsNullOrEmpty(userName))
throw new ArgumentNullException("userName");
if (string.IsNullOrEmpty(clientSecretJson))
throw new ArgumentNullException("clientSecretJson");
if (!File.Exists(clientSecretJson))
throw new Exception("clientSecretJson file does not exist.");
var cred = GetUserCredential(clientSecretJson, userName, scopes);
return GetService(cred);
}
catch (Exception ex)
{
throw new Exception("Get Calendar service failed.", ex);
}
}
/// <summary>
/// ** Installed Aplication only **
/// This method requests Authentcation from a user using Oauth2.
/// Credentials are stored in System.Environment.SpecialFolder.Personal
/// Documentation https://developers.google.com/accounts/docs/OAuth2
/// </summary>
/// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
/// <param name="userName">Identifying string for the user who is being authentcated.</param>
/// <param name="scopes">Array of Google scopes</param>
/// <returns>authencated UserCredential</returns>
private static UserCredential GetUserCredential(string clientSecretJson, string userName, string[] scopes)
{
try
{
if (string.IsNullOrEmpty(userName))
throw new ArgumentNullException("userName");
if (string.IsNullOrEmpty(clientSecretJson))
throw new ArgumentNullException("clientSecretJson");
if (!File.Exists(clientSecretJson))
throw new Exception("clientSecretJson file does not exist.");
// These are the scopes of permissions you need. It is best to request only what you need and not all of them
using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
// Requesting Authentication or loading previously stored authentication for userName
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
scopes,
userName,
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
credential.GetAccessTokenForRequestAsync();
return credential;
}
}
catch (Exception ex)
{
throw new Exception("Get user credentials failed.", ex);
}
}
/// <summary>
/// This method get a valid service
/// </summary>
/// <param name="credential">Authecated user credentail</param>
/// <returns>CalendarService used to make requests against the Calendar API</returns>
private static CalendarService GetService(UserCredential credential)
{
try
{
if (credential == null)
throw new ArgumentNullException("credential");
// Create Calendar API service.
return new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Calendar Oauth2 Authentication Sample"
});
}
catch (Exception ex)
{
throw new Exception("Get Calendar service failed.", ex);
}
}
}
我想在 winforms 的网络浏览器控件中显示我的 Google 日历。
我尝试按照教程进行操作 https://www.daimto.com/google-api-and-oath2/
但不幸的是,我仍然没有获得访问我的 google 日历的授权,“浏览器不安全......”。
我知道我必须以某种方式使用访问权限,但我不知道如何使用。
代码:
public partial class Kalender : UserControl
{
public string clientId = "897492813624-glvfpm6heik1fqr7s2mjtl6eme5ad8bq.apps.googleusercontent.com";
public string redirectUri = "https://calendar.google.com/";
public string clientSecret = "HYGFBEd_BZPcWcrPopsX4uZr";
public string redirectURI = "https://calendar.google.com/";
public AuthResponse access;
public Kalender()
{
InitializeComponent();
webKalender.Navigate(AuthResponse.GetAutenticationURI(clientId, redirectUri));
}
private void webKalender_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
string Mytitle = ((WebBrowser)sender).DocumentTitle.ToLower();
if (Mytitle.IndexOf("success code=") > -1)
{
webKalender.Visible = false;
// searching the body for our code
string AuthCode = webKalender.DocumentTitle.Replace("Success code=", "");
string webText = ((WebBrowser)sender).DocumentText;
int start = webText.IndexOf("id=\"code\"");
start = webText.IndexOf(AuthCode, start);
int end = webText.IndexOf('"', start);
string authCode = webText.Substring(start, end - start);
//Exchange the code for Access token and refreshtoken.
access = AuthResponse.Exchange(authCode, clientId, clientSecret, redirectURI);
//processAccess();
}
}
教程中的 class:
public class AuthResponse
{
private string access_token;
public string Access_token
{
get
{
// Access token lasts an hour if its expired we get a new one.
if (DateTime.Now.Subtract(created).Hours > 1)
{
refresh();
}
return access_token;
}
set { access_token = value; }
}
public string refresh_token { get; set; }
public string clientId { get; set; }
public string secret { get; set; }
public string expires_in { get; set; }
public DateTime created { get; set; }
//"{\n \"access_token\" : \"ya29.kwFUj-la2lATSkrqFlJXBqQjCIZiTg51GYpKt8Me8AJO5JWf0Sx6-0ZWmTpxJjrBrxNS_JzVw969LA\",\n \"token_type\" : \"Bearer\",\n \"expires_in\" : 3600,\n \"refresh_token\" : \"1/ejoPJIyBAhPHRXQ7pHLxJX2VfDBRz29hqS_i5DuC1cQ\"\n}"
public static AuthResponse get(string response)
{
AuthResponse result = (AuthResponse)JsonConvert.DeserializeObject(response);
result.created = DateTime.Now; // DateTime.Now.Add(new TimeSpan(-2, 0, 0)); //For testing force refresh.
return result;
}
public void refresh()
{
var request = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
string postData = string.Format("client_id={0}&client_secret={1}&refresh_token={2}&grant_type=refresh_token", this.clientId, this.secret, this.refresh_token);
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var refreshResponse = AuthResponse.get(responseString);
this.access_token = refreshResponse.access_token;
this.created = DateTime.Now;
}
public static AuthResponse Exchange(string authCode, string clientid, string secret, string redirectURI)
{
var request = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
string postData = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code", authCode, clientid, secret, redirectURI);
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var x = AuthResponse.get(responseString);
x.clientId = clientid;
x.secret = secret;
return x;
}
public static Uri GetAutenticationURI(string clientId, string redirectUri)
{
string scopes = "https://www.googleapis.com/auth/calendar";
if (string.IsNullOrEmpty(redirectUri))
{
redirectUri = "urn:ietf:wg:oauth:2.0:oob";
}
string oauth = string.Format("https://accounts.google.com/o/oauth2/auth?client_id={0}&redirect_uri={1}&scope={2}&response_type=code", clientId, redirectUri, scopes);
return new Uri(oauth);
}
}
对不起德国人,但它说的是:“浏览器或应用程序我不安全。使用不同的浏览器。”
I want to show my Google Calendar in a webbrowser control from winforms.
您应该了解的第一件事是,如果您尝试做的是在您的应用程序中显示 Google 日历 Web 应用程序,那么如果不使用该代码或任何代码,它就无法工作。
您可以使用 Google 日历 api 访问 Google 日历数据,然后在您的 Web 表单中创建您自己的数据显示。
这就是您使用的代码的设计目的。然而它已经九岁多了。
如果可能的话,您应该使用 Google .net 客户端库。话虽如此,您使用的代码最初是在九年前为 .Net 3.5 编写的。 google .net 客户端库不支持 .net 3.5。 (我指的不是 .Net core 3.1,我们说的要老得多。)
从那时起,安全性发生了很多变化。如果 Google 检测到您正在 web 视图中打开它,那么它可能无法正常工作。这些天授权屏幕工作的唯一方法是在机器上安装的浏览器中打开 oauth window。
.net 客户端库正是为此而设计的。
这是一些可以帮助您入门的授权代码。
public static class Oauth2Example
{
/// <summary>
/// ** Installed Aplication only **
/// This method requests Authentcation from a user using Oauth2.
/// </summary>
/// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
/// <param name="userName">Identifying string for the user who is being authentcated.</param>
/// <param name="scopes">Array of Google scopes</param>
/// <returns>CalendarService used to make requests against the Calendar API</returns>
public static CalendarService GetCalendarService(string clientSecretJson, string userName, string[] scopes)
{
try
{
if (string.IsNullOrEmpty(userName))
throw new ArgumentNullException("userName");
if (string.IsNullOrEmpty(clientSecretJson))
throw new ArgumentNullException("clientSecretJson");
if (!File.Exists(clientSecretJson))
throw new Exception("clientSecretJson file does not exist.");
var cred = GetUserCredential(clientSecretJson, userName, scopes);
return GetService(cred);
}
catch (Exception ex)
{
throw new Exception("Get Calendar service failed.", ex);
}
}
/// <summary>
/// ** Installed Aplication only **
/// This method requests Authentcation from a user using Oauth2.
/// Credentials are stored in System.Environment.SpecialFolder.Personal
/// Documentation https://developers.google.com/accounts/docs/OAuth2
/// </summary>
/// <param name="clientSecretJson">Path to the client secret json file from Google Developers console.</param>
/// <param name="userName">Identifying string for the user who is being authentcated.</param>
/// <param name="scopes">Array of Google scopes</param>
/// <returns>authencated UserCredential</returns>
private static UserCredential GetUserCredential(string clientSecretJson, string userName, string[] scopes)
{
try
{
if (string.IsNullOrEmpty(userName))
throw new ArgumentNullException("userName");
if (string.IsNullOrEmpty(clientSecretJson))
throw new ArgumentNullException("clientSecretJson");
if (!File.Exists(clientSecretJson))
throw new Exception("clientSecretJson file does not exist.");
// These are the scopes of permissions you need. It is best to request only what you need and not all of them
using (var stream = new FileStream(clientSecretJson, FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
// Requesting Authentication or loading previously stored authentication for userName
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets,
scopes,
userName,
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
credential.GetAccessTokenForRequestAsync();
return credential;
}
}
catch (Exception ex)
{
throw new Exception("Get user credentials failed.", ex);
}
}
/// <summary>
/// This method get a valid service
/// </summary>
/// <param name="credential">Authecated user credentail</param>
/// <returns>CalendarService used to make requests against the Calendar API</returns>
private static CalendarService GetService(UserCredential credential)
{
try
{
if (credential == null)
throw new ArgumentNullException("credential");
// Create Calendar API service.
return new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Calendar Oauth2 Authentication Sample"
});
}
catch (Exception ex)
{
throw new Exception("Get Calendar service failed.", ex);
}
}
}