secret-net.md 4.4 KB
Newer Older
W
wanganxp 已提交
1
云端一体安全网络
d-u-a's avatar
d-u-a 已提交
2

W
wanganxp 已提交
3
## 简介
d-u-a's avatar
d-u-a 已提交
4

W
wanganxp 已提交
5
网络安全的问题很多:
d-u-a's avatar
d-u-a 已提交
6

W
wanganxp 已提交
7 8
1. 客户端受信。因为过去采用无状态网络通过接口交换数据,客户端的真实性很难保证。
2. 网络抓包,即便是https的请求也会被抓包。
d-u-a's avatar
d-u-a 已提交
9

W
wanganxp 已提交
10
当攻击者了解了你的服务器接收什么样的数据时,就可以冒名客户端,提交假数据来攻击你的服务器。
d-u-a's avatar
d-u-a 已提交
11

W
wanganxp 已提交
12
尤其当你的业务中涉及促销、返佣、激励视频等场景,非常容易被刷。褥羊毛已经是一个非常成熟的灰产。
d-u-a's avatar
d-u-a 已提交
13

W
wanganxp 已提交
14
当DCloud同时提供了`uni-app``uniCloud`时,事实上具备了提供云端一体的安全网络的能力。
d-u-a's avatar
d-u-a 已提交
15

d-u-a's avatar
d-u-a 已提交
16
在HBuilderX 3.6.2+ ,当开发者同时使用 `uni-app``uniCloud` 时,可以在网络请求时选择是否通过安全网络运行,它通过高安全的保护机制,防止客户端伪造和通信内容抓包。
d-u-a's avatar
d-u-a 已提交
17

W
wanganxp 已提交
18
注意:安全网络不支持web平台,只支持微信小程序和App。并且App的安全级别更高。
d-u-a's avatar
d-u-a 已提交
19

W
wanganxp 已提交
20
**平台差异说明**
d-u-a's avatar
d-u-a 已提交
21

W
wanganxp 已提交
22 23
|App|微信小程序|
|:-:|:-:|
d-u-a's avatar
d-u-a 已提交
24
|后续支持|3.6.2+|
d-u-a's avatar
d-u-a 已提交
25

W
wanganxp 已提交
26
## 开通流程
d-u-a's avatar
d-u-a 已提交
27

W
wanganxp 已提交
28
### App平台
d-u-a's avatar
d-u-a 已提交
29

d-u-a's avatar
d-u-a 已提交
30
后续支持
d-u-a's avatar
d-u-a 已提交
31

W
wanganxp 已提交
32
### 微信小程序
d-u-a's avatar
d-u-a 已提交
33

W
wanganxp 已提交
34
1. 下载uni-id插件
d-u-a's avatar
d-u-a 已提交
35

