鉴权与授权
概述
IoT系统使用OAtuh2协议进行接入与授权操作。原生的OAuth2支持Authenticatoin Code,Password,Client Credentials,Implicit四种授权模式。IoT系统扩展了OAuth2协议,以支持更多的接入方式,如基于微信登录的js_code模式,基于短信或邮件验证码的captcha模式。具体来讲,IoT系统支持以下授权模式:
Js Code
适用于微信小程序接入Captcha
适用于使用短信或者邮件验证码进行接入Password
适用于传统的用户名和密码登录Client Credentials
适用于终端设备接入Refresh Token
适用于接入后刷新验证码
授权
鉴权API统一接口为
POST /api/v1/oauth/token?grant_type=${granty_type}¶ms
params随着鉴权模式的不同而不同,可能用到的参数如下表:
参数 | 含义 | 备注 |
---|---|---|
grant_type | 授权类型 | 枚举值,可选js_code/captcha/password/client_credentials/refresh_token |
client_id | 授权的client id | client id应当事先注册在授权服务器中 |
client_secret | client 密钥 | client secret应当事先存储于授权服务器 |
username | 用户名 | 当grant_type为password模式时,需要该字段 |
password | 用户密码 | 当grant_type为password模式时,需要该字段 |
code | 代码 | 当grant_tyep为js_code或captcha时需要该字段提供微信登录代码或者验证码 |
refresh_token | 刷新令牌 | 当grant_type为refresh_token时,需要该字段提供刷新令牌 |
scope | 授权范围 | OAuth2协议要求的必填字段,可填任意非空值 |
鉴权成功后会返回如下类似的鉴权结果:
{
"access_token": "07dc71f9-89b0-45e2-8f62-e9924d664fb3",
"token_type": "bearer",
"refresh_token": "92e70c5d-7974-4b9c-85a0-9bfe67313ff6",
"expires_in": 23318,
"scope": "all"
}
响应JSON字段的含义如下:
字段 | 含义 |
---|---|
access_token | 用于后续访问受保护的api的token |
token_type | token的类型,上文中的token是bearer类型 |
refresh_token | 更新token,access_token有一个有效期,当access_token过期而refresh_token未过期时,可以使用refresh_token快速获取新的access_token,详见下文的refresh_token接入模式 |
expires_in | access_token的过期时间,单位秒 |
scope | OAuth2协议规定的授权范围,与请求scope参数值保持一致 |
Js Code接入
使用场景
Js Code接入模式主要用于消费者使用微信小程序进行基于微信的OAuth2登录,以避免用户输入用户名和密码.
请求示例
POST /api/v1/oauth/token?grant_type=js_code&client_id=${client_id}&client_secret=${client_secret}&code=${code}&scope=all
`
注意: 一般来讲js_code模式中的code值只能通过微信拉取.
Password 模式接入
使用场景
Password接入可用于用户基于App或者网站通过用户名和密码登录.
请求示例
POST /api/v1/oauth/token?grant_type=password&client_id=client_id&client_secret=client_secret&username=username&password=password&scope=all
`
Client Credentials 模式接入
使用场景
Client Credentials模式只对客户端如App或者浏览器进行验证,适合不需要用户登录的场景.
请求示例
POST /api/v1/oauth/token?grant_type=client_credentials&client_id=client_id&client_secret=client_secret&scope=all
`
Captcha 模式接入
使用场景
Captcha模式适用于使用短信或者邮件验证码而非密码的场景进行用户接入.
请求示例
POST /api/v1/oauth/token?grant_type=captcha&client_id=client_id&client_secret=client_secret&code=code&scope=all
`
Refresh Token 模式接入
使用场景
Refresh Token模式适用于快速根据刷新token再次获得access_token.
请求示例
POST /api/v1/oauth/token?grant_type=refresh_token&client_id=client_id&client_secret=client_secret&refresh_token=refresh_token&scope=all
`
非url形式请求授权
鉴于将所有的请求参数附着于url导致url过长的问题,可通过将参数封装在请求头和表单中进行解决.
请求头
请求头使用basic方式对客户端信息进行认证,具体格式为
"Authorization": Basic+${space}+Base64(${client_id}:${client_secret})
即Authorization请求头的内容为Basic加空格再加上一段Base64编码,编码的内容为由英文冒号连接的client_id和client_secret字符串.
表单
除去client_id和client_secret的其他所有参数都可以放置到表单中,如下请求
post /api/v1/oauth/token?grant_type=password&client_id=${client_id}&client_secret=${client_secret}&username=${username}&password=${password}&scope=all
等价于如下请求
curl -X POST \
'/api/v1/oauth/token' \
-H 'Authorization: Basic RGV9aHViNm5gdGlvbmTsY2hpca==' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F grant_type=password \
-F username=${username} \
-F password=${password} \
-F scope=all
鉴权
对于IoT系统中的绝大部分API,都需要进行鉴权后才能访问,具体的鉴权方式分为两种
- 针对浏览器,可直接在URL的query param加上access_token,即:
access_token可由前述鉴权模块获取.GET some/api?access_token=access_token
- 针对App或者命令行工具如wget/curl,需要加上如下HTPP请求头:
"Authorization": Bearer+${SPACE} + ${access_token}
注: 即Authentication的值是由字符串"Bearer"+空格+获取的access_token组成
如果未携带有效access_token,将会返回如下提示:
{
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
}