Обработка webhook с помощью API microsoftgraph и Django - PullRequest
0 голосов
/ 11 июня 2018

В настоящее время я разрабатываю простое веб-приложение, которое подключается к учетной записи Outlook 365 через Microsoft Graph API .В этом приложении я хотел бы настроить веб-крючок, который обрабатывает электронные письма после их получения в папке входящих.Однако для этого мне нужно получить токен для обработки электронного письма.

Вот мой текущий код Django:

@csrf_exempt
def webhook(request):
    validation_token = str(request)
    validation_token = validation_token.replace(
        "<WSGIRequest: POST '/app/webhook/?validationToken=", "")
    validation_token = validation_token.replace(
        "HTTP/1.1", "").replace("'>", "")

    if len(request.body) == 0:
        request.session['validation_token'] = validation_token
        return HttpResponse(validation_token, content_type="text/plain")
    else:
        data = json.loads(request.body)
        print('received notification(s) !')
        notifications = data['value']
        request.session['notifications'] = notifications
        return HttpResponseRedirect(reverse('app:categorize'), status=202)

Представление категоризации (в views.py),который я перенаправляю, должен обрабатывать входящее уведомление (получение или обновление сообщения).Причина, по которой я не обрабатываю его в представлении webhook, заключается в том, что мне нужно обновить токен, который уже должен храниться в объекте сеанса.Однако, возможно, возможно, поскольку request является входящим запросом POST, токен не сохраняется в сеансе.

def categorize(request):
    access_token, refresh_token, expiration = get_access_token(
        request, request.build_absolute_uri(reverse('app:gettoken')))
    notifications = request.session.get('notifications')
    if notifications is not None:
        account = OutlookAccount(
            access_token=access_token,
            refresh_token=refresh_token,
            token_expiration=expiration
            )
        for resource in notifications:
            resource_data = resource['resourceData']
            client_state = resource['clientState']
            if client_state == 'CLIENT_STATE':
                do_something(resource_data)           
    return HttpResponseRedirect(reverse('app:mail'))  

Функция python, используемая для получения запроса (импортированного из другого модуля), является

def get_access_token(request, redirect_uri):
    try:
        current_token = request.session['access_token']
        expiration = request.session['token_expires']
        refresh_token = request.session['refresh_token']
        now = int(time.time())
        if (current_token and now < expiration):
            # Token still valid
            return current_token, refresh_token, expiration
        else:
            # Token expired
            refresh_token = request.session['refresh_token']
            new_tokens = get_token_from_refresh_token(refresh_token, redirect_uri)

            # Update session
            # expires_in is in seconds
            # Get current timestamp (seconds since Unix Epoch) and
            # add expires_in to get expiration time
            # Subtract 5 minutes to allow for clock differences
            expiration = int(time.time()) + new_tokens['expires_in'] - 300

            # Save the token in the session
            request.session['access_token'] = new_tokens['access_token']
            request.session['refresh_token'] = new_tokens['refresh_token']
            request.session['token_expires'] = expiration

            return new_tokens['access_token'], new_tokens['refresh_token'], expiration        
    except KeyError:
        return None, None, None

Представление gettoken дает конечную точку для извлечения токена.

def gettoken(request):
    auth_code = request.GET['code']
    redirect_uri = request.build_absolute_uri(reverse('app:gettoken'))
    token = get_token_from_code(auth_code, redirect_uri)
    access_token = token['access_token']

    refresh_token = token['refresh_token']
    expires_in = token['expires_in']
    expiration = int(time.time()) + expires_in - 300

    request.session['access_token'] = access_token     
    request.session['refresh_token'] = refresh_token
    request.session['token_expires'] = expiration

    return HttpResponseRedirect(reverse('app:mail'))

Я понимаю, что функция get_access_token отчасти избыточна с предыдущим представлением, но я не знаю, какиспользовать только представление gettoken для получения токена аутентификации.

Подводя итог, моя основная проблема - выяснить, как получить доступ к свойствам access_token, refresh_token, которые обычно сохраняются после входа в систему вручную.Однако они не доступны в представлении webhook (возможно, это справедливо).

Мне нужен способ временного перенаправления в представление gettoken, сохранения токенов в сеансе и завершения обработки.в представлении webhook.

Извините, если это не имеет смысла, я просто подбираю Django, и я вообще не веб-разработчик.

1 Ответ

0 голосов
/ 11 июня 2018

Вы не можете извлечь токен из сеанса, потому что веб-ловушка не приходит из сеанса браузера пользователя.Он идет от Microsoft Graph на удаленной машине.Таким образом, похоже, что другой клиент работает с вашим бэкэндом, а не с сообщением из сеанса данного пользователя.

Если вам нужно предпринять действия на основе уведомления о веб-крюке, вам нужно иметь refresh_token сохраненное вне сеанса и систему для подключения данного уведомления кправильный пользователь.Имея их, вы можете получить уведомление, получить новый токен и позвонить в Microsoft Graph от имени пользователя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...