在 WinForms 浏览器控件中查看 Google 日历

问题描述 投票:0回答:1

我想在 WinForms 的 WebBrowser 控件中显示我的 Google 日历。

我尝试遵循教程https://www.daimto.com/google-api-and-oath2/

但不幸的是我仍然没有获得访问我的谷歌日历的授权,“浏览器不安全......”。

我知道我必须以某种方式使用访问权限,但我不知道如何使用。

代码:

 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();
        }
    }

教程中的课程:

 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);
        }

    }

After Email input an google login

After i press yes on the previous error message

对不起德国人,但它说的是:“浏览器或应用程序不安全。使用不同的浏览器。”

c# winforms oauth google-oauth google-calendar-api
1个回答
1
投票

我想在 winforms 的网络浏览器控件中显示我的 Google 日历。

您应该了解的第一件事是,如果您想要做的是在应用程序中显示 Google 日历 Web 应用程序,那么如果不使用该代码或任何代码,它就无法工作。

您可以使用 Google 日历 api 访问 Google 日历数据,然后在 Web 表单中创建您自己的数据显示。

这就是您正在使用的代码的设计目的。然而它已经九年多了。

如果可能的话,您应该使用 Google .net 客户端库。话虽如此,您使用的代码最初是九年前为与 .Net 3.5 一起使用而编写的。 google .net 客户端库不支持 .net 3.5。 (我不是指 .Net core 3.1,我们谈论的是更古老的版本。)

自那时以来,安全性发生了很多变化。如果 Google 检测到您正在网络视图中打开它,那么它可能无法工作。如今,身份验证屏幕工作的唯一方法是在计算机上安装的浏览器中打开 oauth 窗口。

.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);
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.