ExpressJS Node.js Angular 错误:获取 OAuth2 API 授权令牌时出现 getaddrinfo ENOTFOUND

Posted

技术标签:

【中文标题】ExpressJS Node.js Angular 错误:获取 OAuth2 API 授权令牌时出现 getaddrinfo ENOTFOUND【英文标题】:ExpressJS Node.js Angular Error: getaddrinfo ENOTFOUND While Getting OAuth2 API Authorisation Token 【发布时间】:2020-07-08 16:18:54 【问题描述】:

我编写了一个 Angular 应用程序,单击按钮会向 Node/Express.js 端点发出 HTTP 发布请求以获取授权令牌。

在邮递员中,我已成功完成以下操作:

    为基本 OAuth2 授权令牌配置相关凭据并获取访问令牌 我正在调用带有访问令牌的 RESTful 端点并在 ldap 目录上创建用户。

在 Angular 应用中,我创建了以下关键组件:

    用户界面 AuthResponse 接口 认证服务 界面组件

以下是 Angular 前端应用中 Auth Service 的逻辑摘录:

import  Injectable  from '@angular/core';
import  HttpClient  from '@angular/common/http';
import  User  from  './../auth/user';
import  AuthResponse  from  './../auth/auth-response';
import  tap  from  'rxjs/operators';
import  Observable, BehaviorSubject  from  'rxjs';

@Injectable(
  providedIn: 'root'
)
export class AuthService 

  AUTH_SERVER = "http://localhost:3000";
  authSubject  =  new  BehaviorSubject(false);

  constructor(private httpClient: HttpClient)  

  register(user: User): Observable<AuthResponse> 
      return this.httpClient.post<AuthResponse>(`$this.AUTH_SERVER/register`, user).pipe(
        tap((res:  AuthResponse ) => 

          if (res.token) 
            console.log("ACCESS_TOKEN : "+ res.token.access_token);
            localStorage.set("ACCESS_TOKEN", res.token.access_token);
            localStorage.set("EXPIRES_IN", res.token.token_type);
            localStorage.set("ACCESS_TOKEN", res.token.expires_in);
            localStorage.set("EXPIRES_IN", res.token.refresh_token);
            this.authSubject.next(true);
          
        )

      );
    

下面是角度视图组件中的代码

  register() 
    console.log('fetching registration token');
    this.authService.register(this.user).subscribe((res) => 
      //this.router.navigateByUrl('home');
    );
  

以下是调用包含调用注册端点的按钮的html片段:

<div>
      <button (click)="register()" >Register</button> 
</div>

下面是我的 expressjs app.js

const express = require('express')
const http = require('https')
const app = express()
const  router  =  express.Router();
const cors = require('cors');
const bodyParser  = require("body-parser")
const api_helper = require('./util/api_helper')

const port = 3000

app.use(cors());
router.use(bodyParser.urlencoded( extended:  false ));
router.use(bodyParser.json());

router.get('/', (req, res) => 
    res.status(200).send('Welcome to Make REST API Calls to Authorisation Server In Express!');
);

router.get('/getAPIResponse', (req, res) => 
    api_helper.make_API_call('https://jsonplaceholder.typicode.com/todos/1')
    .then(response => 
        res.json(response)
    )
    .catch(error => 
        res.send(error)
    )
)


router.post('/register', (req, res) => 
  console.log('Entering the server endpoint ');

  //following variables are being printed to my browser console successfully
  console.log('angular sent user name = '+req.body.username);
  console.log('angular sent password = '+req.body.password);

  var client_id = 'xxxx';
  var client_secret = 'yyyyyy';
  var auth_header = 'Basic ' + Buffer.from(client_id + ':' + client_secret).toString('base64');

  const data = "grant_type=password&username=joe&password=joepass&client_id=xxxx&client_secret=yyyyyy";

  var authURI = "https://[hostname]:[port-no]/osp/a/idm/auth/oauth2/token";

  const options = 
      hostname: authURI,
      form: data,
      port: [port-no],
      method: 'POST',
      headers: 
          'Content-Type': 'application/x-www-formurlencoded'
          //'Authorization': auth_header
      
  ;

  http.request(options, (res) => 
  //  const req = http.request(options, (res) => 
    console.log(`statusCode: $res.statusCode`)
    res.setHeader( 'Access-Control-Allow-Headers', 'Accept,Accept-Language,Content-Language,Content-Type')
    res.on('data', (chunk) => 
      console.log(`BODY: $chunk`);
    );
    res.on('end', () => 
      console.log('No more data in response.');
    );
  );

  req.on('error', (error) => 
    console.log('error is ' + error);
  );

);

app.use(router);
app.listen(port, () => console.log(`Node server listening on port $port!`))

我的 nodejs app.js 中的以下端点有效:

router.get('/getTestResponse', (req, res) => api_helper.make_API_call('https://jsonplaceholder.typicode.com/todos/1') .then(响应 => res.json(响应) ) .catch(错误 => res.send(错误) ) )

它使用以下辅助函数:

const request = require('request')

module.exports = 
    /*
    ** This method returns a promise
    ** which gets resolved or rejected based
    ** on the result from the API
    */
    make_API_call : function(url)
        return new Promise((resolve, reject) => 
            request(url,  json: true , (err, res, body) => 
              if (err) reject(err)
              resolve(body)
            );
        )
    

问题是当我从 Angular 应用程序中单击注册按钮时出现以下错误。 但是,nodejs /register 端点被触发,即将从请求对象检索到的用户名和密码记录到控制台:

Entering the server endpoint 
events.js:288
      throw er; // Unhandled 'error' event
      ^

Error: getaddrinfo ENOTFOUND https://[hostname]:[port-no]/osp/a/idm/auth/oauth2/token
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:64:26)
Emitted 'error' event on ClientRequest instance at:
    at TLSSocket.socketErrorListener (_http_client.js:426:9)
    at TLSSocket.emit (events.js:311:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) 
  errno: 'ENOTFOUND',
  code: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'https://[hostname]:[port-no]/osp/a/idm/auth/oauth2/token'

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! registration-express-app@0.0.1 start: `node ./src/app/app.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the registration-express-app@0.0.1 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/admin/.npm/_logs/2020-03-28T08_56_14_947Z-debug.log

【问题讨论】:

【参考方案1】:

问题在于 http.request 选项。基本上,主机名:应该只是主机名,而不是https://[hostname]:[port-no]/xxx/auth/oauth2/token! 然后将路径属性用于端点 URI 的其余部分,即 /xxx/auth/oauth2/token 。

事情进展了,但我现在收到另一个错误“错误:证书链中的自签名证书” 我将就此结束这个问题,以确保其他人可以从我的经验中受益。 回馈社会。

请参阅下面的一些不错的参考:

https://node.readthedocs.io/en/latest/api/https/

【讨论】:

以上是关于ExpressJS Node.js Angular 错误:获取 OAuth2 API 授权令牌时出现 getaddrinfo ENOTFOUND的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS、Node.js、ExpressJS 应用程序集成问题

Node.js 和 expressjs paypal ipn 监听器给出错误 500

如何在 Node.js expressjs 的异步对象方法中处理未处理的承诺拒绝?

ExpressJS包的用途?

我应该在每次使用 ExpressJS/Node 更改时重新启动应用程序服务器吗? [复制]

Node js 或 Express js 的基于角色的授权