【问题标题】:401 (Unauthorized) error while using AutoDesk APIs使用 AutoDesk API 时出现 401(未经授权)错误
【发布时间】:2020-12-17 02:39:06
【问题描述】:

我有一个 Django 应用程序,我正在使用其中的 .stl、.stp 和 .igs 文件。我必须在 HTML 模板中显示这些文件,并且我正在尝试为此使用 AutoDesk API。我首先创建了一个帐户并通过了身份验证,但在显示图像时遇到了问题。

这是包含身份验证和上传图片到存储桶的视图:

def viewer(request):
    req = { 'client_id' : CLIENT_ID, 'client_secret': CLIENT_SECRET, 'grant_type' : 'client_credentials','scope':'code:all bucket:create bucket:read data:read data:write'}
    resp = requests.post(BASE_URL+'/authentication/v1/authenticate', req)
    if resp.status_code == 200:
        TOKEN = resp.json()['token_type'] + " " + resp.json()['access_token']
    else:
        print('Get Token Failed! status = {0} ; message = {1}'.format(resp.status_code,resp.text))
        TOKEN = ""
    filepath = "C:/Users/imgea/desktop/"
    filename = '55.stl'
    my_file = Path(filepath + filename)
        #check package file (*.zip) exists
    if my_file.is_file():
        filesize = os.path.getsize(filepath + filename)
        # encoding the file name
        if sys.version_info[0] < 3:
            encodedfilename= urllib.pathname2url(filename)
        else:
            encodedfilename= urllib.parse.quote(filename) 
        resp = requests.put(BASE_URL + '/oss/v2/buckets/'+'bucket'+'/objects/'+ encodedfilename, headers={'Authorization': TOKEN,'Content-Type' : 'application/octet-stream','Content-Length' : str(filesize)},data= open(filepath+filename, 'rb'))
        if resp.status_code == 200:
            urn = resp.json()['objectId']
        else:
            print('Upload File to Bucket of Data Management Failed! status ={0} ; message = {1}'.format(resp.status_code,resp.text ))
            urn = "none"
    else:
        print(' ' + filename + ' does not exist')
        urn = "none"
    urn_bytes = urn.encode('ascii')
    base64_bytes = base64.b64encode(urn_bytes)
    base64_urn = base64_bytes.decode('ascii')

    headers = {
    'Authorization': TOKEN,
    'Content-Type': 'application/json',
    }
    data = '{"input": { "urn": "' + base64_urn + '"},"output": {"destination": {"region": "us" }, "formats": [{ "type": "obj" }]}}'
    resp = requests.post(BASE_URL + '/modelderivative/v2/designdata/job', headers=headers, data=data)
    context = {
        'token': "'"+TOKEN+"'",
        'urn': "'"+urn+"'",
    }
    return render(request, 'viewer.html', context)

这是模板:

<body>
    <!-- The Viewer will be instantiated here -->
    <div id="MyViewerDiv"></div>
    <!-- The Viewer JS -->
    <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/viewer3D.min.js"></script>
    <!-- Developer JS -->
    <script>
        var viewer;
        var options = {
            env: 'AutodeskProduction',
            getAccessToken: function(onGetAccessToken) {
                var accessToken = {{token|safe}};
                var expireTimeSeconds = 86400;
                onGetAccessToken(accessToken, expireTimeSeconds);
            },
            api: 'derivativeV2'    // for models uploaded to EMEA change this option to 'derivativeV2_EU'
        };
        var documentId = {{urn|safe}};
        Autodesk.Viewing.Initializer(options, function onInitialized(){
            Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
        });
        function onDocumentLoadSuccess(doc) {
            // A document contains references to 3D and 2D geometries.
            var geometries = doc.getRoot().search({'type':'geometry'});
            if (geometries.length === 0) {
                console.error('Document contains no geometries.');
                return;
            }
            // Choose any of the avialable geometries
            var initGeom = geometries[0];
            // Create Viewer instance
            var viewerDiv = document.getElementById('MyViewerDiv');
            var config = {
                extensions: initGeom.extensions() || []
            };
            viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv, config);
            // Load the chosen geometry
            var svfUrl = doc.getViewablePath(initGeom);
            var modelOptions = {
                sharedPropertyDbPath: doc.getPropertyDbPath()
            };
            viewer.start(svfUrl, modelOptions, onLoadModelSuccess, onLoadModelError);
        }
        function onDocumentLoadFailure(viewerErrorCode) {
            console.error('onDocumentLoadFailure() - errorCode:' + viewerErrorCode);
        }
        function onLoadModelSuccess(model) {
            console.log('onLoadModelSuccess()!');
            console.log('Validate model loaded: ' + (viewer.model === model));
            console.log(model);
        }
        function onLoadModelError(viewerErrorCode) {
            console.error('onLoadModelError() - errorCode:' + viewerErrorCode);
        }
    </script>
</body>

根据这些代码块,我就可以成功获取到access token和image urn了。同时,它们被正确发送到模板。但我得到了一个错误 { "developerMessage":"Token is not provided in the request.", "moreInfo": "https://forge.autodesk.com/en/docs/oauth/v2/developers_guide/error_handling/", "errorCode": "AUTH-010"}。如何解决此问题并以 HTML 格式显示 3D 文件?

【问题讨论】:

  • 我也有同样的问题。自上周以来,我还没有解决它。同样的错误,但不是 3D 查看器希望以某种方式解决。

标签: python django python-requests autodesk-forge autodesk-viewer


【解决方案1】:

请注意,将令牌添加到授权标头时,您必须在令牌前加上“Bearer”,因此标头应为"Authorization": "Bearer &lt;token&gt;",而不是"Authorization": "&lt;token&gt;"

【讨论】:

  • 具体在哪里?在您的代码中,我看到TOKEN = resp.json()['access_token'] 行,它只是没有“Bearer”前缀的令牌,然后将您的文件上传到 Forge 的行显示resp = requests.put(BASE_URL + '/oss/v2/buckets/'+'bucket'+'/objects/'+ encodedfilename, headers={'Authorization': TOKEN,'Content-Type' : 'application/octet-stream','Content-Length' : str(filesize)},data= open(filepath+filename, 'rb'))。同样,那里没有添加“Bearer”前缀。
  • 我忘记在我的问题中添加它。我现在编辑了问题。
  • 您是否仍然收到相同的“请求中未提供令牌”。错误?我还注意到您正在将文件上传到名为“bucket”的 Forge 存储桶。您确定您是此存储分区的所有者/创建者吗?
  • 是的,我仍然遇到同样的错误。是的,我自己创建了那个桶。
  • 并且示例代码实际上还有其他问题,例如,将文件上传到Forge后,您没有使用模型衍生服务翻译文件。并且 URN 不等于 objectId。 URN 必须是 base64 编码的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
  • 2014-11-03
  • 1970-01-01
  • 2020-11-15
  • 2022-01-03
  • 1970-01-01
  • 2019-05-06
相关资源
最近更新 更多