djangogoogle-oauthgoogle-calendar-apipython-social-auth

Not correct scope for accessing events


HttpError at /calendar <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/primary/events?singleEvents=true&orderBy=startTime&alt=json returned "Request had insufficient authentication scopes.". Details: "[{'message': 'Insufficient Permission', 'domain': 'global', 'reason': 'insufficientPermissions'}]"> Request Method: GET Request URL: http://localhost:8000/calendar Django Version: 3.2.9 Exception Type: HttpError Exception Value:

Then does this after a while

RefreshError at /calendar The credentials do not contain the necessary fields need to refresh the access token. You must specify refresh_token, token_uri, client_id, and client_secret.

It seems I don't possess the right scope when accessing the calendar and it seems currently the access_token does appear.

from google.oauth2.credentials import Credentials
def get_user_events(request):
    credentials = Credentials(get_access_token(request), scopes=SCOPES)
    service = googleapiclient.discovery.build('calendar', 'v3', credentials=credentials)
    google_calendar_events = service.events().list(calendarId='primary', singleEvents=True,
                                          orderBy='startTime').execute()
    google_calendar_events = google_calendar_events.get('items', [])
    return google_calendar_events

def get_access_token(request): 
    social = request.user.social_auth.get(provider='google-oauth2') 
    return social.extra_data['access_token']

So the Scope I am using is the following

SCOPES = ['https://www.googleapis.com/auth/calendar']

Solution

  • "Request had insufficient authentication scopes.".

    If we check the documentation for events.get we will find that this method operates on private user data which means that we need to be authorized to access it. On top of that we need to be authorized with one of the following scopes

    enter image description here

    I cant see from your code which scopes you are requesting. The first thing to do is to ensure that you are requesting one of the scopes above when authorizing your user. If you change the scopes remember you must request consent of the user again for it to take effect.

    You must specify refresh_token, token_uri, client_id, and client_secret.

    Sounds like you are not properly storing your refresh token. get_access_token wont work if it doesn't have a refresh token stored.

    In the official sample notice how they store the user creds in token.json then the library will automatically request a new access token when it needs.

     """Shows basic usage of the Google Calendar API.
        Prints the start and name of the next 10 events on the user's calendar.
        """
        creds = None
        # The file token.json 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.json'):
            creds = Credentials.from_authorized_user_file('token.json', SCOPES)
        # 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(port=0)
            # Save the credentials for the next run
            with open('token.json', 'w') as token:
                token.write(creds.to_json())