nodejs实现OAuth2.0授权服务

时间:2022-06-07 12:37:43

OAuth是一种开发授权的网络标准,全拼为open authorization,即开放式授权,最新的协议版本是2.0。

举个栗子:

有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来。用户为了使用该服务,必须让"云冲印"读取自己储存在Google上的照片。

传统方法是,用户将自己的Google用户名和密码,告诉"云冲印",后者就可以读取用户的照片了。这样的做法有以下几个严重的缺点。

  • "云冲印"为了后续的服务,会保存用户的密码,这样很不安全。
  • Google不得不部署密码登录,而我们知道,单纯的密码登录并不安全。
  • "云冲印"拥有了获取用户储存在Google所有资料的权力,用户没法限制"云冲印"获得授权的范围和有效期。
  • 用户只有修改密码,才能收回赋予"云冲印"的权力。但是这样做,会使得其他所有获得用户授权的第三方应用程序全部失效。
  • 只要有一个第三方应用程序被破解,就会导致用户密码泄漏,以及所有被密码保护的数据泄漏。

所以OAuth就诞生了!

名词定义

  • Third-party application:第三方应用程序,本文中又称"客户端"(client),即上一节例子中的"云冲印"。
  • HTTP service:HTTP服务提供商,本文中简称"服务提供商",即上一节例子中的Google。
  • Resource Owner:资源所有者,本文中又称"用户"(user)。
  • User Agent:用户代理,本文中就是指浏览器。
  • Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
  • Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

OAuth整体思路

登录层提供令牌(token)的生成,其中token包括:有效期、权限范围。客户端拿到token去访问受限资源。

  • access_token:请求资源时需要携带的token,即访问token。
  • refresh_token:刷新token,如果access_token过期,可以使用该token获取一份新的access_token和新的refresh_token。一般refresh_token时效性较长,比如一年,而access_token时效性较短,比如几分钟。
  • 权限范围:即指定客户端可以获取的资源权限范围。

OAuth授权模式

OAuth有四种授权模式,分别为:

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

1、授权码模式

授权码模式是最为严密的授权模式,整体流程为:浏览器携带必要信息至授权页面,正常登录成功后,返回一个code(授权码),客户端拿到code后在后台获取拿code换取token。

nodejs实现OAuth2.0授权服务

nodejs实现OAuth2.0授权服务

2、密码模式

密码模式,简单地理解即为使用用户名密码等参数获取access_token,它的步骤如下:

  • 用户向客户端提供用户名和密码。
  • 客户端将用户名和密码发给认证服务器,向后者请求令牌。
  • 认证服务器确认无误后,向客户端提供访问令牌。

nodejs实现OAuth2.0授权服务

3、refresh_token的应用

refresh_token被用来获取新的access_token和refresh_token,使用方式简单如下:

nodejs实现OAuth2.0授权服务

refresh_token无效:

nodejs实现OAuth2.0授权服务

使用nodejs实现OAuth授权服务

技术栈:

  • nodejs + eggjs
  • eggjs-oAuth-server插件

具体可以参考:

https://github.com/Azard/egg-oauth2-server

https://cnodejs.org/topic/592b2aedba8670562a40f60b

1、code grant模式测试及单点登录实现

这里我们构建两个站点,一个是7001端口(授权服务),一个是7002端口(客户端),授权模式为code grant。

首先是客户端登录页:

nodejs实现OAuth2.0授权服务

单击按钮后直接登录:

nodejs实现OAuth2.0授权服务

可以发现,浏览器重定向到授权服务地址,并携带了response_type、client_id、redirect_uri三个参数,登录成功后,浏览器会重定向到redirect_uri指定的地址,即这里的http://127.0.0.1:7002/auth/redirect

如下为授权服务的登录页写法

<form action="/oauth2/authorize?{{query}}" id="form1" name="f" method="post">
<div class="input_outer">
<span class="u_user"></span>
<input name="username" class="text" style="color: #FFFFFF !important" type="text" placeholder="请输入账户">
</div>
<div class="input_outer">
<span class="us_uer"></span>
<input name="password" class="text" style="color: #FFFFFF !important; position:absolute; z-index:100;"value="" type="password" placeholder="请输入密码">
</div>
<div class="mb2"><a class="act-but submit" href="javascript:;" onclick="document.getElementById('form1').submit()" style="color: #FFFFFF">登录</a></div>
</form>

这里的${query}即为客户端登录重定向携带的完整query,然后是/oauth2/authorize路由的写法:

app.all('/oauth2/authorize', app.oAuth2Server.authorize());      // 获取授权码

这里调用app.oAuth2Server.authorize()时,插件会自动执行重定向操作,首先是重定向到客户端指定地址,客户端拿到code和state后,再去授权层获取token:

async redirect(){
// 服务端重定向过来的
console.log(this.ctx.query)
const result = await this.ctx.curl('http://127.0.0.1:7001/users/token', {
dataType: 'json',
// contentType: 'application/x-www-form-urlencoded', // 默认格式
method: 'POST',
timeout: 3000,
data: {
grant_type: 'authorization_code',
code: this.ctx.query.code,
state: this.ctx.query.state,
client_id: client_id,
client_secret: client_secret,
redirect_uri: redirect_uri,
}
});
this.ctx.body = result.data;
}

获取到token后正常返回:

nodejs实现OAuth2.0授权服务

2、password grant模式测试

首先使用username、password获取access_token:

