前言
当今互联网应用程序对用户权限控制的需求日益增长,OAuth2 作为一个广泛应用的授权标准,已成为在应用程序中实现管理用户应用程序授权最流行的方法之一。而在后端技术中,Hapi.js 是一个易于使用、高度可配置且被广泛使用的 node.js 框架。在此篇文章中,我将带领读者了解 Hapi.js 如何实现 OAuth2 验证。
简介
OAuth2 是一个授权框架,它允许第三方应用程序以特定用户的身份访问另一个 Web 应用程序资源,而不需要公开 安全凭证。在理解 OAuth2 之前,我们需要知道以下概念:
- 资源所有者(resource owner):能够对资源进行访问、控制资源访问权限的个人或实体。
- 客户端(client):请求访问受保护资源的应用程序。
- 授权服务器(authorization server):负责认证资源所有者并提供访问令牌(access tokens)的服务器。
- 资源服务器(resource server):存储受保护资源的服务器。
- 访问令牌(access tokens):由授权服务器颁发,用于访问资源服务器的令牌。
OAuth2 定义了四种授权方式:
- 授权码模式(authorization code grant)
- 简化模式(implicit grant)
- 密码模式(resource owner password credentials grant)
- 客户端凭证模式(client credentials grant)
在本文中,我们将使用授权码模式进行实现。
实现
Hapi.js 提供了插件 hapi-auth-oauth2,它可以帮助我们快速地实现 OAuth2 验证。让我们先安装它:
$ npm install hapi-auth-oauth2
接下来是 Hapi.js 实现 OAuth2 的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Bcrypt = require('bcrypt'); const HapiAuthOAuth2 = require('hapi-auth-oauth2'); // 设置客户端,资源服务器和授权服务器 const clients = { '123': { clientSecret: 'secretKey' } }; const users = { 'john': { // 对密码加密 password: Bcrypt.hashSync('password', 10) } }; const tokens = {}; const server = new Hapi.Server(); // 注册 hapi-auth-oauth2 插件 await server.register(HapiAuthOAuth2); server.auth.strategy('oauth2', 'oauth2', { // 配置认证服务器和客户端 tokenType: 'Bearer', verifyOptions: { algorithms: ['HS256'] }, accessTokenName: 'access_token', // 验证客户端 validateClientFunc: function (clientId, clientSecret, callback) { const client = clients[clientId]; if (!client) { return callback(null, false); } if (client.clientSecret !== clientSecret) { return callback(null, false); } callback(null, true, client); }, // 验证访问令牌 validateFunc: function (token, callback) { if (tokens[token]) { return callback(null, true, tokens[token]); } callback(null, false); } }); // 路径需要 OAuth2 验证,需要先定义策略 server.route({ method: 'GET', path: '/private', config: { auth: 'oauth2', handler: function (request, h) { return 'private'; } } }); server.route({ method: 'POST', path: '/oauth/token', config: { auth: false, handler: function (request, h) { const {grant_type, client_id, client_secret} = request.payload; if (grant_type === 'client_credentials') { const client = clients[client_id]; if (!client) { return h.response({error: 'Invalid client credentials'}).code(401); } if (client.clientSecret !== client_secret) { return h.response({error: 'Invalid client credentials'}).code(401); } const accessToken = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); tokens[accessToken] = {id: accessToken}; return {access_token: accessToken}; } if (grant_type === 'password') { const {username, password} = request.payload; const user = users[username]; if (!user) { return h.response({error: 'Invalid username or password'}).code(401); } if (!Bcrypt.compareSync(password, user.password)) { return h.response({error: 'Invalid username or password'}).code(401); } const accessToken = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); tokens[accessToken] = {id: username}; return {access_token: accessToken}; } return h.response({error: 'Invalid grant_type'}).code(400); } } }); await server.start(); console.log('Server running at: ', server.info.uri);
上述代码中,我们定义了客户端、资源服务器和授权服务器的配置。Hapi.js 的插件使得我们只需要引入插件并设置策略即可实现 OAuth2 的验证功能。在路由中只需要在 auth
属性中指定使用 OAuth2 策略即可进行 OAuth2 验证。
总结
在本文中,我们简单介绍了 OAuth2 概念及其四种授权方式。同时,我们通过 Hapi.js auth 插件的帮助轻松实现了 OAuth2 验证。本文的示例代码可以帮助读者更好地理解 OAuth2 和 Hapi.js 的实现方式,并体验 OAuth2 在 Hapi.js 中的应用。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65387d4b7d4982a6eb153895