在 Node.js 中实现 OAuth 认证

OAuth 是一种开放标准,用于用户授权同意第三方应用访问他们的资源,比如通过 Google 或 Facebook 登录第三方网站。本文将介绍在 Node.js 中实现 OAuth 认证的方法。

什么是 OAuth

OAuth 开放授权协议在 Web 应用程序之间,在用户授权第三方应用访问他们存储在另一个服务提供商上的信息的同时,无需向第三方应用公开用户名和密码。

通俗的说,如果你需要以 Twitter 的身份来访问 Flickr,你就不需要将 Twitter 的身份告诉 Flickr,只需要告诉 Flickr 你有 Twitter 的身份,让 Flickr 去授权。如果你需要以商店的身份,访问银行的 API,商家不需要去向银行询问你的密码,只需要让你同意授权这个请求即可。

比起早期授权方案,OAuth 被认为更安全和简便,因为用户无需直接分享他们的第三方凭证和敏感信息。

客户端 OAuth 和服务端 OAuth

根据 OAuth 的标准,有两种授权模式:客户端 OAuth 和服务端 OAuth。

  • 客户端 OAuth:客户端 OAuth 是最简单的模式,当用户在应用中请求访问第三方接口时,该应用弹出一个登录窗口要求用户在该第三方网站上授权访问,用户点击授权后,返回到该应用并调用该接口。
  • 服务端 OAuth:服务端 OAuth 相对复杂。当用户在应用中请求访问第三方接口时,该应用向第三方网站发起请求,并告诉第三方网站访问本应用得到的 token。如果第三方网站检测到该 token 是正确的,则返回给该应用需要的数据。

实现 OAuth 认证

下面是一个使用 Node.js 实现服务端 OAuth 认证的代码示例。

  1. 首先,你需要安装 express 和 request 模块,这两个可以用 npm 安装,实现代码如下:
npm install express request --save
  1. 然后,创建一个 express 服务器,实现代码如下:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});
  1. 接着,我们将 OAuth 所需的数据存放在环境变量中,便于更改,具体请参考你所需 API 的文档,实现代码如下:
const CLIENT_ID = process.env.CLIENT_ID 
const CLIENT_SECRET = process.env.CLIENT_SECRET 
const REDIRECT_URI = process.env.REDIRECT_URI
  1. 我们还需要一个路由来响应用户的认证请求,首先,设置好路由:
app.get('/auth/:provider', (req, res) => {
  const {provider} = req.params;
  
// TODO: 认证代码写在这里

});
  1. 接着,我们将使用 request 和 querystring 模块构造一个发送请求的中间件:
const qs = require('querystring');
const request = require('request');

function getAccessTokenFromCode({code, provider}, callback) {
  const grantType = 'authorization_code';

  const params = {
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET,
    code: code,
    grant_type: grantType,
    redirect_uri: REDIRECT_URI
  }

  const url = `https://${provider}/oauth/token`;

  const options = {
    url: url,
    headers: {
      'Accept': 'application/json'
    },
    form: params
  }

  request.post(options, (err, res, body) => {
    if (err) return callback(err);

    const accessToken = qs.parse(body).access_token;
    callback(null, accessToken);
  });
}
  1. 最后,在路由中添加认证代码即可。
app.get('/auth/:provider', (req, res) => {
  const {provider} = req.params;
  
  const params = {
    client_id: CLIENT_ID,
    redirect_uri: REDIRECT_URI,
    response_type: 'code',
    scope: 'read'
  }

  const url = `https://${provider}/oauth/authorize`;

  res.redirect(url + '?' + qs.stringify(params));
});

app.get('/callback/:provider', (req, res) => {
  const {code} = req.query;
  const {provider} = req.params;

  getAccessTokenFromCode({code, provider}, (err, accessToken) => {
    if (err) return res.status(500).send(err);

    res.send(`Your access token is: ${accessToken}`);
  });
});

上述代码中,路由 /auth/:provider 用于初始化认证请求,该路由将用户重定向到第三方机构的授权页面上,在用户授权后,重定向回该应用的回调 URL。当接收到回调时,路由 /callback/:provider 会获取令牌,使用令牌调用认证 API,将令牌返回给用户。

总结

本文介绍了 OAuth 的基本概念,以及如何在 Node.js 中使用 OAuth 实现认证。OAuth 结合各种第三方服务,为应用程序提供了更多的可扩展性和互操作性,可以使用户更加方便地使用 Web 应用程序。需要注意的是,在实现 OAuth 认证的过程中,一定要注意隐私和安全问题。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659e676fadd4f0e0ff75ebc8


纠错反馈