
# 配置OAuth管理
在AstroZero中，可通过配置OAuth管理第三方接入鉴权。AstroZero采用OAuth 2.0协议进行接入认证。第三方系统在调用AstroZero业务接口前，需要在AstroZero上进行鉴权注册，获取接入客户端ID、密钥等鉴权信息，才能实现调用AstroZero业务接口。
#### 使用场景
AstroZero提供了"客户端模式"和"授权码模式"两种授权模式进行OAuth鉴权。
- 客户端模式 通过该模式获取的access-token，用于在调用API接口时进行鉴权，使用时需在请求消息头上设置"access-token"。
  图1客户端模式   
  ![](https://support.huaweicloud.com/usermanual-astrozero/zh-cn_image_0000001960127769.png "点击放大") 
- 授权码模式 通过该模式获取的access-token，只能用于在获取用户信息时进行鉴权，使用时需在请求消息头上设置"Authorization: Bearer \*\*\*"。
  图2授权码模式   
  ![](https://support.huaweicloud.com/usermanual-astrozero/zh-cn_image_0000001932889064.png "点击放大") 
 
#### 客户端模式接入认证
1. 参考[登录管理中心](https://support.huaweicloud.com/usermanual-astrozero/astrozero_06_2092.html)中操作，登录AstroZero管理中心。
2. 创建机机用户账号。
   
   机机用户只能通过OAuth客户端模式鉴权，登录AstroZero。
   1. 在左侧导航栏中，选择"用户管理 \> 用户"，单击"新建"。
   
   2. "用户类型"选择为"机机用户"，设置其他用户信息，单击"保存"。
      图3新建机机用户   
      ![](https://support.huaweicloud.com/usermanual-astrozero/zh-cn_image_0000001933048444.png "点击放大") 
    
   
   
3. 在左侧导航栏中，选择"系统管理 \> OAuth"，单击"新建"。
4. 授权类型选择"客户端模式"，参照[表1]设置其他参数后，单击"保存"。
   
   ![](https://support.huaweicloud.com/usermanual-astrozero/public_sys-resources/note_3.0-zh-cn.png)
   - 每个OAuth都有特定的用途，建议为不同的第三方系统单独新建一个OAuth。
   
   - OAuth关联的用户需要具有访问相关API的权限，否则会因为权限问题导致回调失败。
    
    表1新建客户端模式参数说明 
   | 参数     | 参数说明                                                                                                                     |
   |:---|:---|
   | 名称     | 新建接入认证的名称，用于标识待接入的第三方系统名称。                                                                                               |
   | 授权类型   | 对第三方系统进行OAuth 2.0接入认证的授权类型，选择"客户端模式"。                                                                                    |
   | 用户     | 选择[2]中创建的机机用户，当第三方鉴权成功后，将获取和此用户相同的权限。                  |
   | 登录IP范围 | 是否指定登录IP范围，勾选后，表示只有在指定范围内的IP地址才可以接入AstroZero。                                                                            |
   | 起始地址   | 起始IP地址，必须为合法的IPv4地址，且必须小于等于结束地址。 勾选"登录IP范围"后，才会显示该参数。     |
   | 结束地址   | 结束IP地址，必须为合法的IPv4地址，且必须大于等于起始地址。 勾选"登录IP范围"后，才会显示该参数。 |
   | 描述     | 接入认证的描述信息。                                                                                                               |
      
   
   
5. 在OAuth管理列表中，单击该鉴权所在行的![](https://support.huaweicloud.com/usermanual-astrozero/zh-cn_image_0000001960127773.png)，下载密钥文件到本地，从中获取鉴权的客户端ID和鉴权密钥取值。
   
   下载到本地的密钥文件名为"*认证名称* .csv"，文件中包含如下参数：
   - username：[4]中选择的用户。
   
   - client_id：鉴权的客户端ID。
   
   - client_secret：鉴权的密钥。
    
   
   
6. 根据鉴权ID和鉴权密钥调用接口"/baas/auth/v1.0/oauth2/token"，获取access_token。
   
   表2接口基本信息 
   | 接口名称  | 接口路径                         | 接口协议  | 接口方法 |
   |:---|:---|:---|:---|
   | token | /baas/auth/v1.0/oauth2/token | HTTPS | POST |
      
   表3请求参数说明 
   | 参数名称          | 类型     | 必选（M）/可选（O） | 参数位置 | 参数含义                             | 值                                                                            |
   |:---|:---|:---|:---|:---|:---|
   | grant_type    | String | M           | Body | 授权模式，对应OAuth2.0中的grant_type字段的值。 | 配置为client_credentials，即客户端模式。                                                |
   | client_id     | String | M           | Body | 鉴权的客户端ID。                        | 配置为[5]中获取的值。 |
   | client_secret | String | M           | Body | 鉴权密钥。                            | 配置为[5]中获取的值。 |
   | redirect_url  | String | O           | Body | 重定向URL。                          | 根据实际需求配置                                                                     |
   | locale        | String | O           | Body | 语言。                              | en_US                                                                        |
      
   样例：
   通过Curl请求模拟接口调用：curl -i -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=client_credentials\&client_id=*鉴权ID值* \&client_secret=*鉴权密钥值* ' https://*域名*/baas/auth/v1.0/oauth2/token
   响应如下：
   ```
   {
       "access_token": "ACCESS_TOKEN",
       "expires_in": 7200,
       "token_type": "Bearer"
   }
   ```
   请记录获取的access_token，后续第三方需要通过该access_token访问业务接口。
   
   
7. 第三方调用的业务接口，这里以调用自定义接口"queryEquipments"（电梯设备查询接口）为例进行说明。 
   1. 通过下面的REST接口调用"queryEquipments"。
      ```
      https://域名/service/syw__Elevator/1.0.1/queryEquipments
      ```
      *其中"* *域名* *"替换为对外提供的开发态域名"appcube.cn-north-4.huaweicloud.com"，"* *service/syw__Elevator/1.0.1/queryEquipments* *"为自定义接口URL。*
      
   
   2. （可选，调用公共接口时，当需要做CSRF校验时，请执行该步骤），调用接口*"https://AstroZero域名/u-route/baas/sys/v1.0/csrf/get"* 获取"csrf-token"值，返回的result取值即为"csrf-token"值。
      调用该接口时，需要在请求消息头上设置"access-token"，即[6]中获取的值。
      
   
   3. 在请求消息头Request Header中增加"access-token"："*ACCESS_TOKEN* "、"Content-Type":"application/json"、"csrf-token"："*上一步result取值*"。
   
   4. 在请求消息体中，写入该接口的输入参数。
      ```
      {
          "equipmentSn": "001"
      }
      ```
      
   
   5. 调用成功，返回输出结果。
      ```
      {
        "interviewId": "002N000000MJ77KcFGwC",
        "outputs": {
          "Equipments": [
            {
              "HW__equipmentBrand__CST": null,
              "HW__equipmentModel__CST": null,
              "HW__equipmentSN__CST": "9996660001",
              "HW__fullAddress__CST": "",
              "HW__installationDetailAddress__CST": null,
              "HW__installationSiteArea__CST": "",
              "HW__installationSiteCity__CST": "",
              "HW__installationSiteProvince__CST": "",
              "HW__latitude__CST": "",
              "HW__longitude__CST": "",
              "createdBy": "10gd000000MEGPaz7P16",
              "createdBy.__objectType": "User",
              "createdBy.name": "test",
              "createdDate": "2018-12-19 06:39:29",
              "currencyIsoCode": "",
              "custom": true,
              "equipmentSn__CST": "9996660001",
              "fullAddress__CST": "",
              "id": "c000000000MFhgYMQtmq",
              "installedPackage": null,
              "isLocked": false,
              "lastModifiedBy": "10gd000000MEGPaz7P16",
              "lastModifiedBy.__objectType": "User",
              "lastModifiedBy.name": "test",
              "lastModifiedDate": "2018-12-19 06:39:29",
              "latitude__CST": "",
              "longitude__CST": "",
              "name": "荔枝苑10栋1单元1号",
              "owner": "10gd000000MEGPaz7P16",
              "owner.__objectType": "User",
              "owner.name": "test"
            },
            {
              "HW__equipmentBrand__CST": "",
              "HW__equipmentModel__CST": null,
              "HW__equipmentSN__CST": "3217890001",
              "HW__fullAddress__CST": "ssss",
              "HW__installationDetailAddress__CST": null,
              "HW__installationSiteArea__CST": null,
              "HW__installationSiteCity__CST": null,
              "HW__installationSiteProvince__CST": null,
              "HW__latitude__CST": null,
              "HW__longitude__CST": null,
              "createdBy": "10gd000000MEGPaz7P16",
              "createdBy.__objectType": "User",
              "createdBy.name": "test",
              "createdDate": "2018-12-18 12:49:46",
              "currencyIsoCode": "",
              "custom": true,
              "equipmentSN__CST": "3217890001",
              "fullAddress__CST": "ssss",
              "id": "c000000000METF70NiZk",
              "installedPackage": null,
              "isLocked": false,
              "lastModifiedBy": "10gd000000MEGPaz7P16",
              "lastModifiedBy.__objectType": "User",
              "lastModifiedBy.name": "test",
              "lastModifiedDate": "2018-12-21 07:34:06",
              "latitude__CST": "",
              "longitude__CST": "",
              "name": "A栋1单元1号",
              "owner": "10gd000000MEGPaz7P16",
              "owner.__objectType": "User",
              "owner.name": "test"
            }
          ],
          "total": "2"
        }
      }
      ```
      上述示例中，"HW"为命名空间名称，请以实际返回的结果为准。
      
   
   
   
   
 
#### 授权码模式接入认证
1. 参考[登录管理中心](https://support.huaweicloud.com/usermanual-astrozero/astrozero_06_2092.html)中操作，登录AstroZero管理中心。
2. 在左侧导航栏中，选择"系统管理 \> OAuth"，单击"新建"。
3. 授权类型选择"授权码模式"，参照[表4]设置其他参数后，单击"保存"。
   
   ![](https://support.huaweicloud.com/usermanual-astrozero/public_sys-resources/note_3.0-zh-cn.png)
   每个OAuth都有特定的用途，因此建议为不同的第三方系统单独新建一个OAuth。
    表4新建授权码模式参数说明 
   | 参数名   | 说明                                                                                                   |
   |:---|:---|
   | 名称    | 新建接入认证的名称，用于标识待接入的第三方系统名称。                                                                           |
   | 授权类型  | 对接第三方系统时进行的OAuth 2.0接入认证的授权类型，选择"授权码模式"。                                                             |
   | 重定向地址 | 当第三方系统访问时，会给该重定向地址返回授权码，第三方系统需要携带授权码、鉴权的客户端ID、鉴权密钥来调用接口获取access_token。后续第三方需要通过access_token获取授权用户信息。 |
   | 描述    | 认证的描述信息。                                                                                             |
      
   
   

4. 在OAuth管理列表中，单击该鉴权所在行的![](https://support.huaweicloud.com/usermanual-astrozero/zh-cn_image_0000001960287573.png)，下载密钥文件到本地，从中获取客户端鉴权ID和鉴权密钥取值。
   
   密钥只需创建一次，不需要重复新建。密钥文件中包含如下参数：
   - redirect_uri：为[3]中设置的重定向地址。
   
   - client_id：鉴权的客户端ID。
   
   - client_secret：鉴权密钥。
    
   
   
5. 获取授权码code。
   
   第三方系统访问获取授权码code的接口为"https://*域名* /baas/auth/v1.0/oauth2/authorize?response_type=code\&client_id=*鉴权ID值* \&redirect_uri=*重定向地址* "。如果第三方系统选择同意接受授权，认证服务器将浏览器重定向到之前第三方系统注册时指定的重定向地址，同时附带上授权码，即*重定向地址*/?code=授权码。
   若引导第三方系统打开页面时，提示"该链接无法访问"，请检查如下参数是否填写错误：
   - 鉴权ID值：为[4]中获取的鉴权客户端ID。
   
   - 重定向地址：为[3]配置的重定向地址。
   
   
   
   
6. 获取access_token。
   
   客户端收到授权码code，根据鉴权ID、鉴权密钥和授权码code在后端调用接口" https://*域名* /baas/auth/v1.0/oauth2/token"获取access_token。后续第三方需要通过access_token获取授权用户信息。
   表5接口基本信息 
   | 接口名称  | 接口路径                                     | 接口协议  | 接口方法 |
   |:---|:---|:---|:---|
   | token | https://*域名*/baas/auth/v1.0/oauth2/token | HTTPS | POST |
      
   表6参数说明 
   | 参数名称          | 类型     | 必选（M）/可选（O） | 参数含义                             | 值                                                                                 |
   |:---|:---|:---|:---|:---|
   | grant_type    | String | M           | 授权模式，对应OAuth2.0中的grant_type字段的值。 | 配置为authorization_code，即授权码模式。                                                     |
   | client_id     | String | M           | 客户端鉴权ID。                         | 配置为[4]中获取的值。   |
   | client_secret | String | M           | 客户端鉴权密钥。                         | 配置为[4]中获取的值。   |
   | redirect_url  | String | M           | 重定向地址。                           | 配置为[3]中获取的重定向地址。 |
   | code          | String | M           | 授权码。                             | 配置为[5]中获取的值。     |
   | locale        | String | O           | 语言。                              | en_US                                                                             |
      
   样例：
   通过Curl请求模拟接口调用：curl -i -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'grant_type=authorization_code\&client_id=*鉴权ID值* \&client_secret=*鉴权密钥值* \&redirect_uri=*重定向地址* \&code=*授权码* ' https://*域名*/baas/auth/v1.0/oauth2/token
   响应如下：
   ```
   {
       "access_token": "ACCESS_TOKEN",
       "expires_in": 7200,
       "refresh_token":"REFRESH_TOKEN",
       "token_type": "Bearer"
   }
   ```
   
   
7. （可选）刷新access_token。 
   access_token的有效期较短，例如[6]中获取的access_token，有效期是7200秒（即2小时），当access_token超时后，可使用refresh_token进行刷新。refresh_token有效期为30天，当refresh_token失效之后，需要用户重新授权。
   获取[6]中的refresh_token后，可使用如下链接获取access_token：
   https://*域名* /baas/auth/v1.0/oauth2/token?grant_type=refresh_token\&client_id=*鉴权ID值* \&client_secret=*客户端鉴权密钥* \&refresh_token=*REFRESH_TOKEN*
   
   
8. 获取授权用户信息。
   
   使用GET请求方法，调用"https://*域名*/u-route/baas/oauth/v1.0/userinfo"请求，获取授权用户信息。
   ```
   {
     "resCode": "0",
     "resMsg": "成功",
     "result": {
       "usrname": "test",
       "alias": "",
       "email": "test@example.com",
       "aboutme": "",
       "company_name": "name01",
       "photo": "",
       "address": "",
       "phone": "188XXXX8888",
       "country": "",
       "post_code": "",
       "province": "",
       "city": ""
     }
   }
   ```
   
   
 
#### 自定义OAuth2授权码模式接入鉴权
前面介绍了第三方系统在调用AstroZero业务接口前，如何配置接入鉴权。鉴权通过后，才能实现调用AstroZero业务接口。在AstroZero中开发的应用，也可以自定义OAuth2授权码模式接入鉴权。当应用配置鉴权后，只有通过鉴权的第三方系统才可以访问应用。
1. 参考[2]\~[4]获取鉴权ID"client_id"和鉴权密钥"client_secret"。
2. 在应用开发页面，通过自定义接口，给第三方接入调用，用于第三方系统获取授权码code。
3. 应用调用脚本API，判断第三方客户端的鉴权ID"client_id"和重定向地址"redirect_url"是否和注册接入鉴权时匹配。 
   如果匹配，则由AstroZero应用自定义接口，实现登录跳转和授权跳转。在授权完成后，再调用脚本API获取授权码code，并将需要展示给第三方的授权用户信息通过该API传给AstroZero，AstroZero会返回一个code。最后，应用重定向到"redirect_url"，并携带code。
   - 判断第三方客户端的鉴权ID"client_id"和重定向地址"redirect_url"是否和注册接入鉴权时匹配的API样例如下：
     ```
     // Here's your code.
     import * as oauth from 'oauth'
     let handle = oauth.getAuthorizeHandle()
     let clientDatas: oauth.clientDataFromApp = {
         redirect_uri: "http://10.26.30.68:14000/appauth/code",
         client_id: "bff4398905ee4a918722debec98b594c",
     }
     let pass = handle.checkURL(clientDatas)
     console.log(pass) //true
     if (pass){
     //判断是否登录，做登录跳转
     //判断是否授权，做授权跳转
     }
     ```
     
   
   - 获取授权码code的脚本API样例如下：
     ```
     // Here's your code.
     import * as oauth from 'oauth'
     let handle = oauth.getAuthorizeHandle()
      
      
     //前面步骤已经走完
     let clientDatas: oauth.clientDataFromApp = {
           redirect_uri: "http://10.26.30.68:14000/appauth/code",
         client_id: "bff4398905ee4a918722debec98b594c",
     }
      
     let userInfo = {
         "name": "jack",
         "phone": "1256287222",
         "email": "example.com"
     } 
     let code = handle.getAuthCode(clientDatas, userInfo)
     console.log(code) //WEUcqXbeQDKUHxcn8til3Q
     ```
     
    
   
   

4. 第三方系统接收到该请求，并解析出code后，在后端访问接口获取access_token，步骤和[6]一致。
5. 第三方系统在获取到access_token后，使用该凭证访问平台"https://*域名* /u-route/baas/oauth/v1.0/**third** /userinfo"接口（该接口和[8]中的接口**不同** ），来获取授权用户的信息。
   
   响应示例如下：
   ```
   { 
     "resCode": "0", 
     "resMsg": "成功", 
     "result": { 
      "email": "example.com",
       "name": "jack",
   "phone": "1256287222"
   } 
   }
   ```
   
   
 