nodejs实现OAuth2.0授权服务

用户名或密码错误时返回:

nodejs实现OAuth2.0授权服务

使用token获取授权资源正常返回:

nodejs实现OAuth2.0授权服务

以上内容完整源码参考:https://github.com/caiya/eggjs-oAuth2-server

总结

  • OAuth实际使用时要上https,包括客户端和授权服务端
  • 授权服务可以使用私钥签名,客户端使用公钥验证,从而保证数据安全性

nodejs实现OAuth2.0授权服务的更多相关文章

  1. Microsoft&period;Owin&period;Security&period;OAuth搭建OAuth2&period;0授权服务端

    Microsoft.Owin.Security.OAuth搭建OAuth2.0授权服务端 目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Se ...

  2. Spring Security实现OAuth2&period;0授权服务 - 进阶版

    <Spring Security实现OAuth2.0授权服务 - 基础版>介绍了如何使用Spring Security实现OAuth2.0授权和资源保护,但是使用的都是Spring Sec ...

  3. Spring Security实现OAuth2&period;0授权服务 - 基础版

    一.OAuth2.0协议 1.OAuth2.0概述 OAuth2.0是一个关于授权的开放网络协议. 该协议在第三方应用与服务提供平台之间设置了一个授权层.第三方应用需要服务资源时,并不是直接使用用户帐 ...

  4. SimpleSSO&colon;使用Microsoft&period;Owin&period;Security&period;OAuth搭建OAuth2&period;0授权服务端

    目录 前言 OAuth2.0简介 授权模式 (SimpleSSO示例) 使用Microsoft.Owin.Security.SimpleSSO模拟OpenID认证 通过authorization co ...

  5. 使用微服务架构思想,设计部署OAuth2&period;0授权认证框架

    1,授权认证与微服务架构 1.1,由不同团队合作引发的授权认证问题 去年的时候,公司开发一款新产品,但人手不够,将B/S系统的Web开发外包,外包团队使用Vue.js框架,调用我们的WebAPI,但是 ...

  6. 使用DotNetOpenAuth搭建OAuth2&period;0授权框架

    标题还是一如既往的难取. 我认为对于一个普遍问题,必有对应的一个简洁优美的解决方案.当然这也许只是我的一厢情愿,因为根据宇宙法则,所有事物总归趋于混沌,而OAuth协议就是混沌中的产物,不管是1.0. ...

  7. 基于 IdentityServer3 实现 OAuth 2&period;0 授权服务【密码模式&lpar;Resource Owner Password Credentials&rpar;】

    密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码.客户端使用这些信息,向"服务商提供商"索要授权 ...

  8. Spring Boot 集成 Swagger2 与配置 OAuth2&period;0 授权

    Spring Boot 集成 Swagger2 很简单,由于接口采用了OAuth2.0 & JWT 协议做了安全验证,使用过程中也遇到了很多小的问题,多次尝试下述配置可以正常使用. Maven ...

  9. oauth2&period;0授权协议

    参考文章 一.OAuth是什么? OAuth的英文全称是Open Authorization,它是一种开放授权协议.OAuth目前共有2个版本,2007年12月的1.0版(之后有一个修正版1.0a)和 ...

随机推荐

  1. App&period;domain http-&gt&semi;https

    App.domain = `${location.origin}/toa-mgw/rest/gateway`.replace(/http:\/\//, 'https://');

  2. Python内存数据库&sol;引擎

    1 初探 在平时的开发工作中,我们可能会有这样的需求:我们希望有一个内存数据库或者数据引擎,用比较Pythonic的方式进行数据库的操作(比如说插入和查询). 举个具体的例子,分别向数据库db中插入两 ...

  3. Linux Ubuntu12&period;04下安装OpenCv2&period;4&period;10

    参考 http://blog.sina.com.cn/s/blog_53b0956801010lfu.html 捣鼓了一个晚上了,OpenCv还没装好,本来以为看个类似的比如Ubuntu安装OpenC ...

  4. 我们的动机(Our motivation)

    我们的动机(Our motivation) There are many PHP frameworks nowadays, but none of them is like Phalcon (Real ...

  5. redis&period;conf 配置详解 (转)

    # Redis 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写)## 1k => 1000 bytes# 1kb =&gt ...

  6. BST、B树、B&plus;树、B&ast;树

    一. BST BST即二叉搜索树Binary Search Tree(又叫二叉排序树Binary Sort Tree).它有以下特点: 所有非叶子结点至多拥有两个儿子(Left和Right): 所有结 ...

  7. Tomcat8配置数据库连接池

    1.所有的tomcat项目共用一个连接池配置 1.1 修改conf->context.xml文件,在Context节点下配置 <Resource name="jdbc/myDat ...

  8. jQuery中each的break和continue

    each实质上是一个for循环,那么能不能像普通的for循环那样break和continue呢? 参考http://bevisoft.iteye.com/blog/641195做了个实验,可以的, 代 ...

  9. 通过 Javacore 了解线程运行状况

    Javacore 是一个当前 JVM 运行状态的快照.通过对Javacore 的分析,可以了解在 JVM 中运行的应用程序的当前状态,比如是否“卡”在某一点上,或在某些代码上运行时间太长. Javac ...

  10. POJ2531——Network Saboteur&lpar;随机化算法水一发&rpar;

    Network Saboteur DescriptionA university network is composed of N computers. System administrators g ...