はじめに
Googleスプレッドシートへ利用者ごとのトークンを書き込む場合、文字列として渡しているつもりでも、シート側で数値として解釈されることがあります。 この問題は、数人のテストでは見つからず、本番で「特定の人だけURLが開けない」という形で出やすいです。
何が起きるか
UUIDからハイフンを消して先頭12文字を使うと、16進文字列になります。
function newToken_() {
return Utilities.getUuid().replace(/-/g, "").slice(0, 12);
}
16進文字列は、まれに数値や指数表記として読める並びになります。
| トークン例 | シート側の解釈 | 結果 |
|---|---|---|
01234ABC8901 | 文字列ID | 自動判定に任せると意図しない変換が起きる |
1e2345678901 | 指数表記 | 極端な数値やInfinity扱いになる |
7e00b2b1fd1a | 文字列 | 問題になりにくい |
setValue()で文字列を渡しても、セルの書式が自動判定だと、Googleスプレッドシート側が値として解釈してしまう場合があります。
解決策
書き込む前に、対象セルの表示形式を「書式なしテキスト」に固定します。
function writeToken_(range) {
range.setNumberFormat("@");
range.setValue(newToken_());
}
複数セルへsetValues()で一括投入する場合も同じです。
書き込む範囲に先にsetNumberFormat("@")をかけてから値を入れます。
const range = sheet.getRange(2, 3, values.length, 1);
range.setNumberFormat("@");
range.setValues(values.map((token) => [token]));
どの値で注意するか
トークン以外でも、次のような値は同じ問題を起こします。
- 郵便番号
- 電話番号
- 商品コード
- 先頭ゼロを含むID
1E5のように指数表記へ見えるコード
業務アプリでは、見た目が数字でも「計算する値」ではなく「識別子」として扱う列がよくあります。 そのような列は、先にテキスト書式へ固定します。
トークンの置き場所も分ける
利用者へ配るURLに載せるトークンは、管理者が目視しやすいようにシートへ置くことがあります。 一方で、外部API連携用のAPIトークンや秘密情報は、シートではなくScript Propertiesへ置く方が安全です。
function ensureApiToken_() {
const props = PropertiesService.getScriptProperties();
let token = props.getProperty("API_TOKEN");
if (!token) {
token = Utilities.getUuid().replace(/-/g, "");
props.setProperty("API_TOKEN", token);
}
return token;
}
関連記事
まとめ
トークンやIDをスプレッドシートへ保存する場合は、値を書き込む前にsetNumberFormat("@")を実行します。
「文字列として渡したから大丈夫」と考えず、シート側の自動解釈を止めることが、再現しにくい認証不具合を防ぐコツです。
