隐式模式
OIDC除了授权码模式,还有隐式模式,即基于token的登录。该模式常结合移动应用或 Web App 使用。
OIDC 隐式模式不会返回授权码 code,而是直接将
access_token和id_token通过 URL hash 发送到回调地址前端,后端无法获取到这里返回的值,因为 URL hash 不会被直接发送到后端。
OIDC配置
我们仍以授权码模式中提到的这张图为例:

隐式模式不需要配置App Secret,但开启该模式后,需要保证JWKS可用,有两种指定方式:
JWKS JSON文件:
其中,JWKS URL可以从服务发现地址中获取。
OIDC使用
获取Token
获取Token有两种方式:id_token Flow和登录接口。
id_token Flow
以Authing为例,构建如下 id_token flow URL。
访问后,进入登录页,输入账号密码登录。
登录成功后,将跳转到如下链接:
将 access_token 保存到客户端使用,例如:local storage。
登录接口
下面是Authing用账户密码登录的HTTP请求,详情可参考Authing的SDK。
Fireboom官方也开源一个简单的OIDC服务,当前仅支持隐式模式,详情请查看:fb-oidc
使用Token
假设,有如下OPERATION,使用 @fromClaim 指令修饰,意思是根据当前登录用户的UID,查询待做事项列表:
其将被编译为如下REST API,请求如下:
工作原理
接下来,我们学习下OIDC协议隐式模式的工作原理。
正常流程

该时序图有3个主体:客户端、Fireboom服务器、OIDC供应商 authing。
1.客户端到OIDC(Authing)
在客户端构造下述URL,跳转到Authing授权端点。
2.跳转到OIDC登录页
若用户未登录,则跳转到authing的登录页,支持账户密码、手机验证码,甚至是社交登录,如微信、QQ等。

3.OIDC跳转到客户端
登录成功后,authing再跳转到客户端回调地址上,同时携带授权码access_token和id_token。
和授权码模式不同这里拿到的不是code,且此时未经过飞布服务。
4.客户端保存令牌
客户端保存access_token及expires_in ,供下次使用,一般存储到local storage中。
5.客户端获取OIDC用户
客户端使用access_token,访问OIDC的用户信息端点,获得当前用户。
总结一下,1-5步骤,都不需要飞布服务参与,完全可以由客户端和OIDC服务器完成。
和授权码模式最大的不同是,隐式模式不需要client secret,也不需要使用 code 换 token,更无需请求 token 端点,access_token 和 id_token 会直接从授权端点返回。
6.客户端请求Fireboom API
客户端请求Fireboom API时,携带如下请求头 ,示例见 使用Token
7.Fireboom校验令牌
Fireboom 根据 配置的JWK公钥 验签access_token。该过程不需要OIDC服务参与,因此也意味着OIDC中的Token黑名单不会生效。需要使用Fireboom的 网关钩子 自行实现黑名单。
8.客户端获取Fireboom用户
若Fireboom服务未缓存用户信息,则会用access_token请求OIDC用户端点,获得用户,同 隐式模式。
9.Fireboom调用钩子
Fireboom 调用授权钩子,在钩子中修改用户信息,返回后,由Fireboom 缓存用户信息,详情见 身份验证钩子,并返回用户信息到客户端。
简化流程
刚刚介绍的,无论是授权码模式还是隐式模式都需要使用OIDC原生的登录页。那如果想自定义登录页,又该如何做呢?
其实只要基于隐式模式稍作调整,就能支持该需求。我们知道,隐式模式的本质是获得access_token,然后用其请求接口。
那如果OIDC服务提供了根据账户密码获得accest_token的接口,是不是就可以供我们在自己编写的界面中直接调用了呢?

我们仍以authing为例,上述流程图就展示了该过程。
1.调用登录接口
通过post请求,输入账户、密码或手机号、验证码,获得acces_token。不同OIDC供应商有对应实现,详情可参考其文档。例如前文中提到的 登录接口
2.客户端存储令牌
客户端存储 acces_token,供后续使用。
其他流程没有变化,同 正常流程 的步骤6-9。
总结
总结一下,隐式模式的流程更加简洁。
由于其不依赖cookie,所以适用范围更广,不仅支持浏览器,也能支持类似微信小程序或者原生APP。
但缺点是安全性不足,因为其直接将access_token泄露给了客户端。
最后更新于
这有帮助吗?