Skip to content

Commit f196c7d

Browse files
AlexJerabekCopilot
andauthored
[excel] (Custom Functions) Reorganize CF Auth article for better engagement (#5798)
* Refresh CF Auth article * Reorder sections * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 8f25226 commit f196c7d

1 file changed

Lines changed: 79 additions & 71 deletions

File tree

docs/excel/custom-functions-authentication.md

Lines changed: 79 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,48 @@
11
---
22
title: Authentication for custom functions without a shared runtime
3-
description: Authenticate users using custom functions that don't use a shared runtime.
4-
ms.date: 02/10/2024
3+
description: Learn how to authenticate users in Excel custom functions that run in a JavaScript-only runtime and share tokens with a task pane.
4+
ms.date: 06/17/2026
55
ms.topic: how-to
66
ms.localizationpriority: medium
77
---
88

99
# Authentication for custom functions without a shared runtime
1010

11-
In some scenarios, a custom function that doesn't use a [shared runtime](../testing/runtimes.md#shared-runtime) will need to authenticate the user in order to access protected resources. Custom functions that don't use a shared runtime run in a [JavaScript-only runtime](../testing/runtimes.md#javascript-only-runtime). Because of this, if the add-in has a task pane, you'll need to pass data back and forth between the JavaScript-only runtime and the HTML-supporting runtime used by the task pane. You do this by using the [OfficeRuntime.storage](/javascript/api/office-runtime/officeruntime.storage) object and a special Dialog API.
11+
If your Excel custom function doesn't use a [shared runtime](../testing/runtimes.md#shared-runtime), it runs in a [JavaScript-only runtime](../testing/runtimes.md#javascript-only-runtime). In that runtime, authentication usually requires a dialog flow and token sharing with your task pane.
1212

13-
[!include[Shared runtime note](../includes/shared-runtime-note.md)]
13+
Use [OfficeRuntime.displayWebDialog](/javascript/api/office-runtime#office-runtime-officeruntime-displaywebdialog-function(1)) to sign in and [OfficeRuntime.storage](/javascript/api/office-runtime/officeruntime.storage) to cache and share the token between runtimes.
1414

15-
## OfficeRuntime.storage object
16-
17-
The JavaScript-only runtime doesn't have a `localStorage` object available on the global window, where you typically store data. Instead, your code should share data between custom functions and task panes by using `OfficeRuntime.storage` to set and get data.
18-
19-
### Suggested usage
20-
21-
When you need to authenticate from a custom function add-in that doesn't use a shared runtime, your code should check `OfficeRuntime.storage` to see if the access token was already acquired. If not, use [OfficeRuntime.displayWebDialog](/javascript/api/office-runtime#office-runtime-officeruntime-displaywebdialog-function(1)) to authenticate the user, retrieve the access token, and then store the token in `OfficeRuntime.storage` for future use.
15+
[!INCLUDE [Shared runtime note](../includes/shared-runtime-note.md)]
2216

23-
## Dialog API
24-
25-
If a token doesn't exist, you should use the `OfficeRuntime.dialog` API to ask the user to sign in. After a user enters their credentials, the resulting access token can be stored as an item in `OfficeRuntime.storage`.
17+
## Authentication workflow
2618

27-
> [!NOTE]
28-
> The JavaScript-only runtime uses a dialog object that is slightly different from the dialog object in the browser runtime used by task panes. They're both referred to as the "Dialog API", but use [OfficeRuntime.displayWebDialog](/javascript/api/office-runtime#office-runtime-officeruntime-displaywebdialog-function(1)) to authenticate users in the JavaScript-only runtime, *not* [Office.ui.displayDialogAsync](/javascript/api/office/office.ui#office-office-ui-displaydialogasync-member(1)).
19+
The following workflow is typical for custom functions that don't use a shared runtime.
2920

30-
The following diagram outlines this basic process. The dotted line indicates that custom functions and your add-in's task pane are both part of your add-in as a whole, though they use separate runtimes.
31-
32-
1. You issue a custom function call from a cell in an Excel workbook.
33-
1. The custom function uses `OfficeRuntime.dialog` to pass your user credentials to a website.
34-
1. This website then returns an access token to the page in the dialog.
35-
1. Your JavaScript in the dialog calls the [Office.ui.messageParent](/javascript/api/office/office.ui#office-office-ui-messageparent-member(1)) function to send the access token to the custom function. For more information about this function, see [Send information from the dialog box to the host page](../develop/dialog-api-in-office-add-ins.md#send-information-from-the-dialog-box-to-the-host-page).
36-
1. Your custom function then sets this access token to an item in the `OfficeRuntime.storage`.
37-
1. Your add-in's task pane accesses the token from `OfficeRuntime.storage`.
21+
1. A user runs a custom function in an Excel cell.
22+
1. The custom function calls `OfficeRuntime.displayWebDialog` to open a sign-in page in a dialog, where the user enters their credentials.
23+
1. The sign-in page then returns an access token to the dialog.
24+
1. The dialog calls the [Office.ui.messageParent](/javascript/api/office/office.ui#office-office-ui-messageparent-member(1)) function to send the access token to the custom function. For more information about this function, see [Send information from the dialog box to the host page](../develop/dialog-api-in-office-add-ins.md#send-information-from-the-dialog-box-to-the-host-page).
25+
1. The custom function then sets this access token to an item in the `OfficeRuntime.storage`.
26+
1. The add-in's task pane accesses the token from `OfficeRuntime.storage`.
3827

3928
:::image type="content" source="../images/authentication-diagram.png" alt-text="Diagram of custom function using dialog API to get access token, and then share token with task pane through the OfficeRuntime.storage API.":::
4029

41-
## Storing the token
42-
43-
The following examples are from the [Using OfficeRuntime.storage in custom functions](https://github.com/OfficeDev/Office-Add-in-samples/tree/main/Excel-custom-functions/AsyncStorage) code sample. Refer to this code sample for a complete example of sharing data between custom functions and the task pane in add-ins that don't use a shared runtime.
30+
## Try it with a sample
4431

45-
If the custom function authenticates, then it receives the access token and will need to store it in `OfficeRuntime.storage`. The following code sample shows how to call the `storage.setItem` method to store a value. The `storeValue` function is a custom function that stores a value from the user. You can modify this to store any token value you need.
32+
Use the [Using OfficeRuntime.storage in custom functions](https://github.com/OfficeDev/Office-Add-in-samples/tree/main/Excel-custom-functions/AsyncStorage) sample to test token storage and retrieval between custom functions and a task pane.
4633

47-
```js
48-
/**
49-
* Stores a key-value pair into OfficeRuntime.storage.
50-
* @customfunction
51-
* @param {string} key Key of item to put into storage.
52-
* @param {*} value Value of item to put into storage.
53-
*/
54-
function storeValue(key, value) {
55-
return OfficeRuntime.storage.setItem(key, value).then(function (result) {
56-
return "Success: Item with key '" + key + "' saved to storage.";
57-
}, function (error) {
58-
return "Error: Unable to save item with key '" + key + "' to storage. " + error;
59-
});
60-
}
61-
```
62-
63-
When the task pane needs the access token, it can retrieve the token from the `OfficeRuntime.storage` item. The following code sample shows how to use the `storage.getItem` method to retrieve the token.
64-
65-
```js
66-
/**
67-
* Read a token from storage.
68-
* @customfunction GETTOKEN
69-
*/
70-
function receiveTokenFromCustomFunction() {
71-
const key = "token";
72-
const tokenSendStatus = document.getElementById('tokenSendStatus');
73-
OfficeRuntime.storage.getItem(key).then(function (result) {
74-
tokenSendStatus.value = "Success: Item with key '" + key + "' read from storage.";
75-
document.getElementById('tokenTextBox2').value = result;
76-
}, function (error) {
77-
tokenSendStatus.value = "Error: Unable to read item with key '" + key + "' from storage. " + error;
78-
});
79-
}
80-
```
81-
82-
## General guidance
83-
84-
Office Add-ins are web-based and you can use any web authentication technique. There is no particular pattern or method you must follow to implement your own authentication with custom functions. You may wish to consult the documentation about various authentication patterns, starting with [this article about authorizing via external services](../develop/auth-external-add-ins.md).
34+
## Dialog API
8535

86-
Avoid using the following locations to store data when developing custom functions:
36+
If a token doesn't exist, you should use `OfficeRuntime.displayWebDialog` to ask the user to sign in. After a user enters their credentials, the resulting access token can be stored as an item in `OfficeRuntime.storage`.
8737

88-
- `localStorage`: custom functions that don't use a shared runtime don't have access to the global `window` object and therefore have no access to data stored in `localStorage`.
89-
- `Office.context.document.settings`: This location isn't secure and information can be extracted by anyone using the add-in.
38+
> [!NOTE]
39+
> The JavaScript-only runtime uses a dialog object that is slightly different from the dialog object in the browser runtime used by task panes. They're both referred to as the "Dialog API", but use [OfficeRuntime.displayWebDialog](/javascript/api/office-runtime#office-runtime-officeruntime-displaywebdialog-function(1)) to authenticate users in the JavaScript-only runtime, *not* [Office.ui.displayDialogAsync](/javascript/api/office/office.ui#office-office-ui-displaydialogasync-member(1)).
9040
91-
## Dialog box API example
41+
### Dialog box API example
9242

9343
In the following code sample, the function `getTokenViaDialog` uses the `OfficeRuntime.displayWebDialog` function to display a dialog box. This sample is provided to show the capabilities of the method, not demonstrate how to authenticate.
9444

95-
```JavaScript
45+
```javascript
9646
/**
9747
* Function retrieves a cached token or opens a dialog box if there is no saved token. Note that this isn't a sufficient example of authentication but is intended to show the capabilities of the displayWebDialog method.
9848
* @param {string} url URL for a stored token.
@@ -136,6 +86,64 @@ function getTokenViaDialog(url) {
13686
}
13787
```
13888

89+
## OfficeRuntime.storage object
90+
91+
The JavaScript-only runtime doesn't have a `localStorage` object available on the global window, where you typically store data. Instead, your code should share data between custom functions and task panes by using `OfficeRuntime.storage` to set and get data.
92+
93+
### Suggested usage
94+
95+
When you need to authenticate from a custom function add-in that doesn't use a shared runtime, your code should check `OfficeRuntime.storage` to see if the access token was already acquired. If not, use [OfficeRuntime.displayWebDialog](/javascript/api/office-runtime#office-runtime-officeruntime-displaywebdialog-function(1)) to authenticate the user, retrieve the access token, and then store the token in `OfficeRuntime.storage` for future use.
96+
97+
### Storing the token
98+
99+
The following examples show how to store and retrieve tokens by using `OfficeRuntime.storage`.
100+
101+
If the custom function authenticates, then it receives the access token and will need to store it in `OfficeRuntime.storage`. The following code sample shows how to call the `storage.setItem` method to store a value. The `storeValue` function is a custom function that stores a value from the user. You can modify this to store any token value you need.
102+
103+
```javascript
104+
/**
105+
* Stores a key-value pair into OfficeRuntime.storage.
106+
* @customfunction
107+
* @param {string} key Key of item to put into storage.
108+
* @param {*} value Value of item to put into storage.
109+
*/
110+
function storeValue(key, value) {
111+
return OfficeRuntime.storage.setItem(key, value).then(function (result) {
112+
return "Success: Item with key '" + key + "' saved to storage.";
113+
}, function (error) {
114+
return "Error: Unable to save item with key '" + key + "' to storage. " + error;
115+
});
116+
}
117+
```
118+
119+
When the task pane needs the access token, it can retrieve the token from the `OfficeRuntime.storage` item. The following code sample shows how to use the `storage.getItem` method to retrieve the token.
120+
121+
```javascript
122+
/**
123+
* Read a token from storage.
124+
* @customfunction GETTOKEN
125+
*/
126+
function receiveTokenFromCustomFunction() {
127+
const key = "token";
128+
const tokenSendStatus = document.getElementById('tokenSendStatus');
129+
OfficeRuntime.storage.getItem(key).then(function (result) {
130+
tokenSendStatus.value = "Success: Item with key '" + key + "' read from storage.";
131+
document.getElementById('tokenTextBox2').value = result;
132+
}, function (error) {
133+
tokenSendStatus.value = "Error: Unable to read item with key '" + key + "' from storage. " + error;
134+
});
135+
}
136+
```
137+
138+
## General guidance
139+
140+
Office Add-ins are web-based, so you can use any web authentication technique. There isn't one required authentication pattern for custom functions. Start with [Authorize to external services in Office Add-ins](../develop/auth-external-add-ins.md) for design patterns and tradeoffs.
141+
142+
Avoid using the following locations to store data when developing custom functions:
143+
144+
- `localStorage`: custom functions that don't use a shared runtime don't have access to the global `window` object and therefore have no access to data stored in `localStorage`.
145+
- `Office.context.document.settings`: This location isn't secure, and anyone using the add-in can extract this information.
146+
139147
## Next steps
140148

141149
Learn how to [debug custom functions](custom-functions-debugging.md).

0 commit comments

Comments
 (0)