Я пытаюсь реализовать следующую логику c:
Пользователь открывает страницу моего сайта и нажимает кнопку
всплывающее окно показывает запрос согласия на загрузку файлов на его диск Google
Пользователи соглашаются, я беру auth_code, получаю доступ и повторно получаю sh токены
Когда обязательно позже, я загружаю некоторые документы на его диск Google, не спрашивая разрешения.
Первые 3 пункта, наконец, работают. Код на стороне клиента (ReactJS):
componentWillMount() {
let script = document.createElement('script');
script.setAttribute('id', 'google_script');
const self = this;
script.onload = function() {
gapi.load('auth2', ()=>{
const clientId = window.googleClientId;
const scope = 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file';
let config = {
clientId: clientId,
scope: scope
};
self.googleAuth = gapi.auth2.init(config);
});
};
script.src = "https://apis.google.com/js/platform.js";
document.getElementsByTagName('head')[0].appendChild(script);
};
// Затем
buttonClick(){
this.googleAuth.grantOfflineAccess().then((data)=>{ //<== Offline access
if (data.code){
this.saveGoogleDriveToken(data.code); //<-- Sends to the server
} else {
}
});
}
Серверная часть, обменивающая код на токены.
def get_tokens(auth_code):
json_path = os.path.join(static_folder_path, "client_secrets.json")
credentials = None
try:
credentials = client.credentials_from_clientsecrets_and_code(
json_path,
scopes,
auth_code)
except Exception as ex:
print(ex)
return None
return {
'access_token': credentials.access_token,
'refresh_token': credentials.refresh_token
}
Я сохраняю эти 2 токена в базе данных. Позже, когда я хочу загрузить документы:
credentials = google.oauth2.credentials.Credentials(user_access_token,
refresh_token = user_refresh_token,
token_uri = 'https://oauth2.googleapis.com/token',
client_id = get_config_var('GOOGLE_CLIENT_ID'),
client_secret = get_config_var('GOOGLE_CLIENT_SECRET')
)
drive_service = build('drive', 'v3', credentials=credentials)
fd = io.BytesIO(invoice_file_bytes)
body = {'name': invoice_file_name, 'mimeType': 'application/pdf'}
media_body = MediaIoBaseUpload(fd = fd, mimetype='application/pdf')
file = drive_service.files().create(body=body,
media_body=media_body,
fields='id').execute() #<== When hit here
Но я не могу заставить его работать. Это сработало вскоре после того, как пользователь дал согласие, но не через 1 час (я думаю, что после истечения срока действия токена доступа) у меня есть 'invalid_client: Unauthorized', '{\ n "error": "invalid_client", \ n "error_description": "Unauthorized" \ n} ')
Я читаю google api, могу самостоятельно обновить sh токен доступа, но не могу понять, как заставить его работать.