31 Jul 2017

Viewer 2.16 Cookie Authentication

Default blog image


Version 2.16 of the Forge Viewer will no longer rely on the browser cookie when authenticating with Forge API REST endpoints.

From version 2.16 and going forward, every browser request will include an Authentication header with the OAuth token.


Why is this change happening?

The browser cookie the Forge Viewer has been relying on is a Third Party Cookies. These can be problematic in that:

  1. They are susceptible to Cross Site Request Forgery (CSRF) Attacks.
  2. Some browsers on mobile devices, such as Safari for iPad, disable Third Party Cookies by default.


How will this change affect me?

A) Request Preflights

Application developers will start noticing that the browser will be sending a lot more preflight requests. This happens because the Viewer will now include an Authorization header to each Forge request. The header will include the OAuth token, required to access the Forge resource. 


B) HTML thumbnails

The usage of browser cookies provided a seamless mechanism to attach authorization to each request made to Forge API. This was specially useful when populating image data into an <img> tag.

Given the following HTML

<div id='MyViewerDiv' />
<img id='MyThumbnail' />

The following code shows how to display the thumbnail of the first available viewable into MyThumbnail:

// Only works up to Viewer version 2.15 (inclusive)
Autodesk.Viewing.Document.load(documentId, function(doc){
    var viewables = Autodesk.Viewing.Document.getSubItemsWithProperties(doc.getRootItem(), { 'type': 'geometry' }, true);
    var thumbImg = document.getElementById('MyThumbnail');
    thumbImg.src = doc.getThumbnailPath(viewables[0]);

A full example can be found here: https://jsfiddle.net/uLnvwyLa/


How can I prepare for this change?

1) Versioning

Make sure that your application is requesting a specific version of the Viewer code.

<!-- Fetch version 2.15 of the Viewer code -->
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/viewer3D.min.js?v=2.15"></script>

Version 2.15 will still rely of browser cookie for authentication.

Developers can configure the Viewer code to not use the browser cookie by initializing the global variable window.LMV_THIRD_PARTY_COOKIE to false.

// Forcing cookie to not be used.
// Needs to be set before Autodesk.Viewing.Initializer();
window.LMV_THIRD_PARTY_COOKIE = false;

var initOpts = Autodesk.Viewing.createInitializerOptions();
initOpts.accessToken = '<your_access_token>';
Autodesk.Viewing.Initializer(initOpts, function(){
    // Proceed to initialize Viewer...

The above code will avoid setting a browser cookie and instead will add the Authorization request header to each browser request hitting to Forge API.


Once you verify that your application is not relying on the browser cookie, you will be ready to move to the cookie-less version of the Viewer:

<!-- Fetch version 2.16 of the Viewer code -->
<script src="https://developer.api.autodesk.com/viewingservice/v1/viewers/viewer3D.min.js?v=2.16"></script>


2) Handling <img> tags (Thumbnails)

If you notice that your web application is relying on the browser cookie to populate <img> with Forge image content, additional steps will be required to get thumbnails to show up.

Raw JavaScript

Here's some code showcasing how it could be done for PNG images:

var xhr = new XMLHttpRequest();
xhr.open( "GET", "https://developer.api.autodesk.com/.../something.png", true );
xhr.setRequestHeader( "Authorization", "Bearer " + token );
// Ask for the result as an ArrayBuffer.
// Important note! This has to happen AFTER the xhr.open in order to work on IE. For more info please see: https://stackoverflow.com/a/34647690
xhr.responseType = "arraybuffer";
xhr.onload = function( e ) {
    // Obtain a blob: URL for the image data.
    var arrayBufferView = new Uint8Array( this.response );
    var blob = new Blob( [ arrayBufferView ], { type: "image/png" } );
    var imageUrl = window.URL.createObjectURL( blob );
    img.src = imageUrl;
    img.onload = function () { window.URL.revokeObjectURL(thumbElem.src); };



Developers building their web application on top of Angular may rely on angular-img-http-src. Integrate the module, then all you need to do is change code so that the image url is assigned to the http-src property instead of the src property. Behind the scenes the image will be loaded using the Angular http_service which you will already have configured to add the authorization header to any request.



Related Article