title: Token errors using msgraph-sdk-javascript with office-js-helpers authenticator
body: <p>I have an Outlook add-ins using React + TypeScript, debugging locally with Node.js.  I'm using the office-js-helpers library to authenticate and the msgraph-sdk-javascript Graph client library.  As a POC I'm simply trying to verify that I can successfully call Graph, by retrieving details of the current email by its id.  I can successfully use the office-js-helpers Authenticator to authorize the app, and successfully retrieve a token.</p>
  
  <p>However, when I use the Graph client to make a call to <code>v1/me/messages/{ID}</code>, I get:</p>
  
  <blockquote>
    <p>"401 InvalidAuthenticationToken: Access token validation failure"</p>
  </blockquote>
  
  <p>I'm not sure whether this is a problem with the way I'm using the Authenticator, or a problem with my add-in or app's manifests.  My add-in is using these for <code>AppDomains</code>: </p>
  
  <pre><code>&lt;AppDomains&gt;
    &lt;AppDomain&gt;https://localhost:3000&lt;/AppDomain&gt;
    &lt;AppDomain&gt;https://login.microsoftonline.com&lt;/AppDomain&gt;
  &lt;/AppDomains&gt;
  </code></pre>
  
  <p>I am using <code>https://localhost:3000</code> as my app's redirect URI, with implicit auth enabled.</p>
  
  <p>If I use the force option with the authenticate method, I also get this error: </p>
  
  <blockquote>
    <p>Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('<a href="https://login.microsoftonline.com" rel="nofollow noreferrer">https://login.microsoftonline.com</a>') does not match the recipient window's origin ('<a href="https://localhost:3000" rel="nofollow noreferrer">https://localhost:3000</a>'). </p>
  </blockquote>
  
  <p>However, I am able to retrieve a token.</p>
  
  <p>What am I doing wrong?  I'm not certain about the flow for the Authenticator, in terms of when to use <code>authenticator.tokens.get</code> and <code>authenticator.authenticate</code>.  For the first run I assume always authenticate and no need to use <code>tokens.get</code>, and for second run I assume just use <code>tokens.ge</code>t, but if I try either of those or always both it doesn't seem to change the result of an invalid token.</p>
  
  <pre><code>import * as React from "react";
  import { Button, ButtonType, TextField } from "office-ui-fabric-react";
  import { Authenticator, Utilities, DefaultEndpoints } from "@microsoft/office-js-helpers";
  import * as Graph from "@microsoft/microsoft-graph-client";
  
  export default class GetItemOJSHelpers extends React.Component&lt;any, any&gt; {
    constructor(props) {
      super(props);
      this.getEmail = this.getEmail.bind(this);
      this.callGraph = this.callGraph.bind(this);
      this.getItemRestId = this.getItemRestId.bind(this);
  
      this.state = { graphResponse: "", accessToken: "" };
      console.log("====GetItemOJSHelpers loaded");
    }
  
    getEmail() {
      console.log("====getEmail(): Entered ");
  
      //debugger;
      // Get the access token and create a Microsoft Graph client
      let authenticator = new Authenticator();
  
      // register Microsoft (Azure AD 2.0 Converged auth) endpoint
      authenticator.endpoints.registerMicrosoftAuth("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", {
        redirectUrl: "https://localhost:3000/index.html",
        scope: "Mail.ReadWrite User.Read User.ReadBasic.All"
      });
  
      console.log("====getEmail(): Getting token");
  
      let authObject = authenticator.tokens.get("Microsoft");
      let accessToken = authObject.access_token;
  
      if (accessToken !== null) {
        console.log(`====getEmail(): Current cached token: ${accessToken}`);
        this.callGraph(accessToken);
        return;
      } else {
        // for the default Microsoft endpoint
        //If the user, rejects the grant to the application then you will receive an error in the catch function.
        authenticator
          .authenticate(DefaultEndpoints.Microsoft)
          .then(function(token) {
            /* Microsoft Token */
            console.log(`====getEmail(): Authenticated; auth token: ${token.access_token}`);
            accessToken = token.access_token;
          })
          .catch(function(error) {
            //debugger;
            console.log("====getEmail(): authenticate error");
            Utilities.log(error);
            throw new Error("Failed to login using your Office 365 Account");
          });
      }
  
      console.log(`====getEmail(): Current token: ${accessToken}`);
      this.callGraph(accessToken);
    }
  
    callGraph(token) {
      // Get the item's REST ID
      let itemId = this.getItemRestId();
      console.log(`====callGraph(): itemId ${itemId}`);
  
      const client = Graph.Client.init({
        authProvider: done =&gt; {
          done(null, token); //first parameter takes an error if you can't get an access token
        },
        debugLogging: true
      });
  
      client
        .api("me/messages/" + itemId)
        .version("v1.0")
        .get()
        .then(function(item) {
          //debugger;
          console.log("Email " + item.Subject + " retrieved!!!");
        })
        .then(function() {
          console.log("====callGraph(): complete");
          //debugger;
        })
        .catch(err =&gt; {
          //debugger;
          //403 Forbidden! code: "ErrorAccessDenied", message: "Access is denied. Check credentials and try again."
          //Also 401 InvalidAuthenticationToken: Access token validation failure.
          console.log(`====callGraph(): error! ${err.statusCode}:'${err.code}': ${err.message}`);
        });
    }
  
    getItemRestId() {
      if (Office.context.mailbox.diagnostics.hostName === "OutlookIOS") {
        // itemId is already REST-formatted
        return Office.context.mailbox.item.itemId;
      } else {
        // Convert to an item ID for API v2.0
        return Office.context.mailbox.convertToRestId(
          Office.context.mailbox.item.itemId,
          Office.MailboxEnums.RestVersion.v2_0
        );
      }
    }
    render() {
      return (
        &lt;div&gt;
          &lt;Button
            id="getEmailButton"
            className="ms-welcome__action ms-bgColor-red"
            buttonType={ButtonType.primary}
            onClick={this.getEmail}
          &gt;
            Call Graph
          &lt;/Button&gt;
          &lt;div&gt;
            &lt;h3&gt; Access Token &lt;/h3&gt;
            &lt;TextField id="accessToken" /&gt;
          &lt;/div&gt;
          &lt;div&gt;
            &lt;h3&gt;Graph API Call Response&lt;/h3&gt;
            &lt;TextField id="graphResponse" /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      );
    }
  }
  </code></pre>