authentication.md 7.0 KB
Newer Older
雪洛's avatar
雪洛 已提交
1 2
**本章内容仅针对腾讯云开发,阿里侧暂不支持**

雪洛's avatar
雪洛 已提交
3 4 5 6 7
**腾讯云侧必须以任意登录方式登录之后才可以访问云端资源。开发者在控制台开启匿名登录之后,可以在客户端调用匿名登录来获取访问云端资源的权限**

## uniClient.auth()

获取登录对象
雪洛's avatar
雪洛 已提交
8 9 10 11 12 13 14 15

**示例代码**

```js
const uniClient = uniCloud.init({
  spaceId: 'xxxx-yyy'
});

雪洛's avatar
雪洛 已提交
16
const auth = uniClient.auth()
雪洛's avatar
雪洛 已提交
17 18
```

雪洛's avatar
雪洛 已提交
19
## auth.signInAnonymously()
雪洛's avatar
雪洛 已提交
20

雪洛's avatar
雪洛 已提交
21
进行匿名登录,详细描述参考[匿名登录](#匿名登录)
雪洛's avatar
雪洛 已提交
22 23 24 25 26 27 28

**示例代码**

```js
const uniClient = uniCloud.init({
  spaceId: 'xxxx-yyy'
});
雪洛's avatar
雪洛 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

const auth = uniClient.auth()
auth.signInAnonymously()
```

## auth.signInWithTicket()

进行自定义登录,详细描述参考[自定义登录](#自定义登录)

**示例代码**

```js
auth.signInWithTicket('YourTicket').then(() => {
    // 获取用户信息
    return auth.getUserInfo()
  })
  .then(userInfo => {
    //...
  })
```

## auth.getLoginState()

开发者可以通过 `getLoginState()` 来获取当前的登录状态,调用 `getLoginState()` 后,SDK 会识别本地是否有登录状态,如果有,则会尝试刷新登录状态,若刷新登录状态成功,则会返回新的登录状态,否则返回 `undefined`

**示例代码**

```js
auth.getLoginState().then(loginState => {
雪洛's avatar
雪洛 已提交
58 59 60 61 62 63 64 65
  if (loginState) {
    // 登录态有效
  } else {
    // 没有登录态,或者登录态已经失效
  }
})
```

雪洛's avatar
雪洛 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
## auth.getUserInfo()

任何方式登录成功后,可以调用 `getUserInfo` 获得用户的身份信息。

**响应参数**

|字段					|类型		|是否必备	|说明														|
|:-:					|:-:		|:-:			|:-:														|
|uid					|string	|是				|用户在云开发的唯一ID						|
<!-- |customUserId	|string	|否				|用户使用自定义登录传入的用户Id	| -->

**示例代码**

```js
auth.signInWithTicket('YourTicket').then(() => {
    // 获取用户信息
    return auth.getUserInfo()
  })
  .then(userInfo => {
    //...
  })
```

雪洛's avatar
雪洛 已提交
89 90 91 92 93 94
## 自定义登录

`uniCloud`允许开发者使用特定的登录凭据`Ticket`对用户进行身份认证。开发者可以使用`服务端 SDK`来创建`Ticket`,并且将`token`传入到应用内,然后调用`signInWithTicket()`获得登录态。

### 获取私钥文件

雪洛's avatar
雪洛 已提交
95
登录uniCloud控制台[uniCloud控制台](http://unicloud.dcloud.net.cn/),在`用户管理页面`中,点击“登录设置”,然后**生成并下载私钥**
雪洛's avatar
雪洛 已提交
96

雪洛's avatar
雪洛 已提交
97
![uniCloud下载私钥](https://img.cdn.aliyun.dcloud.net.cn/uni-app/uniCloud/auth-custom.png)
雪洛's avatar
雪洛 已提交
98 99 100 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 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144

### 使用云函数创建登录凭据

获取私钥文件之后,重命名为`credentials.json`放在云函数同级目录即可

`服务端 SDK`内置了生成`Ticket`的接口,开发者需要提供一个自定义的`customUserId`作为用户的唯一身份标识。`Ticket`有效期为**5分钟**,过期则失效。

每个用户的`customUserId`不能相同,每次用户重新登录时,原有的登录态将会失效。

```js
let customUserId = '123456';

const ticket = uniCloud.auth().createTicket(customUserId, {
  refresh: 10 * 60 * 1000 // 每十分钟刷新一次登录态, 默认为一小时
});
// 然后把 ticket 发送给客户端
```

<!-- ### 在开发者服务器创建登录凭据

获取私钥文件之后,在服务端 SDK 初始化时,加入私钥文件的路径:

```js
// 开发者的服务端代码
// 初始化示例
const tcb = require('tcb-admin-node');

// 1. 直接使用下载的私钥文件
tcb.init({
  // ...
  spaceId: 'your-space-id',
  credentials: require('/path/to/your/tcb_custom_login.json')
});

// 2. 也可以直接传入私钥的内容
tcb.init({
  // ...
  spaceId: 'your-space-id',
  credentials: {
    private_key_id: 'xxxxxxxxxxxxx',
    private_key: 'xxxxxxxxxxx'
  }
});
``` -->

### 客户端上使用Ticket登录

雪洛's avatar
雪洛 已提交
145
创建`Ticket`之后,开发者应将`Ticket`发送至客户端,然后使用`客户端SDK`提供的 `signInWithTicket()` 登录`uniCloud`
雪洛's avatar
雪洛 已提交
146 147 148 149 150 151 152 153 154 155 156 157

```js
auth.signInWithTicket(ticket).then(() => {
  // 登录成功
})
```


## 匿名登录
uniCloud允许开发者使用匿名登录的方式进行静默授权,可以避免强制登录。在匿名状态下可正常的调用uniCloud的资源,开发者同时可以配合安全规则针对匿名用户制定对应的访问限制。

### 开启匿名登录授权
雪洛's avatar
雪洛 已提交
158
登录uniCloud控制台[uniCloud控制台](http://unicloud.dcloud.net.cn/),在`用户管理页面`中,点击“登录设置”,点击“登录设置”,然后在“匿名登录”一栏打开/关闭可用状态。
雪洛's avatar
雪洛 已提交
159

雪洛's avatar
雪洛 已提交
160
![uniCloud匿名登录](https://img.cdn.aliyun.dcloud.net.cn/uni-app/uniCloud/auth-anonymously.png)
雪洛's avatar
雪洛 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229

### 客户端进行匿名登录
```js
await auth.signInAnonymously().catch(err=>{
  // 登录失败会抛出错误
});
// 匿名登录成功检测登录状态isAnonymous字段为true
const loginState = await auth.getLoginState();
console.log(loginState.isAnonymous) // true
```

#### 匿名用户重新登录

匿名用户如果要重新使用开发者提供的身份登录,可以调用`auth.signInWithTicket`来进行。[参考](#客户端上使用Ticket登录)

#### 匿名用户转化为自定义用户
目前UniCloud支持将匿名用户转化为自定义登录用户,此转正用户将会继承匿名用户在云端创建的资源,流程如下:
1. 首先需要按照自定义登录的流程搭建获取自定义登录凭证`ticket`的服务;
2. 客户端请求接口获取自定义登录凭证`ticket`**请注意**,此`ticket`必须未注册过uniCloud,换句话说,匿名用户只能转化为新的uniCloud用户;
3. 客户端调用`auth.linkAndRetrieveDataWithTicket`API,如下:
```js
// 调用此API之前需先请求接口获取到ticket
auth.linkAndRetrieveDataWithTicket(ticket).then(res => {
  // 转正成功
}).catch(err => {
  // 转正失败会抛出错误
});
```

## 登录授权相关事件及钩子函数

### Event: 'loginStateExpire'

当登录态失效时,会触发这个事件,开发者可以在这个事件回调内,尝试重新登录 uniCloud。

```js
uniClient.on('loginStateExpire', () => {
  // 尝试重新登录
});
```

### Event: 'refreshAccessToken'

JS SDK 会在登录态生效期间,自动刷新和维护短期访问令牌(access token),每次成功刷新时会触发此事件。

对于两种登录态并存(uniCloud、自身业务登录态)的 Web 应用,这个事件可以用于同步登录态之间的状态。

```js
uniClient.on('refreshAccessToken', () => {
  // 此时 uniCloud 短期访问令牌已经刷新,可以尝试刷新自身业务的登录态
})
```

### Auth.shouldRefreshAccessToken(callback)

`shouldRefreshAccessToken` 接收一个 `callback` 函数,并且会在刷新短期访问令牌前调用此 `callback` 函数,根据返回值决定是否要刷新短期访问令牌。

对于两种登录态并存(uniCloud、自身业务登录态)的 Web 应用,可以在 `callback` 内判断自身业务登录态是否失效,从而决定是否续期 uniCloud 的短期访问令牌。

```js
auth.shouldRefreshAccessToken(() => {
  if (/* 自身业务登录态还有效 */) {
    return true;
  } else {
    return false;
  }
});
```