Skip to content

Commit f9e29ef

Browse files
author
Eric Koleda
committed
Add support for custom callback parameters.
1 parent c3f0f1a commit f9e29ef

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,38 @@ if (service.hasAccess()) {
325325
Note that calling `Service.reset()` will remove all custom values from storage,
326326
in addition to the token.
327327
328+
#### Passing additional parameters to the callback function
329+
330+
There are occasionally cases where you need to preserve some data through the
331+
OAuth flow, so that it is available in your callback function. Although you
332+
could use the token storage mechanism discussed above for that purpose, writing
333+
to the PropertiesService is expensive and not neccessary in the case where the
334+
user doesn't start or fails to complete the OAuth flow.
335+
336+
As an alternative you can store small amounts of data in the OAuth2 `state`
337+
token, which is a standard mechanism for this purpose. To do so, pass an
338+
optional hash of parameter names and values to the `getAuthorizationUrl()`
339+
method:
340+
341+
```js
342+
var authorizationUrl = getService().getAuthorizationUrl({
343+
lang: 'fr'
344+
});
345+
```
346+
347+
These values will be stored along-side Apps Script's internal information in the
348+
cryptographically secure `state` token, which is passed in the authorization URL
349+
and passed back to the redirect URI. The `state` token is automatically
350+
decrypted in the callback function, and you can access your parameters using the
351+
same `request.parameter` field used in web apps:
352+
353+
```js
354+
function authCallback(request) {
355+
var lang = request.parameter.lang;
356+
// ...
357+
}
358+
```
359+
328360
#### Using service accounts
329361
330362
This library supports the service account authorization flow, also known as the

src/Service.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,11 @@ Service_.prototype.setGrantType = function(grantType) {
306306
* have the user visit this URL and approve the authorization request. The
307307
* user will then be redirected back to your application using callback function
308308
* name specified, so that the flow may continue.
309+
* @param {Object} optAdditionalParameters Additional parameters that should be
310+
* stored in the state token and made available in the callback function.
309311
* @return {string} The authorization URL.
310312
*/
311-
Service_.prototype.getAuthorizationUrl = function() {
313+
Service_.prototype.getAuthorizationUrl = function(optAdditionalParameters) {
312314
validate_({
313315
'Client ID': this.clientId_,
314316
'Script ID': this.scriptId_,
@@ -317,16 +319,20 @@ Service_.prototype.getAuthorizationUrl = function() {
317319
});
318320

319321
var redirectUri = getRedirectUri(this.scriptId_);
320-
var state = eval('Script' + 'App').newStateToken()
322+
var stateTokenBuilder = eval('Script' + 'App').newStateToken()
321323
.withMethod(this.callbackFunctionName_)
322324
.withArgument('serviceName', this.serviceName_)
323-
.withTimeout(3600)
324-
.createToken();
325+
.withTimeout(3600);
326+
if (optAdditionalParameters) {
327+
Object.keys(optAdditionalParameters).forEach(function(key) {
328+
stateTokenBuilder.withArgument(key, optAdditionalParameters[key]);
329+
});
330+
}
325331
var params = {
326332
client_id: this.clientId_,
327333
response_type: 'code',
328334
redirect_uri: redirectUri,
329-
state: state
335+
state: stateTokenBuilder.createToken()
330336
};
331337
params = extend_(params, this.params_);
332338
return buildUrl_(this.authorizationBaseUrl_, params);

0 commit comments

Comments
 (0)