背景

博主的主要工作是测试API,目前已经用Jmeter+Jenkins实现了项目中的接口自动化测试流程。但是马上要接手的项目,API应用的是OAuth2.0协议授权,并且采用的是简化模式(implicit grant type)。所以最近学习了一下该协议,并尝试用Jmeter模拟该授权方式的处理流程,以改进自动化测试脚本。

   本文主要分为三个部分:1、简述OAuth2.0协议中的简化模式授权方式;

              2、通过在浏览器上抓包,分析获取授权的过程中经历了什么;

              3、尝试用Jmeter模拟整个授权过程,获取授权令牌。

一、OAuth2.0协议简述

OAuth 2.0定义了四种授权方式。博主这里只介绍简化模式。有兴趣了解该协议全部内容的同学可以参考本文末的参考文章。

授权过程中参与的四种角色:

  • 资源所有者(Resource Owner):对资源具有授权能力的人。即用户。
  • 第三方应用(Client):获得资源所有者的授权后,就可以去访问资源所有者的资源。
  • 资源服务器(Resource Server):存储资源,并处理对资源的访问请求。
  • 授权服务器(Authorization Server):它认证资源所有者的身份,为资源所有者提供授权审批流程,并最终颁发授权令牌(Access Token)。

请注意,为了便于协议的描述,这里只是在逻辑上把授权服务器与资源服务器区分开来;在物理上,AS与RS的功能可以由同一个服务器来提供服务。

简化模式的基本工作流程如下:用户被请求授权应用程序,然后授权服务器将访问令牌传递回用户代理,用户代理将其传递给应用程序。

Step 1: Implicit Authorization Link

使用简化模式授权类型,用户会得到一个授权链接,它会从API来请求获取令牌(即:token)。授权链接如下所示:

http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com

对授权链接的各部分介绍:

  • http://10.10.28.141:9999/uaa/oauth/authorize:API授权端点
  • client_id=cmop:应用程序的客户端ID(API用来标识应用程序)
  • redirect_uri=http://example.com:当令牌颁发之后,认证服务器把用户导向客户端指定的重定向URI
  • response_type=token:表示授权类型,固定值为token,表示请求授权令牌

Step 2: User Authorizes Application

当用户点击这个链接时,首先要登录到服务器验证身份(除非已经登录过),然后服务器会提示用户进行授权或拒绝第三方应用使用他们的账户。

Step 3: User-agent Receives Access Token with Redirect URI

如果用户同意授权,授权服务器将用户导向客户端指定的“重定向URI”,并在其中携带一个包含访问令牌的URI片段,看起来像这样:

http://example.com/#access_token=b8c512ef-8083-4654-b71b-7bbe85b03d8d&token_type=bearer&expires_in=19062&scope=open

对重定向URI的各部分介绍:

  • access_token:表示访问令牌
  • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型
  • expires_in:表示过期时间,单位为秒
  • scope:表示权限范围

好了,后面提取令牌以及把令牌发回给应用程序的步骤就不展开了,我们只要了解到如何获取到授权令牌就可以了,接下来访问服务器资源的时候,在请求API的requests中带入令牌参数即可。

二、浏览器抓包过程

1、在浏览器中使用授权链接发起申请令牌请求

http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com

  (1)Firefox浏览器,打开Firebug,输入授权链接发起请求,如下图:

    从图上可看出,我发起请求后,抓到6条GET请求,前两条是我们需要关注分析的数据,后面四条都是在请求页面元素所以不做关注:

      • 第一条请求:GET请求授权链接,返回状态码为302,表示请求链接被暂时性重定向;
      • 第二条请求:GET请求暂时性重定向的链接,即跳转到目前的页面,其URL为http://10.10.28.141:9999/uaa/login.html

    (2)接下来我们看一下前两条requests中的具体信息,如下图:

从图上可以看出,发起第一个GET请求(即授权链接),在其响应头信息(Response Headers)中的Location字段标明了接下来浏览器将重定向的地址;而且还在其中返回一个Set-Cookie字段;

再来看第二个请求,他的请求头信息(Request Headers)中包含一个参数Cookie,该值与上面的Set-Cookie字段的值相同。

  注意:我们把这里的Set-Cookie和Cookie的值起个名字,叫做JSESSIONID_1,方便和后面的cookie值进行区分。

2、用户同意进行授权操作

