google drive apiの認証が上手くいかない。
公式ドキュメントを読みながらgoogle drive apiのアクセストークンを取得しようとしているのですが上手くいきません。
詳しい方、見て頂けないでしょうか?
ドキュメントにあるコードをスコープのみ変えて動作させています。
環境はmacのvagrant上にインストールさえれたubuntu14.04、Pythonバージョンは3.7
コードはエラーなく実行されURLが表示されブラウザでアクセスすると認証画面が表示されます。しかし、途中のリダイレクトのところでアクセス拒否となり止まってしまいます。
考えられる問題
vagrant側で受け付けているipが9000なのに対しリダイレクト先で返ってきたのを確認するとlocalhost:8080となるのでアクセスできないのではと考えています。
個人的に考えたこと、やったこと。
この8080を9000に変更することが可能でしょうか?
ダウンロードしたcredentials.jsonにhttp://localhostという項目があったのでここを変更すれば変更できると試したのですが、ダメでした。
googleからリダイレクト?で返ってくるURL
http://localhost:8080/?state=6lZYW90cMvHypAINsVJMoScxo7cThv&code=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&scope=https://www.googleapis.com/auth/drive.file
コード
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START drive_quickstart]
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.file']
def main():
"""Shows basic usage of the Drive v3 API.
Prints the names and ids of the first 10 files the user has access to.
"""
creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server()
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
service = build('drive', 'v3', credentials=creds)
# Call the Drive v3 API
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
for item in items:
print(u'{0} ({1})'.format(item['name'], item['id']))
if __name__ == '__main__':
main()
追記
認証はまだアプリに組み込まないのでテスト環境のつもりで、その他を選択しており認証リダイレクトの項目がないです。
token.pickleとは一体なんなのでしょうか?
追記2
pickleについて教えていただきありがとうございます。
ウェブアプリでリダイレクトURLを9000に変更しました。
今度は最初のコンソール画面に表示されるURLで400エラーがでるようになってしまいます。localhost:8080とマッチしないと出てきます。
追記3
credentials.json
{"web":{"client_id":"xxxxxxxxx","project_id":"xxxxxxxxx","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_xxxcert_url":"https://www.googleapis.com/oauth2/v1/certs","redirect_uris":["http://localhost:9000"]}}
追記4
vagrant ファイルに8080のIPを追加しドキュメント通り実行したのですが、8080のアクセス拒否が起こりました。本来コードを実行したあとにその後に表示される数値を入力してねと促す文章がプロンプトに表示されinput()
状態になるのですが、私の場合なにも文章は表示されずサーバが応答を待っているような状態になりす。ctr + c
で終了させるとflow.run_local_server()
でプログラムがループをおこしているようでした。認証のコールバックページでエラーが起こります。
サーバlocalhost:8080を立ててmacにインストールしたブラウザからアクセスできたのでファイアウォールではないと考えます。
追記5
400エラーは認証画面のリダイレクト追加でhttp://localhost:9000/で上手くいきました。スラッシュが必要みたいです。