Home > front end >  Getting 401 error when using API Key to Retrieve Gmail inbox contents via list endpoint
Getting 401 error when using API Key to Retrieve Gmail inbox contents via list endpoint

Time:02-05

I am trying to add some API tests for our application that validate that a message is sent out and eventually received in Gmail. I went ahead and added an API key for my email in the Google Cloud Services developer console and created the following code.

The Client.cs class is just an example I found online that I tweaked and made work with our endpoints (maybe this type of strategy wont work with Gmail API?)

Enpoints.cs is just the class to return the URL. Im also including the key as an optional parameter

Test.cs just contains a segment of how I am calling the endpoint and getting the 401 Unauthorized error

Are we able to use the list endpoint to get the contents of a gmail inbox by using an API Key?

Client.cs

public enum Command {
    GET,
    POST,
    PUT,
    DELETE }

namespace Project{
    public class Client
    {

        public string endPoint { get; set; }
        public Command execute { get; set; }
        public string contentType { get; set; }
        public string postData { get; set; }
        public string encoded = "";

        // Basic Client
        public Client()
        {
            endPoint = "";
            execute = Command.GET;
            contentType = "application/JSON";
            postData = "";
            encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes("[email protected]"
  ":"   "mypass"));
        }

        // Basic Request
        public string Request(string parameters)
        {
            var request = (HttpWebRequest)WebRequest.Create(parameters);
            request.Headers.Add("Authorization", "Basic "   encoded);
            request.Method = execute.ToString();
            request.ContentLength = 0;
            request.ContentType = contentType;

            if (postData != "")
            {
                request.SendChunked = true;
                request.ContentType = "application/json";

                using (var streamWriter = new StreamWriter(request.GetRequestStream()))
                {
                    string json = postData;

                    streamWriter.Write(json);
                }
            }

            using (var response = (HttpWebResponse)request.GetResponse())
            {
                var responseValue = string.Empty;

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    var message = String.Format("Failed: Received HTTP {0}", response.StatusCode);
                    Console.WriteLine(message);
                    //throw new ApplicationException(message);
                }

                using (var responseStream = response.GetResponseStream())
                {
                    if (responseStream != null)
                        using (var reader = new StreamReader(responseStream))
                        {
                            responseValue = reader.ReadToEnd();
                        }
                }

                return responseValue;
            }
        }
    }


}

Endpoints.cs

namespace Project
{
    class Endpoints
    {

        // Class to store URLs for Gmail Integrations
        public static class Gmail
        {
            // Class to interface with Gmail Messages
            public static class Messages
            {
                // Retrieve Messsages (List)
                public static string List(string userId)
                {
                    return "https://gmail.googleapis.com/gmail/v1/users/"   userId   "/messages?key=mykey";
                }
            }
        }

    }
}

Test.cs

// Prepare the Client
Client client = new Client();

// Get the Response
client.execute = Command.GET;
var response = client.Request(Endpoints.Gmail.Messages.List("[email protected]"));

// Print Response
Console.WriteLine(response);

CodePudding user response:

No.

Because Gmail includes personal|user data, you will need to provide a facility for the specific user to permit access using OAuth2. There's a facility within Workspace for domain-wide delegation of a Service Account that permits the Service Account to operate on your users' behalf.

Google's APIs Explorer is very useful.

For Gmail API, you can interact with e.g. users.messages.list in the browser.

Google provides auto-generated API Client Libraries for every service in 8 languages. Here's Gmail API Client Library for .NET. I strongly encourage you to use Google SDKs to avoid dealing with the APIs' types, auth, logging etc. directly. As you've seen, this can be challenging, unnecessarily duplicates work (best left to Google) and increases the scope of your security audit.

If you look at the HTTP example from APIs Explorer. You will see that the HTTPS request must include an Authorization header with a value of Bearer [SOME-ACCESS-TOKEN]. The Access Token will be provided to you by Google's OAuth2 endpoint.

https://developers.google.com/gmail/api/reference/rest/v1/users.messages/list?apix_params={"userId":"me"}&apix=true

I was unable to find the link to a good overview of API keys and why you should avoid using them to authenticate. API keys are easily obtained and are a bearer credential (i.e. you don't want them to be easily obtained). Generally (!) an API key is used to associate requests with a specific Google project for billing purposes. They should not be used to authenticate users. See API keys

  •  Tags:  
  • Related