Search code examples
asp.netgoogle-apigoogle-drive-apigoogle-oauthgoogle-api-dotnet-client

How can I hardcode the authentication and authorization part of google drive api?


Currently I have codes which the user authorize before they can access the files inside their own Google Drives account using OAuth2 however now I want to hardcode the authentication part and authorization part into the source code for the aspx.cs page.

Is it possible? The language I currently am using right now is in ASPx together with C#. I used this using ASPSnippets.GoogleAPI; for the codes below.

Here are the codes for my 0Auth2 using client secret and client id

protected void Page_Load(object sender, EventArgs e)
{
    GoogleConnect.ClientId = "client_id";
    GoogleConnect.ClientSecret = "client_secret";
    GoogleConnect.RedirectUri = Request.Url.AbsoluteUri.Split('?')[0];
    GoogleConnect.API = EnumAPI.Drive;
    if (!string.IsNullOrEmpty(Request.QueryString["code"]))
    {
        string code = Request.QueryString["code"];
        string json = GoogleConnect.Fetch("me", code);
        GoogleDriveFiles files = new JavaScriptSerializer().Deserialize<GoogleDriveFiles>(json);

        //Remove the deleted files.
        dlFiles.DataSource = files.Items.Where(i => i.Labels.Trashed == false);
        dlFiles.DataBind();
    }
    else if (Request.QueryString["error"] == "access_denied")
    {
        ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "alert('Access denied.')", true);
    }
    else
    {
        GoogleConnect.Authorize("https://www.googleapis.com/auth/drive.readonly");
    }
}

Solution

  • I am not sure which code it is you would like to hard code.

    1. Access token (only good for an hour not worth hard coding)
    2. Refresh token (long lived can be hard coded but not a good idea see below)
    3. Client id (yes you can hard code this.)
    4. Client secret (yes you can hard code this)

    The way this works is that you request access from a user and you get a refresh token back you should store these refresh tokens. If the user wants to login again or if you need to access their data again you use the refresh token to request a new access token and they you have access to the users data.

    Assuming that you have a list of these refresh tokens you could hard code them in your application for use later. However this is a bad idea. Refresh tokens can expire.

    1. The user can remove your access
    2. Refresh tokens not used for six months will be automatically expired
    3. If the user has requested more then 50 refresh tokens the older ones will stop working
    4. Random Google bugs

    Due to this it is a good idea for your application to have the ability to request access from the user again if needed.

    This is code for authenticating using the google .net client library it stores the user credentials. If the user doesn't have a valid refresh token then it will prompt the user for access again.

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

    With these credentials stored you will not need to prompt a user for access again.

    Note: A service account should IMO only be used if you as a developer would like to share information on a google drive account that you control. Service accounts should not be used to access private user data. Thats what Oauth2 is for.

    Note 2: You may hard code your client id and secret although you may consider putting it in a config file. Or just using the client secrete json like the above example does.

    Code ripped from my sample project

    Service account VS Oauth2

    If the files are on a users Google Drive account then you need access. You are going to have to ask them for access there is no way around that and it has nothing to do with the client library this is how Oauth works. If you are trying to access private data owned by a user you need their permission.

    If you are trying to access a Google Drive account that you personally control and want to grant said users access to a file on that account then you should be using a service account. You can grant a service account permission to access your google drive account by taking the service account email address and sharing a directory with it. The service account will then have access to that directory. Another one of my tutorials here Google Drive with service accounts

    You might find my tutorial series useful Google Development for beginners this part is on service accounts Google Developer service accounts