Created
April 17, 2019 06:51
-
-
Save vanessaaleung/c4e5143837e1791d8e1abfb031472b14 to your computer and use it in GitHub Desktop.
Implement OAuth 2.0 authorization to access Google Drive API in C programming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <curl/curl.h> | |
struct MemoryStruct { | |
char *memory; | |
size_t size; | |
}; | |
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) | |
{ | |
size_t realsize = size * nmemb; | |
struct MemoryStruct *mem = (struct MemoryStruct *)userp; | |
char *ptr = realloc(mem->memory, mem->size + realsize + 1); | |
if(ptr == NULL) { | |
/* out of memory! */ | |
printf("not enough memory (realloc returned NULL)\n"); | |
return 0; | |
} | |
mem->memory = ptr; | |
memcpy(&(mem->memory[mem->size]), contents, realsize); | |
mem->size += realsize; | |
mem->memory[mem->size] = 0; | |
return realsize; | |
} | |
int main(void) | |
{ | |
CURL *curl_handle, *curl_handle2, *curl_handle3, *curl_handle4; | |
CURLcode res, res2, res3, res4; | |
struct MemoryStruct chunk, chunk2, chunk3, chunk4; | |
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ | |
chunk.size = 0; /* no data at this point */ | |
char user_code[21]; | |
char device_code[200]; | |
char access_token[200]; | |
curl_global_init(CURL_GLOBAL_ALL); | |
/* init the curl session */ | |
curl_handle = curl_easy_init(); | |
/* specify URL to get */ | |
curl_easy_setopt(curl_handle, CURLOPT_URL, "https://accounts.google.com/o/oauth2/device/code"); | |
/* Now specify the POST data */ | |
/* Step 1: Request device and user codes */ | |
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, "client_id=603382496792-5ac366vug85fs77v13lh1550cjem0fs5.apps.googleusercontent.com&scope=https://www.googleapis.com/auth/drive.file"); | |
/* send all data to this function */ | |
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); | |
/* we pass our 'chunk' struct to the callback function */ | |
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); | |
/* some servers don't like requests that are made without a user-agent | |
field, so we provide one */ | |
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); | |
/* get it! */ | |
res = curl_easy_perform(curl_handle); | |
/* Step 2: Handle the authorization server response */ | |
/* check for errors */ | |
if(res != CURLE_OK) { | |
fprintf(stderr, "curl_easy_perform() failed: %s\n", | |
curl_easy_strerror(res)); | |
} | |
else { | |
char *expire_result = strstr(chunk.memory, "\"expires_in"); | |
int expire_position = (int)(expire_result - chunk.memory); | |
char *user_result = strstr(chunk.memory, "\"user_code"); | |
int user_position = (int)(user_result - chunk.memory); | |
int uc_length = expire_position - user_position - 19; | |
memcpy(user_code, &chunk.memory[user_position] + 14, uc_length); | |
user_code[uc_length] = '\0'; | |
char *device_result = strstr(chunk.memory, "device_code"); | |
int device_position = (int)(device_result - chunk.memory); | |
int dc_length = user_position - device_position - 20; | |
memcpy(device_code, &chunk.memory[device_position] + 15, dc_length); | |
device_code[dc_length] = '\0'; | |
} | |
curl_easy_cleanup(curl_handle); | |
free(chunk.memory); | |
/* Step 3: Display the user code */ | |
printf("Enter below code on 'https://www.google.com/device' :\n"); | |
printf("%s\n", user_code); | |
printf("Press enter when finish\n"); | |
while( getchar() != '\n' ); | |
/* init the curl session */ | |
curl_handle2 = curl_easy_init(); | |
/* specify URL to get */ | |
curl_easy_setopt(curl_handle2, CURLOPT_URL, "https://www.googleapis.com/oauth2/v4/token"); | |
char url[300]; | |
strcat(url, "client_id=603382496792-5ac366vug85fs77v13lh1550cjem0fs5.apps.googleusercontent.com&client_secret=6kVOv06vdWFKYwMixUFioF5d&code="); | |
strcat(url, device_code); | |
strcat(url, "&grant_type=http://oauth.net/grant_type/device/1.0"); | |
curl_easy_setopt(curl_handle2, CURLOPT_POSTFIELDS, url); | |
curl_easy_setopt(curl_handle2, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); | |
curl_easy_setopt(curl_handle2, CURLOPT_WRITEDATA, (void *)&chunk2); | |
curl_easy_setopt(curl_handle2, CURLOPT_USERAGENT, "libcurl-agent/1.0"); | |
res2 = curl_easy_perform(curl_handle2); | |
if(res2 != CURLE_OK) { | |
fprintf(stderr, "curl_easy_perform() failed: %s\n", | |
curl_easy_strerror(res2)); | |
} | |
else { | |
//printf("%s\n", chunk2.memory); | |
char *ei2_result = strstr(chunk2.memory, "\"expires_in"); | |
int ei2_position = (int)(ei2_result - chunk2.memory); | |
char *at_result = strstr(chunk2.memory, "\"access_token"); | |
int at_position = (int)(at_result - chunk2.memory); | |
int at_length = ei2_position - at_position - 22; | |
memcpy(access_token, &chunk2.memory[at_position] + 17, at_length); | |
access_token[at_length] = '\0'; | |
/* init the curl session */ | |
curl_handle3 = curl_easy_init(); | |
char token[200]; | |
strcat(token, "https://www.googleapis.com/drive/v2/files?access_token="); | |
strcat(token, access_token); | |
curl_easy_setopt(curl_handle3, CURLOPT_URL, token); | |
curl_easy_setopt(curl_handle3, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); | |
curl_easy_setopt(curl_handle3, CURLOPT_WRITEDATA, (void *)&chunk3); | |
curl_easy_setopt(curl_handle3, CURLOPT_USERAGENT, "libcurl-agent/1.0"); | |
res3 = curl_easy_perform(curl_handle3); | |
if(res3 != CURLE_OK){ | |
fprintf(stderr, "curl_easy_perform() failed: %s\n", | |
curl_easy_strerror(res3)); | |
} | |
else{ | |
printf("%s\n", "Authorization sucessed"); | |
} | |
curl_easy_cleanup(curl_handle3); | |
free(chunk3.memory); | |
} | |
/* cleanup curl stuff */ | |
curl_easy_cleanup(curl_handle2); | |
free(chunk2.memory); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment