首页 > 解决方案 > Azure AD 发布者的授权令牌请求返回 302

问题描述

在作为我网页后端的 Azure 函数中,我按照此页面的说明请求了 Azure AD 发布者的授权令牌。这是我的 Azure Functions 的代码行:

  // Stringfy request body
  const postData = querystring.stringify({
    'grant_type': 'client_credentials',
    'client_id': client_id,
    'client_secret': client_secret,
    'resource': resource,
  });

  
  // Initiate options
  var httpAgent = new http.Agent();
  httpAgent.maxSockets = 200;
  const options = {
    hostname: 'login.microsoftonline.com',
    path: `/${tenantId}/oauth2/token`,
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    agent: httpAgent,
  }


  const tokenReq = http.request(options, (res) => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);

    res.setEncoding('utf-8')

    res.on('data', (chunk) => {
      console.log(chunk);
      body += chunk;
    });

    res.on('end', () => {
      console.log('No more data in response.');
      console.log("body:" + body);
      context.res = {
        status: 200,
        body: body,
      };
    });
  });

  tokenReq.on('error', (e) => {
    console.log(`problem with request: ${e.message}`);
    context.res = {
      status: 500,
      body: `problem with request: ${e.message}`,
    }
  });


  // write data to request body
  tokenReq.write(postData);
  tokenReq.end();

预期的响应是我需要的访问令牌,但是在本地运行它我得到了 STATUS 302,以及一个包含位置和一些其他参数的标头作为响应。据我了解,STATUS 302 表示 URL 暂时移动到标题中提供的位置。现在,我不知道我应该做什么,我必须发出的请求应该是一个 POST 请求,因此重定向不起作用。在收到重定向 URL 后,我也尝试发出新请求,但我收到一条错误消息:getaddrinfo ENOTFOUND {redirect URL from header}。我在这里做错了什么?

标签: javascripthttpazure-active-directoryazure-functions

解决方案


302错误是由http模块引起的,你使用require('http');andhttp.request(options, (res)....来做请求,所以它显示302错误。

我建议你使用var request = require('request');做请求,下面是我的功能代码供你参考(在使用request模块之前,你需要先运行npm install request安装它):

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    var result = await generatetoken(context);
    context.res = {
        body: result
    };
}

function generatetoken(context){
    var request = require('request');

    var options = {
            'method': 'POST',
            'url': 'https://login.microsoftonline.com/<your tenant id>/oauth2/token',
            'headers': {
            'Content-Type': 'application/x-www-url-form-urlencoded'
        },
        form: {
        'client_id': 'xxxxxx',
        'grant_type': 'client_credentials',
        'resource': 'xxxxx',
        'client_secret': 'xxxxx'
        }
    };

    return new Promise(function(resolve, reject) {
        request(options, function(err, res) {
            if (err) {
                reject(err);
            } else {
                context.log(res.body);
                resolve(res.body);
            }
        })
    })
}

推荐阅读