Google API:访问令牌未刷新

问题描述 投票:0回答:1

我正在尝试实现以下逻辑:

  1. 用户打开我的网站页面并单击按钮

  2. 弹出窗口显示要求同意将文件上传到他的Google驱动器

  3. 用户同意,我获取了auth_code,获取访问权限并刷新令牌

  4. 以后有必要时,我将一些文档上传到他的Google驱动器中,不再征求权限。

前三点终于奏效了。客户端上的代码(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
    }

我将这两个令牌保存在数据库中。稍后,当我要上传文档时:

    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”:“未经授权” \ n}')

我读过google api可以自行刷新访问令牌,但我不知道如何使它工作。

python reactjs google-api google-oauth google-oauth2
1个回答
0
投票
出于安全考虑,您正在使用的google API库不允许您从客户端代码刷新访问令牌。如果get_tokens中的令牌已过期,则必须从服务器端python代码中刷新令牌。

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') ) http = cred.authorize(httplib2.Http()) credentials.refresh(http) 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

© www.soinside.com 2019 - 2024. All rights reserved.