http://10.10.28.141:9999/uaa/login.html

  (1)在前一步的操作中,我们进行到浏览器跳转到暂时性重定向的页面,等待用户输入账号密码验证身份,然后进行授权。

    我们首先输入正确的用户名密码,通过验证,查看浏览器会发出什么请求:

    从图上可看出,我在输入用户名密码后,抓到3条请求,并且浏览器跳转到指定的重定向URI,而且可以在该链接中看到服务器返回来的access_token参数:

      • 第一条请求:POST请求,向服务器提供用户名密码参数,服务器验证用户身份通过后,跳转回申请授权链接;
      • 第二条请求:GET请求,再次向服务器请求申请授权令牌(此时已经得到用户的授权),服务器会颁发令牌,认证服务器把用户导向客户端指定的重定向URI;
      • 第三条请求:GET请求,重定向的URI,并且其中包括访问令牌access_token

(2)接下来我们看一下request中的具体信息:

      • POST请求:请求头信息中传入的cookie参数,与第一个步骤中获取的JSESSIONID_1值一模一样。响应头信息中返回的Set-Cookie值记录为JSESSIONID_2;
      • 第一个GET请求:再次跳转到授权链接向服务器发起请求,此时请求头信息中传入的Cookie参数是JSESSIONID_2,响应头信息中的Location字段包含令牌;
      • 第二个GET请求:我没有截他的图,因为他只是最终认证服务器把用户导向的重定向URI。而我们已经拿到token的数据了。

总结:从用户在浏览器输入授权链接到最后浏览器返回给我们access_token的过程中,由于其中包含暂时性重定向的地址,所以浏览器自动进行过很多跳转。需要我注意的只有两个请求,第一个是GET请求授权链接,浏览器会自动跳转到用户身份验证页面,并保存一个cookie(我叫它验证cookie);第二个就是POST请求用户认证连接,传入用户名和密码参数,并带入验证cookie,服务器验证用户身份后再返回另一个cookie(我叫它授权cookie),也保存在浏览器中,然后自动跳转到授权链接,此时传入授权cookie,服务器即颁发正确的令牌给用户~~

三、Jmeter模拟获取令牌

通过前两部分的分析,我需要发送两个请求即可。

GET http://10.10.28.141:9999/uaa/oauth/authorize?response_type=token&client_id=cmop&redirect_uri=http://example.com
POST  http://10.10.28.141:9999/uaa/login.html

请求一:

请求二:

执行测试:

结果里面会发现,第一个请求执行没问题。但是第二个请求最后没有重新跳转回授权链接,更别提Response headers里面会有服务器颁发的令牌了!!

问题肯定是出在第一个GET请求的cookie没有传入POST请求,我翻了翻Jmeter的官方文档试图找到什么方法能够传递cookie这个参数,很快我就找到一个跟cookie相关的配置元件----前方高能预警!!!!!

HTTP Cookie Manager(HTTP Cookie管理器)

长话短说,我把这部分的重点直接从官网翻译过来如下:

——cookie管理器主要有两个功能

  • 它可以像浏览器一样保存并发送cookies:如果你的http请求的响应中包含一个cookie,那么Cookie Manager就会自动保存这些Cookie并在所有后续请求该站点的请求中使用这个Cookie的值。对Jmeter来说,每个线程都有自己的“cookie存储区域”。(注意:这样的cookie不会在Cookie Manager中展示给用户,但是用户可以使用监听器“查看结果树”来查看)
  • 用户可以手动添加cookie到Cookie Manager,这种方式添加的cookie会被Jmeter的所有线程共享。

从上面这段话可以得出,我的需求是第一种~也就是只需要在线程内添加一个Cookie Manager配置元件即可。

1、添加HTTP Cookie 管理器

2、执行测试

bingo~~~~~~~

access_token所在的URI正确获取到,POST请求中也传入了cookie.

注:如果在查看结果树中没有看到cookie的值,请检查Jmeter的/bin目录下jmeter.properties文件中CookieManager.save.cookies的值是否设置为true

参考资料:

OAuth2.0

http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Jmeter

http://jmeter.apache.org/usermanual/component_reference.html#HTTP_Cookie_Manager

