1

I've been trying to create a simple function using the Office JavaScript API to log into my company's on-prem server hosted at my local machine and fetch a response back. I have used Vue JS as my front-end framework with axios for HTTP/S requests.

Here's the code for the axios call:

import Vue from "vue";
import Vuex from "vuex";

const axios = require('axios').default;

axios.defaults.crossDomain = true;
Vue.use(Vuex);

/**
 * Network interactions and state manager
 */
const Network = new Vuex.Store({
    state: {
        url: 'http://127.0.0.1', //localhost by default
        user: '',
        pass: ''
    },
    getters: {

    },
    mutations: {
        setLoginCreds(state, payload) {
            state.url = payload.url;
            state.user = payload.user;
            state.pass = payload.pass;
        },
    },
    actions: {
        async login(context, { url, user, pass }) {
            let route = '/core/loginguest';

            let path = url + route;

            await axios({
                url: path,
                method: 'POST',
                params: {
                    userid: user,
                    password: pass
                }
            }).then(response => {
                console.log(response)
                if (response.status == 200) {
                    context.commit('setLoginCreds', { url, user, pass })
                }
            }).catch(err => {
                console.log('Exception hit!')
                console.log(err)
            })
        },
    }
});

export default Network;

While running this on Word, I get the following error at login(as viewed using Microsoft Edge dev Tools):

SEC7120: [CORS] The origin 'https://localhost:3000' did not find 'https://localhost:3000' in the Access-Control-Allow-Origin response header for cross-origin resource at 'http://127.0.0.1/core/loginguest?userid=hari&password=hari1234'.

As per my understanding, the CORS issue arises from Access-Control-Allow-Origin: * not being present in the response header of the server, but I did not experience this when using the same calls on Electron.js.

Is it just another CORS issue which puts me at the mercy of the server or is it something that I can control from client-end?

Hari Mohan
  • 53
  • 8
  • What happens if you use `http://localhost` instead of `http://127.0.0.1` for your URL? What happens if you add the axios option `withCredentials: true`? Does your server use the cors npm package? – O. Jones Oct 15 '20 at 10:53
  • As far as I know the server doesn't use the `cors npm` package. According to Office JS policies, the app hosting the Office add-in needs to be secure with HTTPS, so can't really play with that. I tried `withCredentials`, but didn't work. – Hari Mohan Oct 15 '20 at 12:32
  • Where do you have this add-in hosted? in other words, what's the URL in your manifest for your office add-in? – Mavi Domates Oct 15 '20 at 17:10
  • The URL in manifest is `https://localhost:3000` – Hari Mohan Oct 15 '20 at 18:51
  • @HariMohan and what's the url of your onprem server? – Mavi Domates Oct 15 '20 at 20:06
  • The URL of the on-prem server is http://localhost:80 – Hari Mohan Oct 16 '20 at 10:48

2 Answers2

1

So to clarify, the OP is asking why an add-in hosted at localhost:3000 can't call an on premise server at localhost:80 - hitting a CORS issue.

This is expected. Here are a few resources to check out:

An origin is defined by the scheme, host, and port of a URL.

A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.

In your case the port is different therefore you have to enable CORS on your server. By default it would be disallowed, so whatever your configuration is, you'll have to update it.

The reason why you don't have this problem when you're calling the same endpoint from Postman is because Postman isn't a browser, therefore isn't bound by CORS rules. CORS would apply when you're calling from one resource to another through browsers. You won't run into this issue with requests originating from non-browser sources.

Here are a few more key answers for you:

Mavi Domates
  • 4,262
  • 2
  • 26
  • 45
0

There is a small hack you can implement, I don't know if it's possible in your case.

You can set up NGINX over both Exchange and your add-in.

You can map a route like /your/api/route on NGINX to your application and all rest of the calls can be transferred to exchange to handle.

server{
    server_name yourdomain.tld;

    # Requests to be managed by your add-in
    location /api {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # Requests to be managed by exchange
    location / {
        proxy_pass http://localhost:4000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    listen 80;
}

By doing this both the exchange and your add-in will be working on the same port (whatever you configure) and cors will not be a problem then.

architjn
  • 1,397
  • 2
  • 13
  • 30