首页 > 解决方案 > jsonwebtoken 包验证用户 Office.context.mailbox.getUserIdentityToken 结果失败

问题描述

我正在开发 Outlook Web 加载项。

我正在尝试通过库验证我传递给服务器端的令牌node.js,但它失败了,我不明白为什么。

这就是我为检索用户身份令牌所做的工作。

Office.context.mailbox.getUserIdentityTokenAsync(function(result) {
    result.value // contains the token.
    // send this value to server side, which I can see that it's working.
})

在服务器端,我检索令牌并执行以下操作:

token; // contains the token passed from the web-app.
const jwt = require('jsonwebtoken');
const request = require('request');

let decoded = jwt.decode(token, {complete: true});

// Get the key, we'll need this later since we'll have to
// find the matching key from the config file.
let key = decoded.header.x5t;
let amurl = JSON.parse(decoded.payload.appctx).amurl;

// Make a request to the url to get the configuration json file.
request(amurl, {}, (err, response, body) => {
    let keys = JSON.parse(body).keys;

    // Filter the keys so we get the one which we can verify.
    let s = keys.filter(t => t.keyinfo.x5t === key);
    let cert = s[0].keyvalue.value;

    // Fails the verification.
    console.log(jwt.verify(token, cert));
});

澄清一下,我正在正确检索令牌,并且这个 npm 包似乎对其他 jwt 令牌运行良好。(所以这不是真正的配置问题)

标签: jwtoffice-jsoffice-addinsoutlook-web-addinsoffice-js-helpers

解决方案


我现在已经找到了这个问题的答案。

只是为了重申问题是:

  1. Office.context.mailbox.getUserIdentityToken方法返回一个 jwt 令牌。
  2. 解码后,此令牌包含一个amurl以文本形式指向公共证书的字段。
  3. 调用时jsonwebtoken.verify(token, certText),消息失败invalid algorithm(即使您从令牌的标头中指定算法)

问题是证书文本的格式jsonwebtoken包正在寻找一种特定的格式(每行与证书开始和证书结束行分开 64 个字符,所以当使用下面的方法格式化时 - 它开始正常工作。

原始代码取自这里:https ://github.com/auth0/node-jsonwebtoken/issues/68并稍微格式化以适应需要。

/**
 * @param {string} key - The certificate value retrieved from amurl property.
 */
formatKey: function(key) {
    const beginKey = "-----BEGIN CERTIFICATE-----";
    const endKey = "-----END CERTIFICATE-----";

    const sanitizedKey = key.replace(beginKey, '').replace(endKey, '').replace('\n', '')

    const keyArray = sanitizedKey.split('').map((l, i) => {
      const position = i + 1
      const isLastCharacter = sanitizedKey.length === position
      if(position % 64 === 0 || isLastCharacter) {
        return l + '\n'
      }
      return l
    })

    return `${beginKey}\n${keyArray.join('')}${endKey}\n`
  }

推荐阅读