一些非常奇怪的事情让我感到非常悲伤,这与Django会话有关 . 有时我的代码按预期工作,有时则不然 .

我的工作流程如下:

用户访问URL'/ connect /',它解析为以下函数'get_session_id' . 在这个函数中,我获得了一个“ebay会话ID”,这是ebay API发送给我的会话ID . 在我获得此“ebay会话ID”后,我将用户重定向到允许用户验证自己的易趣URL .

import json
import pytz
import requests

from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect
from django.shortcuts import redirect, render

from ebaysdk.trading import Connection as Trading
from ebaysdk.exception import ConnectionError

def get_session_id(request):
    api = Trading(
        appid="XXXXXXXXXXXXXX",
        devid="XXXXXXXXXXXXXX",
        certid="XXXXXXXXXXXXXX",
        config_file=None,
    )

    res = None
    max_retries = 5
    number_retries = 0
    while number_retries <= max_retries:
        try:
            res = api.execute(
                'GetSessionID',
                {"RuName": "XXXXXXXX"}
            )
        except requests.exceptions.ReadTimeout as exception:
            if number_retries > max_retries:
                raise exception
            number_retries += 1
        except ConnectionError as exception:
            raise Exception('ConnectionError:\n%s' %
                            json.dumps(exception.response.dict(), sort_keys=True, indent=5))
        else:
            break

    redirect_url = "https://signin.ebay.com/ws/eBayISAPI.dll?SignIn&runame=%s&SessID=%s" % \
                   ("XXXXXXXXXXXXXX", res.reply.SessionID)

    response = HttpResponseRedirect(redirect_to=redirect_url)

    print 'Fetched eBay SessionID: %s' % res.reply.SessionID
    print 'Django Session Key: %s' % request.session._get_session_key()

    request.session['ebay_session_id'] = res.reply.SessionID
    request.session.modified = True

    return response

如果用户成功验证,我会指示eBay将用户引导回我网站上的'fetchToken /'URL,该URL解析为以下函数'fetch_token' . 此时我需要获取我在上面的request.session / Django会话中存储的原始'ebay_session_id',但由于某种原因,Django会话密钥有时不匹配!有人可以解释为什么会这样吗???

def fetch_token(request):
    api = Trading(
        appid="XXXXXXXXXXXXXXXXX",
        devid="XXXXXXXXXXXXXXXXX",
        certid="XXXXXXXXXXXXXXXXX",
        config_file=None,
    )

    print 'Retrieved eBay SessionID for FetchToken: %s' % request.session['ebay_session_id']
    print 'Django Session Key: %s' % request.session._get_session_key()

    res = None
    max_retries = 5
    number_retries = 0
    while number_retries <= max_retries:
        try:
            res = api.execute(
                "FetchToken",
                {"SessionID": request.session['ebay_session_id']}
            )
        except requests.exceptions.ReadTimeout as exception:
            if number_retries > max_retries:
                raise exception
            number_retries += 1
        except ConnectionError as exception:
            raise Exception('ConnectionError:\n%s' %
                            json.dumps(exception.response.dict(), sort_keys=True, indent=5))
            #return HttpResponse(e.response.dict())
        else:
            break

    expiration_time_aware = res.reply.HardExpirationTime.replace(tzinfo=pytz.UTC)
    EbayTokens.objects.create_ebay_token(eias_token=res.reply.eBayAuthToken,
                                         expiration_time=expiration_time_aware,
                                         user=request.user)

我的设置文件具有以下行以启用会话,因此这不是问题 . 我正在使用Django 1.9 .

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

MIDDLEWARE_CLASSES = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

正如我所说,有时它有效,有时却没有 . 当我与用户登录,点击错误然后刷新时,我感觉它停止工作 . 当它不起作用时,请参见下面的示例 . 当我转到“/ connect /”时,我有以“mxcp ...”开头的Django会话密钥,但是当我指示eBay重定向回“/ fetchToken /”时,我得到的密钥以“ 4b2b” .

值得注意的是,在我的'django_session'表中,“4b2b ..”是倒数第二个条目,而“mxcp ...”是最后一个条目 .

[21/May/2017 19:17:03] "POST /signup HTTP/1.1" 302 0
Fetched eBay SessionID: skADAA**2c710a5615c0a5f02a54ffe4fffffa58
Django Session Key: mxcpfrtaz2psxf9bp8tb5m2qyknzmw6a
[21/May/2017 19:17:04] "GET /connect/ HTTP/1.1" 302 0
Retrieved eBay SessionID for FetchToken: skADAA**2c6c73ae15c0a7958d63e7e3fffffa42
Django Session Key: 4b2b2d7shui5qxa593wfnccy6c4fudz5

有人请帮忙,我将永远感激不尽 .