随着互联网的普及,前端技术得到了快速发展。而用户登录认证作为网站必不可少的一部分,也越来越受到前端工程师们的关注。本文将详细介绍如何基于 Hapi 框架来实现用户认证,并提供示例代码及学习参考。
什么是 Hapi 框架
Hapi 是一款基于 Node.js 的 Web 应用框架,是由 Walmart 实验室的开发人员编写的。该框架旨在提供一种可靠、可扩展和灵活的方法来构建 Web 应用程序,尤其是适用于大型组织和团队使用的 Web 应用。
与 Express 框架类似,Hapi 框架提供了路由、中间件、请求处理、视图等一系列 Web 开发所需的基本功能。但是,Hapi 还具有其它一些优秀的特性,例如支持插件机制、集中式配置、异常处理等。
Hapi 框架中的用户认证方法
在 Hapi 框架中,可以使用一组策略来实现用户认证。一个“策略”指定了一组验证规则和处理方法,用于对特定类型的用户(或请求)进行身份验证。
可供选择的认证策略有很多种,包括基本认证、cookie 认证、JSON web token(JWT)认证、OAuth2 认证等等。我们在本文中以 cookie 认证和 JWT 认证为例来介绍用户认证的方法。
Cookie 认证
对于某些应用程序,使用 cookie 来进行用户认证是一个方便且较为安全的方式。在 Hapi 框架中,可以使用 hapi-auth-cookie
插件来实现 cookie 认证。
以下是基于 Cookie 认证的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Boom = require('boom'); const Vision = require('vision'); const Inert = require('inert'); const Cookie = require('hapi-auth-cookie'); const server = Hapi.server({ port: 3000, host: 'localhost' }); const userDb = { john: { id: 1, password: 'password', name: 'John Doe' } }; const validate = async (request, session) => { const user = userDb[session.username]; if (!user) { return { valid: false }; } return { valid: true, credentials: user }; }; const init = async () => { await server.register([Cookie, Inert, Vision]); server.auth.strategy('session', 'cookie', { cookie: { name: 'sid-example', password: 'password-should-be-32-characters', isSecure: false }, redirectTo: '/login', validateFunc: validate }); server.route([ { method: 'GET', path: '/', config: { auth: 'session', handler: (request, h) => { return `Welcome ${request.auth.credentials.name}!`; } } }, { method: 'GET', path: '/login', handler: (request, h) => { return ` <html> <body> <h3>Login</h3> <form method="POST" action="/login"> <input type="text" name="username"> <input type="password" name="password"> <button type="submit">Login</button> </form> </body> </html> `; } }, { method: 'POST', path: '/login', handler: (request, h) => { const { username, password } = request.payload; const user = userDb[username]; if (!user) { return Boom.unauthorized('User not found'); } if (user.password !== password) { return Boom.unauthorized('Invalid password'); } request.cookieAuth.set({ username }); return h.redirect('/'); } }, { method: 'GET', path: '/logout', handler: (request, h) => { request.cookieAuth.clear(); return h.redirect('/login'); } } ]); await server.start(); console.log(`Server running at ${server.info.uri}`); }; init();
上面代码中,我们创建了一个名为 session
的认证策略,它使用 hapi-auth-cookie
插件并配置了以下参数:
cookie.name
: cookie 的名称cookie.password
: cookie 的加密密码,应当是一个长度为 32 的字符串cookie.isSecure
: 是否只接受 HTTPS 请求(为了安全起见,默认为 true)redirectTo
: 认证失败时重定向的 URLvalidateFunc
: 用于验证用户的函数
其中,validate
函数接受两个参数:request
和 session
。request
对象包含当前请求的数据,而 session
对象则包含了当前访问链接的会话数据。
在 validate
函数中,我们可以判断 session
中是否包含正确的用户信息,并根据结果返回 { valid: true, credentials: user }
或 { valid: false }
。
另外,还需要在路由配置中指定哪些请求需要进行认证。例如,我们使用 { auth: 'session' }
将所有访问 /
的请求都设置为需要经过 session
认证。同时,还需要在登录页面中添加用户名和密码输入框,并使用 POST
方法向 /login
发送数据以进行认证。
当用户登录成功后,我们使用 request.cookieAuth.set()
方法将认证信息写入 cookie,以便后续访问中再次进行认证。
JSON Web Token 认证
如果你希望更灵活地进行用户认证,那么 JSON Web Token(JWT)可能是一个更好的选择。JWT 是一种轻量级的授权标准,它允许在身份验证和授权过程中传递声明。
以下是基于 JWT 认证的示例代码:
// javascriptcn.com 代码示例 const Hapi = require('hapi'); const Boom = require('boom'); const Vision = require('vision'); const Inert = require('inert'); const Jwt = require('hapi-auth-jwt2'); const JwtSecret = 'password-should-be-32-characters'; const server = Hapi.server({ port: 3000, host: 'localhost' }); const userDb = { john: { id: 1, password: 'password', name: 'John Doe' } }; const validate = async (decoded, request) => { const user = userDb[decoded.username]; if (!user) { return { isValid: false }; } return { isValid: true, credentials: user }; }; const init = async () => { await server.register([Jwt, Inert, Vision]); server.auth.strategy('jwt', 'jwt', { key: JwtSecret, validateFunc: validate, verifyOptions: { algorithms: ['HS256'] }, cookieKey: 'sid-example', cookie: { isSecure: false } }); server.route([ { method: 'GET', path: '/', config: { auth: 'jwt', handler: (request, h) => { return `Welcome ${request.auth.credentials.name}!`; } } }, { method: 'POST', path: '/login', handler: (request, h) => { const { username, password } = request.payload; const user = userDb[username]; if (!user) { return Boom.unauthorized('User not found'); } if (user.password !== password) { return Boom.unauthorized('Invalid password'); } const token = Hapi.jwt.sign({ username }, JwtSecret, { algorithm: 'HS256', expiresIn: '1h' }); return h.response({ token }); } } ]); await server.start(); console.log(`Server running at ${server.info.uri}`); }; init();
上面代码中,我们创建了一个名为 jwt
的认证策略,它使用 hapi-auth-jwt2
插件,并配置了以下参数:
key
: JWT 的加密密码validateFunc
: 用于验证用户的函数verifyOptions
: 验证 JWT 的参数cookieKey
: 用于存储 JWT 的 cookie 名称cookie
: cookie 的相关设置
与 Cookie 认证的示例不同,我们并没有在路由配置中设置需要进行认证的请求。而是使用 auth: 'jwt'
标记所有 /
的请求都需要进行 JWT 认证。
由于 JWT 通常在登录时返回给用户,因此我们需要提供 /login
接口,以便用户向服务器获取 JWT。在此示例中,我们使用 Hapi.jwt.sign()
方法创建 JWT,其中包含了用户信息以及 JWT 的有效期,然后在返回的响应中将 JWT 作为数据传输。
总结
通过本文,我们了解了如何基于 Hapi 框架来实现用户认证,并提供了 Cookie 认证和 JWT 认证的示例代码。在实际项目中,也可以根据具体需求选择适合的认证方式。
对于前端工程师们而言,学习并掌握 Hapi 框架中的用户认证方法,有助于提高 Web 应用程序的安全性和可靠性,也能更好地满足用户的需求。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654574d27d4982a6ebf22edf