OAuth2是一个安全框架,控制着程序受保护部分的准入,主要是控制不同的客户端如何来调取API,保证它们在请求相应资源的时候有相应的权限。

Laravel Passport是一个强大的Oauth2服务实现,使用Passport往往已经足以应对我们日常API开发中的各种需求,甚至说,大部分时候,我们只是用到了Passport的部分功能而已。也正因为其强大,所以理解和使用起来也有一定难度,而这其中,理解和熟悉oauth2相关的各种授权类型是关键,授权类型理解了,Passport也就没什么难的了。话不多说,一起来看看不同的授权类型都是怎么回事吧。

概念理解:

1. 客户端(Client)

指的是调取你程序API的那个应用,或者说终端,在Passport里创建客户端可以通过artisan命令来进行

php artisan passport:client

每一个客户端(client)都要有一个key, name, secret, redirect URI, user(程序创建者/所有者)

2. 资源拥有者(Resource Owner)

这个指的是客户端请求的那个API,其背后所对应资源(或者说数据)的所有者(user)

3. 资源服务器(Resource Server)

这个也就是我们的API,可以是不需要读取权限的公共数据,也可以是需要验证权限的私有数据。公共数据,或者说公开节点(endpoints),举个例子就是比如说搜索所有的tweets消息,或者说搜索微信文章,这不需要特别的权限,谁都可以搜。另一方面,假设说以某个用户的名义去发布(post)一个推特消息,发一个朋友圈,就需要来自这个用户的权限认证了。

4. 权限范围(Scope)

指的是获取特定数据,或者进行特定操作的权限(permission),可以在AuthServiceProvider使用Passport::tokensCan()方法来具体定义权限(scope)

Passport::tokensCan([
    'read-tweets' => 'Read all tweets',
    'post-tweet' => 'Post new tweet',
]);

5. 准入令牌(Access token)

当客户端程序想要取得某些受保护的数据时,就要传递一个准入令牌(Access token),以此来验证当前请求(request)。

授权类型(Grant Type)

授权(Grant),说白了就是从资源服务器获取准入令牌(Access token)的方式,也可以更通俗地说成颁发令牌(token)的方式。一共有五种授权方式,其中四种是用来获取令牌(Access token)的,另一个是用来刷新、或者说重新创建一个已有令牌(token)的。

1. 认证码授权(Authorization Code grant)

这是最常见的一种类型,说白了就是第三方登陆,也即当第三方的程序想着获取我们这边的受保护信息,这个第三方程序必须得获得我们这边用户的认证授权。更直白的,当第三方的客户端想着调用我们这边的用户信息,来登陆他们的网站,那么它得获得这个用户的认证授权。

大部分的流行API都会实现这一种授权类型。比如说Facebook,当用户想着登陆我们的网站,我们可以先把用户重定向到Facebook,让他先登陆Facebook,然后Facebook会询问这个用户,是否同意我们的这个网站获取他在Facebook网站上的用户信息呢?用户点了授权以后,就又会被重定向回我们的网站,同时呢会附上一条认证码(Authorization Code),然后呢我们的网站要利用这个认证码(Authorization Code),再去向Facebook换取准入令牌(access token),有了准入令牌以后,我们才可以进一步获取该用户的详细信息。

这整个过程,又通常被叫做“三条腿的Oauth”(3-Legged OAuth),当然了,还有“两条腿的Oauth”(2-Legged OAuth),也就是接下来的这一种。

2. 模糊授权(Implicit Grant)

Implicit,是模糊、含蓄、不具体指明的意思,这里呢译作模糊。模糊授权(Implicit Grant),跟上面的认证码授权(Authorization Code)类似,不同的是,我们的资源服务器,返回的直接就是准入令牌(access token),而不是认证码(authorization code)。因此呢,就不是需要三步才能获得token。“三条腿的Oauth”被证明是更好的,可能你会纳闷,既然更好,还要这个“两条腿”的模糊授权(Implicit Grant)干啥?

认证码(authorization code)授权,需要的是一个服务器向另一个服务器(Facebook)发起请求,获取认证码,然后交换准入令牌。但如果我们面前是一个JS的APP,它只是一个浏览器端,那么就很难获取了认证码再交换准入token了,这种情况下,我们就需要用到这种模糊授权(Implicit Grant)

3. 用户密码授权(Resource Owner Password Credentials Grant)

Resource Owner == User

这种类型适合于我们信任的客户端,比如我们自己的手机APP来访问网站数据,这个时候,客户端直接使用用户的登陆密码信息请求资源服务器,服务器直接返回准入令牌(access token)。

4. 客户端资质授权(Client Credentials Grant)

这个适合于访问API的这个客户端,本身就是相应数据的所有者的时候,这期间不涉及到用户的互动,说白了就是纯粹的机器与机器之间的沟通。比如说一个App想着向用户显示一个对话框,或者储存一些跟这个App相关的数据到我们的资源服务器上。

5. 令牌刷新授权(Refresh token grant)

当服务器生成一个令牌(token)的时候,同时也会设置一个token的有效期,或者说失效期。令牌刷新授权(Refresh token grant)就是当我们的token过期了,我们得需要将其刷新一下,重新生成一个。这种情况下,验证服务器会在生成准入token的同时发送一个refresh token(刷新令牌),好后期用来生成一个新的token。需要注意的是,这个流程并不适合于模糊授权(Implicit Grant)。