36
- `uni-id-co` [详情](/uniCloud/uni-id-summary.html#save-user-token)
d-u-a's avatar
d-u-a 已提交
37

W
wanganxp 已提交
38
2. 下载uni-open-bridge插件
d-u-a's avatar
d-u-a 已提交
39

W
wanganxp 已提交
40
在微信小程序上依赖 `access_token``session_key`, `encrypt_key`。这些凭据需要`uni-open-bridge`统一接管。
d-u-a's avatar
d-u-a 已提交
41

42
- `uni-open-bridge` [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-open-bridge.html)
d-u-a's avatar
d-u-a 已提交
43

44
3. 在应用的生命周期 `onLaunch` 中检查微信登陆状态,如果过期需要登陆
d-u-a's avatar
d-u-a 已提交
45

46
注意: [uni.checkSession](https://uniapp.dcloud.net.cn/api/plugins/login.html#uni-checksession) 有调用次数限制警告,一个 `pv` 可调用 `2`
d-u-a's avatar
d-u-a 已提交
47 48 49 50 51

```js
// App.vue
<script>
  function checkUserSession() {
d-u-a's avatar
d-u-a 已提交
52
    uni.checkSession({
d-u-a's avatar
d-u-a 已提交
53
      fail: (err) => {
d-u-a's avatar
d-u-a 已提交
54
        uni.login({
d-u-a's avatar
d-u-a 已提交
55 56 57 58 59 60 61 62 63 64 65 66
          success: async ({ code }) => {
            const uniIdCo = uniCloud.importObject('uni-id-co') // uniCloud云对象 uni-id-co
            await uniIdCo.loginByWeixin({ code })
          }
        })
      }
    })
  }

  export default {
    onLaunch: function() {
      console.log('App Launch')
d-u-a's avatar
d-u-a 已提交
67
      // #ifdef MP-WEIXIN
d-u-a's avatar
d-u-a 已提交
68
      checkUserSession();
d-u-a's avatar
d-u-a 已提交
69
      // #endif
d-u-a's avatar
d-u-a 已提交
70 71 72 73 74 75
    }
  }
</script>
```


W
wanganxp 已提交
76
## 调用方式
d-u-a's avatar
d-u-a 已提交
77

W
wanganxp 已提交
78
开通配置后,在uni-app客户端调用uniCloud服务器时,可以通过加入secret参数来声明这次请求走安全网络,对传输数据加密。
d-u-a's avatar
d-u-a 已提交
79

W
wanganxp 已提交
80
- callFunction
d-u-a's avatar
d-u-a 已提交
81

W
wanganxp 已提交
82 83 84 85 86 87 88
客户端通过callFunction调用云函数时,加入secret参数。
```js
uniCloud.callFunction({
  name: 'collection',
  data: {
    name: 'user'
  },
89
  secretType: 'both'
W
wanganxp 已提交
90 91
})
```
d-u-a's avatar
d-u-a 已提交
92

W
wanganxp 已提交
93 94 95 96 97 98 99
- 云对象

客户端通过importObject调用云对象时,加入secret和secretMethods参数。

```js
uniCloud.importObject('object-name', {
  customUI: false,
100
  secretMethods: {'login':'both'}
W
wanganxp 已提交
101 102 103
})
```

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
## 服务器端

为了避免客户端伪造参数获取服务器敏感数据,应以服务器端为准,如果客户端携带的 `secretType` 不符合要求应拒绝响应数据

- callFunction

```js
exports.main = async (event, context) => {
  const secretType = context.secretType
  // secretType 是客户端调用 uniCloud.callFunction 传递的参数 secretType

  if (secretType !== 'both' || secretType !== 'response') {
    return null
  }
}
```

- 云对象

```js
module.exports = {
  async _before() {
    const methodName = this.getMethodName()
    const clientInfo = this.getClientInfo()
    const secretType = clientInfo.secretType
d-u-a's avatar
d-u-a 已提交
129
    // methodName 是客户端调用的方法名
130 131 132 133 134 135 136 137 138
    // secretType 是客户端调用 uniCloud.importObject 传递的参数 secretMethods

    if (methodName === 'login' && (secretType !== 'both' || secretType !== 'response')) {
      throw new Error('secretType invalid')
    }
  }
}
```

W
wanganxp 已提交
139

d-u-a's avatar
d-u-a 已提交
140
**secretType 属性说明**
W
wanganxp 已提交
141

142 143 144 145 146 147
|值				|描述																						|
|:-:			|:-:																						|
|none			|不加密,默认值																	|
|request	|只加密客户端请求时的上行数据,服务器下发数据不加密	|
|response	|客户端请求时不加密数据,只加密服务器下发的数据			|
|both			|客户端和服务器上行下行数据都加密数据							|
W
wanganxp 已提交
148 149 150

**secretMethods 属性说明**

d-u-a's avatar
d-u-a 已提交
151
`secretMethods` 是云对象中指定需要加密的方法名。可对每个方法配置,例如: `secretMethods: {'login':'both'}`,指定 `login` 方法的 `secretType` 为 both
W
wanganxp 已提交
152 153


154 155


W
wanganxp 已提交
156 157 158 159
## 小贴士

1. 安全是相对的,没有绝对的安全。
2. 安全是有代价的,加密的数据越庞大,加密和解密的耗时越长。