接口测试工具-Jmeter使用笔记(八:模拟OAuth2.0协议简化模式的请求)的更多相关文章

  1. 接口测试工具-Jmeter使用笔记(一:运行一个HTTP请求)

    博主自从毕业从事软件测试行业距今一年半时间,大多数时间都在跟各种API打交道,使用过的接口测试工具也有许多,本文记录下各工具的使用心得,以及重点介绍我在工作中是如何使用Jmeter做测试的,都是在wi ...

  2. 接口测试工具-Jmeter使用笔记(六:从文本读取参数)

    使用场景:测试一个接口并发处理数据的能力,并且每次请求传入的参数都要不同. 解决方法--- CSV Data Set Config 列举一个实例,步骤中会侧重读取参数操作的说明,其他有疑问的步骤请查阅 ...

  3. 接口测试工具-Jmeter使用笔记(三:管理请求服务器信息和Headers参数)

    如果使用Jmeter同时执行多个http请求任务,就需要创建多个HTTP取样器,每一个取样器都来手动填写服务器信息和端口号,会非常消耗时间. 解决方法:Jmeter之HTTP请求默认值 1.添加方式 ...

  4. 接口测试工具-Jmeter使用笔记(五:正则表达式提取器)

    (正则表达式提取器是Jmeter关联中的一种)使用场景: 有两个HTTP请求,请求A的返回数据中有一个字段“ABCD”,该字段要作为请求B的入参. 1.添加方式 请求A上右键-->后置处理器-& ...

  5. 接口测试工具-Jmeter使用笔记(九:跨线程组传递变量)

    使用场景: 请求API需要授权令牌,但是授权令牌只需要获取一次,即可调用服务器上其他业务接口. 所以我想要把授权操作放在单独的一个线程,业务流放在其他线程. 这就需要我把从授权线程获取的令牌传入业务流 ...

  6. 接口测试工具-Jmeter使用笔记(四:响应断言)

    Jmeter中断言的类型有许多,我不在这里一一列举,只说下我用到的---响应断言. 作用:一个HTTP请求发出去,怎么判断执行的任务是否成功呢?通过检查服务器响应数据,是否返回预期想要的数据,如果是, ...

  7. 接口测试工具-Jmeter使用笔记(二:GET/POST请求参数填写)

    举例来说 我的被测系统API的http请求涉及到GET/POST/PUT/DELETE四种.请求传参可分为两种: GET请求 http://请求路径/Ecs-duHc0U4E #该请求参数“Ecs-d ...

  8. 接口测试工具 Jmeter使用笔记(一:编写一个http请求)

    记录学习过程 一.安装Jmeter 1.JAVA环境 JDK下载地址http://java.sun.com/javase/downloads/index.jsp 配置系统变量: (1)JAVA_HOM ...

  9. 接口测试工具-Jmeter使用笔记(七:用户定义的变量)

    使用场景:一组API根据业务流程制作成测试脚本,想要移植到其他测试环境时,由于数据库发生了变更,有些初始化数据也相应发生了变化,例如环境地址.请求路径等等.博主甚至把服务器地址和接口的部分共同请求路径 ...

随机推荐

  1. 面试容易问到的Linux问题

    1.有没有使用过linux?用来干什么? Linux是一个长时间运行比较稳定的操作系统,我们一般会拿它作为服务器. 一下软件(redis等)没有软件包,需要在linux的C编译环境下编译得到软件包. ...

  2. springboot集成mybatis源码分析(一)

    本篇文章只是简单接受使用,具体源码解析请看后续文章 1.新建springboot项目,并导入mybatis的pom配置 配置数据库驱动和mybatis dependency <dependenc ...

  3. redis-hash操作

    hset(name, key, value) # name对应的hash中设置一个键值对(不存在,则创建:否则,修改) # 参数: # name,redis的name # key,name对应的has ...

  4. Hdu 1022 Train Problem I 栈

    Train Problem I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. 关于CentOS

    dd if=/dev/cdrom of=centos72.iso 自动挂载镜像: vi /etc/fstab /root/centos72.iso   /mnt/cdrom   iso9660  de ...

  6. Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  7. 《学习之道》第八章孤军奋战or组队合作

    孤军奋战与组队合作:别再苦思冥想,拖延行为需要差别对待 对拖延我得提一个小建议,你要暂时把自己与那些会干扰你的人和事隔离开.自己到一个房间里去,或者去图书馆,这样就没什么事能让你分心了. 如果一门课让 ...

  8. spark MLlib DataType ML中的数据类型

    package ML.DataType; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaRDD; im ...

  9. .net core 设置访问静态资源

  10. Intervals 差分约束

    题意:给定n个区间[Li,Ri]以及n个整数vi. 现在要有一个集合,使得这个集合和任意[Li,Ri]都有 至少 vi个元素相同. 问这个集合最少要几个元素. 定义S(x) 表示[1,x]中选择的元素 ...