-
OAuth 与Passport
- Session 技术都是结合客户端 Cookie 来实现
- 从后端剥离出去的前端应用无法通过 API 请求从客户端传递 Cookie 及 CSRF Token 到后端
- 即Api请求方式无法通过Session实现用户认证,客户端负责维护应用状态,而服务端维护资源状态
-
前后端分离的API认证
- 用户认证信息存储在后端网站,当前端需要访问认证资源时,通过后端应用授权的方式访问
- 授权的前提是前端应用在后端应用注册过,否则不能授权,只有用户允许授权,才可以访问认证资源
- 对于passport建立的oAuth服务,通常是用命令行
passport:client
注册第三方应用- 通常用户的资源在oauth服务器上
- oauth根据用户id及其用户要授权的应用方生成
CLIENT_ID
及CLIENT_SECRET
- 后续用户在第三方首次访问时,只需通过
CLIENT_SECRET
,来得到令牌 - oauth方通过令牌可辨别用户及要授权的资源,给予第三方应用
- 对于passport建立的oAuth服务,通常是用命令行
- 令牌访问认证 API
- 确认身份,即必须备案,有记录可查的用户信息,以此维护用户的状态及数据信息
-
常用的认证的类型
- Bearer Token
- Basic Auth
- Digest Auth
- OAuth 1.0/2.0
- Hawk Authentication
- AWS Signature
-
passport流程
- 在
storage
目录下生成oauth公私钥php artisan passport:install
- 修改认证模型类,使用
Laravel\Passport\HasApiTokens
Trait - API认证路由
Laravel\Passport\Passport::routes()
,路由前缀为/oauth
- 修改配置文件,将API认证驱动由token修改为passport
- 在
单页面应用API认证(Cookie授权令牌)
- 场景
- API 认证只用于客户端 JavaScript 与后端接口的交互
- 单页面应用api认证
- 在web路由组中新增
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
中间件- 在用户首次通过
Web
页面登录表单登录后在Cookie
中设置一个Token
- 在用户访问需要认证的 API 接口时,走
auth:api
认证中间件,api认证驱动是 passport - 在底层根据
api
参数,针对API
接口认证会通过Laravel\Passport\Guards\TokenGuard
获取认证信息
- 在用户首次通过
- 在web路由组中新增
TokenGuard
看守器- 优先从包含
Bearer Authentication
请求头中获取Token
信息 - 若无上,则从cookie中获取
laravel_token
,即bearerToken > passport::cookie
- 优先从包含
移动端应用(密码授权令牌)
- 创建移动端应用
- 在后端应用(passport安装oauth服务的服务器)中注册移动端应用
- 配置移动端应用
- 在移动端应用填写登录表单进行登录
- 后端应用授权移动端认证
- 令牌有效期
passport
方法- 设置有效期
tokensExpireIn
refreshTokensExpireIn
- 刷新令牌 在
oauth/token
路由请求中指定操作类型为refresh_token
来刷新令牌
- 设置有效期
- 应用场景
- 公司自有系统之间如何通过用户凭证获取密码授权访问认证 API 接口
第三方应用(授权码获取令牌)
- 前提
- 第三方应用已知
client_id,
与client_secret
- 后端用到passort的
auth:api
中间件
- 第三方应用已知
- 应用场景
- 支持第三方应用户接入获取认证信息
- 密码授权获取令牌缺点
- 若第三方应用不可信,把用户名密码信息记录下来,用户信息会被泄露风险
- 授权码流程
- 在后端系统注册第三方应用
- 配置第三方应用
- 编写第三方应用路由和控制器
- 测试通过授权码获取令牌
开放平台(客户端令牌)
- 客户端凭证令牌
- 授权方式不需要走典型的登录或授权重定向流程,免去了跳转认证、重定向的复杂流程
- 应用场景 适用于机器与机器之间的接口认证
- 逻辑原理
- 后端需用到passport自带的
CheckClientCredentials
中间件,通常别名为client - 在客户端应用中通过分配的 APP ID 和 APP SECRET 获取授权令牌,最后拿着这个令牌访问后端认证接口
- 后端需用到passport自带的
- 客户端令牌
- 默认长期有效
- 流程
- 在开放平台注册客户端应用
- 在客户端定义路由与控制器
- 访问开放平台认证接口
沙箱测试(私人访问令牌)
- 授权特点
- 用户给自己颁发访问令牌,无需授权码,亦无登录凭证
- 应用于用户测试,平台体验
- 即直接在后端(oauth服务器)上运行,可以管理用户所有令牌
passport
流程- 后端系统注册测试应用
passport:client --personal
- 获取访问令牌
- 后端认证的用户模型类必须使用了
HasApiTokens Trait
- 路由,控制器使用模型
$user->createToken('Users')->accessToken
- 后端认证的用户模型类必须使用了
- 访问认证接口
- 生成的令牌记录可以在 oauth_access_tokens 数据表中找到,私人访问令牌默认是长期有效的。
- 后端系统注册测试应用
隐式授权令牌
- 隐式授权特点
- 不需要获取授权码,就可以将令牌返回给客户端,极度不信任第三方能够安全存储令牌
- 适用于同一个公司自有系统之间的认证
- 特别适合 客户端凭证不能被安全存储的移动应用或 JavaScript 应用
- 使用流程
- 后端设置
- 在后端系统
AuthServiceProvider
的 boot 方法中调用 - 启用隐式授权令牌
Passport::enableImplicitGrant();
- 在后端系统
- 前端设置
- 后端注册后,前端CLIENT_ID 和 CLIENT_SECRET 配置
- 前端配置相应的路由,控制器
- 后端设置
- 特色
- 确认授权之后,会根据当前url中的redirect_url跳转,并在url中以#锚点形式附加access_token令牌
- 通过以锚点形式返回
access_token
的原因是不会把它们发送到服务器 - 确保只有客户端才能解析上述锚点里的参数(你可以无论通过 Laravel 还是PHP 都解析不到 access_token)
- 应用场景
- 隐式授权令牌也可以用于单页面应用认证 API 接口访问
- 在某些安全性要求比较高的场景下,不能在客户端存储令牌信息,通常使用此种获取令牌的方式访问后端认证接口
令牌作用域
- API认证方式小结
- API 接口认证本质是获取授权令牌,然后在请求中带上这个令牌对认证接口进行访问的过程。
- 获取令牌的不同实现方式,产生所谓的各式令牌
- 令牌作用域
- 对令牌的授权作用域进行限制
- 理由
- 不是认证接口的所有返回数据都可以通过该令牌进行访问
- 不是所有接口都需要通过该令牌进行访问
- 是否能够获取对应数据或访问对应接口取决于用户的主动勾选
- 令牌作用域使用实现流程
- 配置后端应用
- 定义API认证的令牌作用域
- 在
Passport::tokensCan
定义 API 认证的令牌作用域,AuthServiceProvider
之boot方法
- 在
- 在
$routeMiddleware
属性中引入两个中间件'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class
,'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class
,scopes
用于检查传入令牌作用域是否包含所有指定中间件参数, 全选scope
用于检查传入令牌作用域是否包含任意指定中间件参数,中间件参数不定项选择
- 定义API认证的令牌作用域
- 配置后端应用
- 令牌作域特点
- 本质上是用路由中间件参数标记,认证时会检查令牌上的作用域是否与中间件上指定的标记域相符
- 与用户数据关联区分标志,使用
$user->tokenCan('all-user-info')
形式