OAuth 2.0 with Gmail over IMAP for web applications
- 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 from desktop and web applications.
This article describes using OAuth 2.0 to access Gmail IMAP and SMTP servers using .NET IMAP component in web application scenario (ASP.NET/ASP.NET MVC). You can also use OAuth 2.0 for installed applications.
Google.Apis
Use Nuget to download “Google.Apis.Auth” package.
Import namespaces:
01 02 03 04 05 06 07 08 09 10 | // c# using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2.Flows; using Google.Apis.Auth.OAuth2.Requests; using Google.Apis.Auth.OAuth2.Responses; using Limilabs.Client.Authentication.Google; using Limilabs.Client.IMAP; |
01 02 03 04 05 06 07 08 09 10 | ' VB.NET Imports Google.Apis.Auth.OAuth2 Imports Google.Apis.Auth.OAuth2.Flows Imports Google.Apis.Auth.OAuth2.Requests Imports Google.Apis.Auth.OAuth2.Responses Imports Limilabs.Client.Authentication.Google Imports Limilabs.Client.IMAP |
Register Application
Before you can use OAuth 2.0, you must register your application using the Google Cloud Console. After you’ve registered, specify “Redirect URI” and copy the “Client ID” and “Client secret” values which you’ll need later.

At least product name must be specified:

Now create credentials:

Specify redirect URI:

After you’ve registered, copy the “Client ID” and “Client secret” values, which you’ll need later:

Now we can define clientID, clientSecret, redirect url 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’s email address and IMAP/SMTP access:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | // C# string clientID = "XXX.apps.googleusercontent.com" ; string clientSecret = "IxBs0g5sdaSDUz4Ea7Ix-Ua" ; string redirectUri = "https://www.example.com/oauth2callback" ; var clientSecrets = new ClientSecrets { ClientId = clientID, ClientSecret = clientSecret }; var credential = new GoogleAuthorizationCodeFlow( new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = clientSecrets, Scopes = new [] { GoogleScope.ImapAndSmtp.Name, GoogleScope.UserInfoEmailScope.Name} }); |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | ' VB.NET Dim clientID As String = "XXX.apps.googleusercontent.com" Dim clientSecret As String = "IxBs0g5sdaSDUz4Ea7Ix-Ua" Dim redirectUri As String = "https://www.example.com/oauth2callback" Dim clientSecrets = New ClientSecrets With { _ .ClientId = clientID, _ .ClientSecret = clientSecret _ } Dim credential = New GoogleAuthorizationCodeFlow( New GoogleAuthorizationCodeFlow.Initializer With { _ .ClientSecrets = clientSecrets, _ .Scopes = {GoogleScope.ImapAndSmtp.Name, GoogleScope.UserInfoEmailScope.Name} _ }) |
Obtain an OAuth 2.0 access token
Now we’ll create authorization url:
1 2 3 4 | // C# AuthorizationCodeRequestUrl url = credential .CreateAuthorizationCodeRequest(redirectUri); |
1 2 3 4 | ' VB.NET Dim url As AuthorizationCodeRequestUrl = credential _ .CreateAuthorizationCodeRequest(redirectUri) |
Now we need to redirect the client:
1 2 3 | // c# return new RedirectResult(url.Build().ToString()); |
1 2 3 | ' VB.NET Return New RedirectResult(url.Build().ToString()) |
At this point user is redirected to Google to authorize the access:

After this step user is redirected back to your website (https://www.example.com/oauth2callback), with code request parameter:
https://www.example.com/oauth2callback?code=4/5Y7M4cARD9hrt0nuKnQa0YgasdbwprRtIIjk4Fus#
1 2 3 4 5 6 7 8 9 | // C# public class OAauth2CallbackController : Controller { public ActionResult Index( string code) { ... } } |
1 2 3 4 5 6 7 8 | ' VB.NET Public Class OAauth2CallbackController Inherits Controller Public Function Index(code As String ) As ActionResult ... End Function End Class |
Following is this callback code. Its purpose is to get a refresh-token and an access-token:
01 02 03 04 05 06 07 08 09 10 11 | // c# string authCode = code; TokenResponse token = await credential.ExchangeCodeForTokenAsync( "" , authCode, redirectUri, CancellationToken.None); string accessToken = token.AccessToken; |
01 02 03 04 05 06 07 08 09 10 11 | ' VB.NET Dim authCode As String = code Dim token As TokenResponse = Await credential.ExchangeCodeForTokenAsync( _ "" , _ authCode, _ redirectUri, _ CancellationToken.None) Dim accessToken As String = token.AccessToken |
An access token is usually valid for a maximum of one hour, and allows you to access the user’s data. You also received a refresh token. A refresh token can be used to request a new access token once the previous expired.
Access IMAP/SMTP server
Finally we’ll ask Google for user’s email and use LoginOAUTH2 method to access Gmail’s IMAP server:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | // c# GoogleApi api = new GoogleApi(accessToken); string user = api.GetEmail(); using (Imap imap = new Imap()) { imap.ConnectSSL( "imap.gmail.com" ); imap.LoginOAUTH2(user, accessToken); imap.SelectInbox(); List< long > uids = imap.Search(Flag.Unseen); foreach ( long uid in uids) { var eml = imap.GetMessageByUID(uid); IMail email = new MailBuilder().CreateFromEml(eml); Console.WriteLine(email.Subject); } imap.Close(); } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | ' VB.NET Dim api As New GoogleApi(accessToken) Dim user As String = api.GetEmail() Using imap As New Imap() imap.ConnectSSL( "imap.gmail.com" ) imap.LoginOAUTH2(user, accessToken) imap.SelectInbox() Dim uids As List(Of Long ) = imap.Search(Flag.Unseen) For Each uid As Long In uids Dim eml = imap.GetMessageByUID(uid) Dim email As IMail = New MailBuilder().CreateFromEml(eml) Console.WriteLine(email.Subject) Next imap.Close() End Using |
Refreshing access token
An access token is usually short lived and valid for a maximum of one hour. 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.
Your refresh token will be sent only once – don’t loose it!
We recommend storing entire TokenResponse object received from GoogleAuthorizationCodeFlow.ExchangeCodeForTokenAsync method call. This object contains both: refresh token and access token, along with its expiration time.
The process of refreshing access token is simple:
1 2 3 4 5 6 | // c# TokenResponse refreshed = await credential.RefreshTokenAsync( "" , token.RefreshToken, CancellationToken.None); |
1 2 3 4 5 6 | ' VB.NET Dim refreshed As TokenResponse = Await credential.RefreshTokenAsync( _ "" , _ token.RefreshToken, _ CancellationToken.None) |