带着问题看源码2-NodeRed的用户认证机制是怎样的

带着问题看源码2-NodeRed的用户认证机制是怎样的文章目录 1 几种常用的认证机制 1 1 HTTPBasicAut 2 OAuth2 NodeRed 中的认证机制使用 2 1 基于用户名 密码凭据的身份验证 2 2 针对任何 OAuth OpenID 提供者 如 Twitter 或 GitHub 进行身份验证 2 3 自定义用户身份验证 2 4 自定义的身份验证 token2 5 使用自定义 token 访问编辑器 3 功能实现的参与者 3 1 oauth2orize 主要功能及在本模块中的意义 3 2 passport3 3 express sessi

博客迁移

不恰饭的小站

文章目录

1. 几种常用的认证机制

1.1. HTTP Basic Auth Basic Auth是开放平台的两种认证方式,简单点说明就是每次请求API时都提供用户的username和password。

  • 优点:
    • 使用非常简单,
    • 开发和调试工作简单,
    • 没有复杂的页面跳转逻辑和交互过程;
    • 更利于发起方控制;
  • 缺点:
    • 安全性低,每次都需要传递用户名和密码,用户名和密码很大程度上存在被监听盗取的可能;一次密码盗用,会导致所有使用此密码的全部应用处于风险之中
    • 同时应用本地还需要保存用户名和密码,在应用本身的安全性来说,也存在很大问题;
    • 开放平台服务商出于自身安全性的考虑(第三方可以得到该服务商用户的账号密码,对于服务商来说是一种安全隐患),未来也会限制此认证方式(Twitter就计划在6月份停止Basic Auth的支持)
    • 用户如果更改了用户名和密码,还需要重新进行密码校验的过程。

1.2. OAuth OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。 OAuth在”客户端”与”服务提供商”之间,设置了一个授权层(authorization layer)。“客户端”不能直接登录”服务提供商”,只能登录授权层,以此将用户与客户端区分开来。”客户端”登录授权层所用的token(token),与用户的密码不同。用户可以在登录的时候,指定授权层token的权限范围和有效期。 “客户端”登录授权层以后,”服务提供商”根据token的权限范围和有效期,向”客户端”开放用户储存的资料。 客户端必须得到用户的授权(authorization grant),才能获得token(access token)。 主要流程如下: 主要流程)

2. NodeRed中的认证机制使用 NodeRed使用 OAuth 2.0 实现认证

2.1. 基于用户名/密码凭据的身份验证 要在编辑器和管理API上启用用户身份验证,在settings.js文件中取消adminAuth属性的注释: “`adminAuth: {

type: "credentials", users: [ { username: "admin", password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.", permissions: "*" }, { username: "george", password: "$2b$08$wuAqPiKJlVN27eF5qJp.RuQYuy6ZYONW7a/UWYxDTtwKFCdB8F19y", permissions: "read" } ] } ```users属性是一个user对象数组。这允许您定义多个用户,每个用户可以拥有不同的权限。 上面的示例配置定义了两个用户。一个叫admin的人可以在编辑器内做任何事情,并且有一个密码为password的密码。另一个叫george,他被赋予只读访问权限。 请注意,密码是使用bcrypt算法生成的。 

