{"id":3359,"date":"2017-03-13T07:01:09","date_gmt":"2017-03-13T05:01:09","guid":{"rendered":"http:\/\/www.limilabs.com\/blog\/?p=3359"},"modified":"2022-05-04T13:37:43","modified_gmt":"2022-05-04T11:37:43","slug":"oauth2-gmail-imap-installed-applications","status":"publish","type":"post","link":"https:\/\/www.limilabs.com\/blog\/oauth2-gmail-imap-installed-applications","title":{"rendered":"OAuth 2.0 with Gmail over IMAP for installed applications"},"content":{"rendered":"\n<div class=\"well\">You can also read how to use:\n<p>&nbsp;<\/p>\n<ul>\n<li><a href=\"\/blog\/oauth2-gmail-imap-web-applications\">OAuth 2.0 with Gmail over IMAP for web applications (Google.Apis)<\/a><\/li>\n<li>OAuth 2.0 with Gmail over IMAP for installed applications (Google.Apis)<\/li>\n<li><a href=\"\/blog\/oauth2-gmail-imap-service-account\">OAuth 2.0 with Gmail over IMAP for service account (Google.Apis)<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2009\/11\/gmail.png\" alt=\"\" title=\"gmail\"\/><\/figure><\/div>\n\n\n\n<p><strong>OAuth 2.0 <\/strong> is an open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.<\/p>\n\n\n\n<p>This article describes using OAuth 2.0 to access Gmail IMAP and SMTP servers using <a href=\"\/mail\">.NET IMAP component<\/a> in installed applications scenario. You can also use <a href=\"\/blog\/oauth2-gmail-imap-web-applications\">OAuth 2.0 for web applications.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Google.Apis<\/h2>\n\n\n\n<p>Use Nuget to download &#8220;<strong>Google.Apis.Auth<\/strong>&#8221; package.<\/p>\n\n\n\n<p>Import namespaces:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ c#\n\nusing Google.Apis.Auth.OAuth2;\nusing Google.Apis.Auth.OAuth2.Flows;\nusing Google.Apis.Auth.OAuth2.Requests;\nusing Google.Apis.Auth.OAuth2.Responses;\n\nusing Limilabs.Client.Authentication.Google;\n\nusing Limilabs.Client.IMAP;\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET \n\nImports Google.Apis.Auth.OAuth2\nImports Google.Apis.Auth.OAuth2.Flows\nImports Google.Apis.Auth.OAuth2.Requests\nImports Google.Apis.Auth.OAuth2.Responses\n\nImports Limilabs.Client.Authentication.Google\n\nImports Limilabs.Client.IMAP\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Register Application<\/h2>\n\n\n\n<p>Before you can use OAuth 2.0, you must register your application using the <a href=\"https:\/\/cloud.google.com\/console\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Google Cloud Console<\/a>. After you\u2019ve registered  copy the \u201c<strong>Client ID<\/strong>\u201d and \u201c<strong>Client secret<\/strong>\u201d values which you\u2019ll need later.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_1a.png\" alt=\"\" title=\"Access Google API\"\/><\/figure>\n\n\n\n<p>At least product name must be specified:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_1b.png\" alt=\"\" title=\"Access Google API\"\/><\/figure>\n\n\n\n<p>Now create credentials:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_1c.png\" alt=\"\" title=\"Access Google API\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_1d_installed.png\" alt=\"\" title=\"Access Google API\"\/><\/figure>\n\n\n\n<p>After you&#8217;ve registered, copy the &#8220;<strong>Client ID<\/strong>&#8221; and &#8220;<strong>Client secret<\/strong>&#8221; values, which you&#8217;ll need later:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_1e.png\" alt=\"\" title=\"Access Google API\"\/><\/figure>\n\n\n\n<p>Now we can define clientID, clientSecret and scope variables, as well as Google OAuth 2.0 server addresses. Scope basically specifies what services we want to have access to. In our case it is user&#8217;s email address and IMAP\/SMTP access:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nstring clientID = \"XXX.apps.googleusercontent.com\";\nstring clientSecret = \"IxBs0g5sdaSDUz4Ea7Ix-Ua\";\n\nvar clientSecrets = new ClientSecrets\n{\n    ClientId = clientID,\n    ClientSecret = clientSecret\n};\n\nvar credential = new GoogleAuthorizationCodeFlow(\n    new GoogleAuthorizationCodeFlow.Initializer\n    {\n        ClientSecrets = clientSecrets,\n        Scopes = new&#x5B;] { \n            GoogleScope.ImapAndSmtp.Name, \n            GoogleScope.UserInfoEmailScope.Name}\n    });\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET \n\nDim clientID As String = \"XXX.apps.googleusercontent.com\"\nDim clientSecret As String = \"IxBs0g5sdaSDUz4Ea7Ix-Ua\"\n\nDim clientSecrets = New ClientSecrets With { _\n\t.ClientId = clientID, _\n\t.ClientSecret = clientSecret _\n}\n\nDim credential = New GoogleAuthorizationCodeFlow( _\n    New GoogleAuthorizationCodeFlow.Initializer With { _\n    \t.ClientSecrets = clientSecrets, _\n\t    .Scopes = { _\n            GoogleScope.ImapAndSmtp.Name,  _\n            GoogleScope.UserInfoEmailScope.Name} _\n})\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Obtain an OAuth 2.0 access token<\/h2>\n\n\n\n<p>Now we&#8217;ll create authorization url. <\/p>\n\n\n\n<p>As OOB addresses are no longer supported, to receive the authorization code using this URL, your application must be listening on the local web server. This is the recommended mechanism for obtaining the authorization code.<\/p>\n\n\n\n<p>When your app receives the authorization response, for best usability it should respond by displaying an HTML page that instructs the user to close the browser and return to your app.<\/p>\n\n\n\n<p>Your application needs to create a server that listens on this local address:<\/p>\n\n\n\n<p><code>http:\/\/127.0.0.1:<var>port<\/var><\/code>&nbsp;or&nbsp;<code>http:\/\/[::1]:<var>port<\/var><\/code> or <code>http:\/\/localhost:<var>port<\/var><\/code><\/p>\n\n\n\n<p>Query your platform for the relevant loopback IP address and start an HTTP listener on a random available port. Substitute&nbsp;<var>port<\/var>&nbsp;with the actual port number your app listens on.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nAuthorizationCodeRequestUrl url = credential\n    .CreateAuthorizationCodeRequest(\"http:\/\/127.0.0.1:1234\/auth2callback\");\n\nProcess.Start(url.Build().ToString());\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET \n\nDim url As AuthorizationCodeRequestUrl = credential _\n    .CreateAuthorizationCodeRequest(\"http:\/\/127.0.0.1:1234\/auth2callback\")\n\nProcess.Start(url.Build().ToString())\n<\/pre><\/div>\n\n\n<p>We are using <em>Process.Start<\/em> here, but you can also embed <em>WebBrowser<\/em> control in your application.<\/p>\n\n\n\n<p>At this point user is redirected to Google to authorize the access:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_2.png\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>After this step user is redirected to the loopback address you provided. <\/p>\n\n\n\n<p>Your application&#8217;s local web server, listening on this address, should obtain code from the url parameter.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/09\/OAuth2_3_installed.png\" alt=\"\" title=\"OAuth 2.0 code to be pasted to your application\"\/><\/figure>\n\n\n\n<p>Following is a code that reads this code and contacts Google to exchange it for a refresh-token and an access-token:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nstring authCode = \"get from the url\";\n\nTokenResponse token = await credential.ExchangeCodeForTokenAsync(\n    \"\", \n    authCode, \n    \"http:\/\/127.0.0.1\/auth2callback\", \n    CancellationToken.None);\n\nstring accessToken = token.AccessToken;\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET \n\nDim authCode As String = \"get from the url\";\n\nDim token As TokenResponse = Await credential.ExchangeCodeForTokenAsync( _\n    \"\",  _\n    authCode,  _\n    \"http:\/\/127.0.0.1\/auth2callback\",  _\n    CancellationToken.None)\n\nDim accessToken As String = token.AccessToken\n<\/pre><\/div>\n\n\n<p>An access token is usually valid for a maximum of one hour, and allows you to access the user&#8217;s data. You also received a refresh token. A refresh token can be used to request a new access token once the previous expired.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Access IMAP\/SMTP server<\/h2>\n\n\n\n<p>Finally we&#8217;ll ask Google for user&#8217;s email and use <em>LoginOAUTH2<\/em> method to access Gmail&#8217;s IMAP server:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ C#\n\nGoogleApi api = new GoogleApi(accessToken);\nstring user = api.GetEmail();\n\nusing (Imap imap = new Imap())\n{\n    imap.ConnectSSL(&quot;imap.gmail.com&quot;);\n    imap.LoginOAUTH2(user, accessToken);\n\n    imap.SelectInbox();\n    List&lt;long&gt; uids = imap.Search(Flag.Unseen);\n\n    foreach (long uid in uids)\n    {\n        var eml = imap.GetMessageByUID(uid);\n        IMail email = new MailBuilder().CreateFromEml(eml);\n        Console.WriteLine(email.Subject);\n    }\n    imap.Close();\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET \n\nDim api As New GoogleApi(accessToken)\nDim user As String = api.GetEmail()\n\nUsing imap As New Imap()\n\timap.ConnectSSL(\"imap.gmail.com\")\n\timap.LoginOAUTH2(user, accessToken)\n\n\timap.SelectInbox()\n\tDim uids As List(Of Long) = imap.Search(Flag.Unseen)\n\n\tFor Each uid As Long In uids\n\t\tDim eml = imap.GetMessageByUID(uid)\n\t\tDim email As IMail = New MailBuilder().CreateFromEml(eml)\n\t\tConsole.WriteLine(email.Subject)\n\tNext\n\timap.Close()\nEnd Using\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Refreshing access token<\/h2>\n\n\n\n<p>An access token is usually <strong>short lived<\/strong> and valid for a maximum of <strong>one hour<\/strong>. The main reason behind this is security and prevention of replay attacks. This means that for long-lived applications you need to refresh the access token.<\/p>\n\n\n\n<p><strong>Your refresh token will be sent only once \u2013 don\u2019t loose it!<\/strong><\/p>\n\n\n\n<p>We recommend storing entire <em>TokenResponse<\/em> object received from <em>GoogleAuthorizationCodeFlow.ExchangeCodeForTokenAsync<\/em> method call. This object contains both: refresh token and access token, along with its expiration time.<\/p>\n\n\n\n<p>The process of refreshing access token is simple:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/ c#\n\nTokenResponse refreshed = await credential.RefreshTokenAsync(\n    \"\", \n    token.RefreshToken, \n    CancellationToken.None);\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: vb; title: ; notranslate\" title=\"\">\n' VB.NET \n\nDim refreshed As TokenResponse = Await credential.RefreshTokenAsync( _\n    \"\",  _\n    token.RefreshToken,  _\n    CancellationToken.None)\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>You can also read how to use: &nbsp; OAuth 2.0 with Gmail over IMAP for web applications (Google.Apis) OAuth 2.0 with Gmail over IMAP for installed applications (Google.Apis) OAuth 2.0 with Gmail over IMAP for service account (Google.Apis) OAuth 2.0 is an open protocol to allow secure API authorization in a simple and standard method [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[15,33,25,28,84,57,85],"class_list":["post-3359","post","type-post","status-publish","format-standard","hentry","category-mail-dll","tag-c","tag-email-component","tag-gmail","tag-imap","tag-oauth-2-0","tag-vb-net","tag-xoauth2"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/3359"}],"collection":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/comments?post=3359"}],"version-history":[{"count":85,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/3359\/revisions"}],"predecessor-version":[{"id":6173,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/posts\/3359\/revisions\/6173"}],"wp:attachment":[{"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/media?parent=3359"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/categories?post=3359"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.limilabs.com\/blog\/wp-json\/wp\/v2\/tags?post=3359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}