2.2. 针对任何OAuth/OpenID提供者(如Twitter或GitHub)进行身份验证 要使用外部身份验证源,Node-RED可以使用Passport提供的各种策略。 Node-RED认证模块可以用于Twitter和GitHub。他们总结了一些具体的策略细节,使其更易于使用。但它们也可以用作其他类似策略的身份验证模板。 下面的示例演示如何配置针对Twitter的身份验证,而不使用我们提供的auth模块。

 type:"strategy", strategy: { name: "twitter", label: 'Sign in with Twitter', icon:"fa-twitter", strategy: require("passport-twitter").Strategy, options: { consumerKey: TWITTER_APP_CONSUMER_KEY, consumerSecret: TWITTER_APP_CONSUMER_SECRET, callbackURL: "http://example.com/auth/strategy/callback", verify: function(token, tokenSecret, profile, done) { done(null, profile); } }, }, users: [ { username: "knolleary",permissions: ["*"]} ] }; ``` 2.3. 自定义用户身份验证 除了将用户硬编码到设置文件中,还可以插入自定义代码对用户进行身份验证。这使得与现有的身份验证方案集成成为可能。 1. 将以下内容保存到一个名为<node-red>/user-authentication.js的文件中 ```module.exports = { type: "credentials", users: function(username) { return new Promise(function(resolve) { // Do whatever work is needed to check username is a valid // user. if (valid) { // Resolve with the user object. It must contain // properties 'username' and 'permissions' var user = { username: "admin", permissions: "*" }; resolve(user); } else { // Resolve with null to indicate this user does not exist resolve(null); } }); }, authenticate: function(username,password) { return new Promise(function(resolve) { // Do whatever work is needed to validate the username/password // combination. if (valid) { // Resolve with the user object. Equivalent to having // called users(username); var user = { username: "admin", permissions: "*" }; resolve(user); } else { // Resolve with null to indicate the username/password pair // were not valid. resolve(null); } }); }, default: function() { return new Promise(function(resolve) { // Resolve with the user object for the default user. // If no default user exists, resolve with null. resolve({anonymous: true, permissions:"read"}); }); } } ``` 2. 在settings.js中设置adminAuth属性来加载这个模块: ```adminAuth: require("./user-authentication") ``` 2.4. 自定义的身份验证token 在某些情况下,您可能需要使用自己的身份验证token,而不使用Node-RED生成的身份验证token。例如: * 您希望使用基于OAuth的用户身份验证,但是您还需要自动访问管理API,它不能执行OAuth要求的交互式身份验证步骤 * 您希望将Node-RED集成到现有系统中,其中用户已经登录,并且不希望他们在访问编辑器时再次登录 adminAuth可以包括一个token函数。如果对管理api的请求不包含Node-RED识别为自己的身份验证token,则将调用此函数。将请求中提供的token传递给它,它应该返回一个与经过身份验证的用户进行解析的承诺,如果token无效,则返回null。 ```adminAuth: { ... tokens: function(token) { return new Promise(function(resolve, reject) { // Do whatever work is needed to check token is valid if (valid) { // Resolve with the user object. It must contain // properties 'username' and 'permissions' var user = { username: 'admin', permissions: '*' }; resolve(user); } else { // Resolve with null as this user does not exist resolve(null); } }); }, ... } ```默认情况下,它将使用授权http头,并期待一个Bearer类型token——只将token的值传递给函数。如果它不是Bearer类型token,则授权头的完整值将传递给函数,其中包含类型和值。 要使用不同的HTTP头,可以使用tokenHeader设置来确定使用哪个头: ```adminAuth: { ... tokens: function(token) { ... }, tokenHeader: "x-my-custom-token" } ``` 2.5. 使用自定义token访问编辑器 要在不提示登录的情况下使用自定义Token访问编辑器,请向URL添加?access_token=< access_token >。编辑器将在本地存储该Token,并将其用于所有未来的请求。 3. 功能实现的参与者 3.1. oauth2orize(主要功能及在本模块中的意义) OAuth2orize 是 NodeJS 的授权服务器工具包。它提供了一套中间件, 这些中间件与 passport 身份验证策略和特定于应用程序的路由处理程序相结合, 可用于组装实现 OAuth 2.0 协议的服务器。 主要方法: * oauth2orize.createServer 提供授权服务器 * server.exchange 授权码交换访问Token。用户名及密码验证通过后,第三方(浏览器)可以使用授权码换到访问Token,通过Token就可以访问服务器资源。 3.2. passport passport.js是Nodejs中的一个做登录验证的中间件,极其灵活和模块化,并且可与Express、Sails等Web框架无缝集成。passport模块本身不能做认证,所有的认证方法都以策略模式封装为插件,需要某种认证时将其添加到package.json即可。 主要方法: * passport.use 提供策略及配置 * passport.authenticate 对请求进行身份验证并指定认证策略 * passport.initialize 在基于Connect或express的应用程序中,需要Passport. initialize()中间件来初始化Passport。 * passport.session 如果您的应用程序使用持久登录会话,还必须使用passport.session()中间件。 请注意,启用会话支持是完全可选的,尽管大多数应用程序都推荐启用会话支持。如果启用,请确保在passport.session()之前使用session(),以确保登录会话以正确的顺序恢复。 3.3. express-session session 的运作通过一个 session_id 来进行。session_id 通常是存放在客户端的 cookie 中,比如在 express 中,默认是 connect.sid 这个字段,当请求到来时,服务端检查 cookie 中保存的 session_id 并通过这个 session_id 与服务器端的 session data 关联起来,进行数据的保存和修改。 express 中操作 session 要用到 express-session (https://github.com/expressjs/session ) 这个模块,主要的方法就是session(options),其中 options 中包含可选参数,主要有: * name: 设置 cookie 中,保存 session 的字段名称,默认为 connect.sid 。 * store: session 的存储方式,默认存放在内存中,也可以使用 redis,mongodb 等。express 生态中都有相应模块的支持。 * secret: 通过设置的 secret 字符串,来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改。 * cookie: 设置存放 session id 的 cookie 的相关选项,默认为 * (default: { path: '/', httpOnly: true, secure: false, maxAge: null }) * genid: 产生一个新的 session_id 时,所使用的函数, 默认使用 uid2 这个 npm 包。 * rolling: 每个请求都重新设置一个 cookie,默认为 false。 * resave: 即使 session 没有被修改,也保存 session 值,默认为 true。 3.4. passport-http-bearer Passport的HTTP Bearer认证策略。 这个模块允许您在Node.js应用程序中使用Bearer Token(由RFC 6750指定)验证HTTP请求。Bearer Token通常使用保护API端点,并且通常使用OAuth 2.0发布。 通过插入Passport,BearerToken支持可以轻松地集成到支持连接式中间件的任何应用程序或框架中,包括Express。 passport-oauth2-client-password 策略 OAuth 2.0 Passport客户端密码认证策略。 这个模块允许您验证请求体中包含客户端凭据的请求,正如OAuth 2.0规范所定义的那样。这些凭据通常用于保护Token端点,并用作HTTP基本身份验证的替代方案。 4. 功能分阶段描述 auth:packages/node_modules/@node-red/editor-api/lib/auth/index.js auth_users:packages/node_modules/@node-red/editor-api/lib/auth/users.js auth_tokens:packages/node_modules/@node-red/editor-api/lib/auth/tokens.js auth_strategies:packages/node_modules/@node-red/editor-api/lib/auth/strategies.js storage:packages/node_modules/@node-red/runtime/lib/storage/index.js ```mermaid %% 配置 %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#FFFFFF'}}}%% sequenceDiagram autonumber %%实现 title: NodeRed中的用户认证机制(settings=credentials) participant 其他 auth -->> auth: 配置passport认证策略 auth -->> auth: 创建 oauth2 认证服务器 auth -->> auth: 配置 oauth2 授权码交换访问Token处理 其他 -->> auth: 启动初始化流程init auth -->> auth_users: 启动初始化流程init,初始化 Users 模块 auth -->> auth_tokens: 启动初始化流程init,初始化 Tokens 模块 其他 -->> auth: 将 /auth/login 路径路由到 login 、 errorHandler 方法 其他 -->> auth: 将 /auth/token 路径路由到 ensureClientSecret 、 authenticateClient 、 getToken、 errorHandler 方法 其他 -->> auth: 将 /auth/revoke 路径路由到 needsPermission 、revoke、 errorHandler 方法 auth -->> auth: ... 其他 -->> auth: 用户登陆操作,调用login方法,根据不同的settings配置,返回显示界面 auth -->> auth: ... 其他 -->> auth: 用户输入用户名称和密码,进行认证 auth -->> auth_users: 验证客户端ID(node-red-editor)是否有效,auth_users 使用 oauth2-client-password 策略 auth -->> auth: ... auth -->> auth_strategies: 根据已配置的 oauth2 授权码交换访问Token方法,获取Token auth_strategies -->> auth_users : 用户认证 authenticate(判断用户是否为合法用户,验证用户名和密码) auth_users -->> auth_strategies: 返回用户信息信息 auth_strategies -->> auth_strategies: 判断用户权限, permissions.hasPermission auth_strategies -->> auth_strategies: 创建Token auth_strategies -->> auth_tokens : 创建会话信息,设置会话结束时间,做Token超时处理 auth_tokens -->> storage: 保存会话信息到文件(/home/freeman/.node-red/.sessions.json) auth -->> auth: ... 其他 -->> auth: 用户登陆后所有操作,调用 bearerStrategy 方法,判断请求所携带的Token是否有效,若无效则返回错误信息,禁止操作 auth -->> auth: ... 其他 -->> auth: 用户登出操作,调用 revoke 方法 auth -->> auth: ... ``` 5. 功能使用场景 存在于使用的各阶段(初始化、运行、结束),是开启用户验证后必需的功能。 6. 实现方式特点 1. 使用策略模式对算法封装 2. 模块化使用第三方库,完成用户认证 3. 可扩展实现定制的用户认证 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231492.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号