---
order: 5
---
# 生成扫码登录二维码

为了避免登录界面展示过多的登录方式，并且还需要让用户手动去选择登录方式，SuccBI提供将多个二维码合并为一个二维码的登录方式，让用户使用微信、钉钉等app扫描PC登录界面所展示的同一个二维码，都可以使用app已经登录的用户授权PC以该用户身份登录到系统中。本文将介绍：

- [如何生成登录用的二维码](#login-qrcode-url)。
- 如何[单独为一种单点登录方式特殊生成二维码](#create-qrcode-for-sso)，以适配同时配置了多个相同类型单点登录方式情况：
  - 比如同时[微信扫码登录](../../devops/sso/wechat.md#oa-qrcode)和[微信小程序扫码登录](../../devops/sso/wechat-miniprogram.md#miniprogram-qrcode)，会[引起冲突](../../devops/sso/wechat-miniprogram.md#qrcode-conflict)。

::: tip
当系统设置中已经针对[系统用户](../../sys-settings/security/README.md#sysUserLoginTypes)或者[外部用户](../../sys-settings/security/README.md#externalUserLoginTypes)设置了二维码登录方式，系统默认登录界面或者[系统登录页设置所设置的登录页](../script/system-pages/login-page.md)会展示出二维码的登录方式。考虑到系统默认登录界面和系统登录页设置中给出的登录模板不能满足条件的时候，开发者才需要自定义登录界面，并且自己生成二维码。
:::

## 登录二维码的URL{#login-qrcode-url}

URL格式如下：

```txt
{domain}/api/auth/qrcode[/{ssoid}]?id={qrcodeId}[&ssoid={ssoid}]
```

`[]`中所包含的内容，表明是可选的。

| 参数     | 说明                                                                                  |
| :------- | :------------------------------------------------------------------------------------ |
| domain   | SuccBI环境部署域名地址，并且需要带上服务器上下文路径                                  |
| qrcodeId | 通过[getQRCode](../references/web-api/auth/getQRCode.md)获取，有效时间为5分钟  |
| ssoid    | [系统单点登录方式的id](../../sys-settings/security/sso.md#common-settings)，这是个非必选的参数，登录界面默认生成的URL不包含这个，如果传入了，则表明这个二维码是为这个单点登录方案特殊生成的 |

在登录界面中可调用下面这种方式来生成二维码:

<!-- 代码注释添加额外的制表符缩进，避免渲染出来的时候不对齐 -->

```javascript
requirejs(["security/login"],function (login)){
	/**
		 * 创建二维码控件
		 * 
		 * 说明：
		 * 1. 二维码生成dom结构
		 *	<div class="qrcode-content">
		 *		<div class="qrcode"></div> 												----- 展示二维码图片的容器
		 *		<span class="qrcode-desc"></span>										----- 二维码的提示信息
		 *		<div class="qrcode-refresh-mask invisible">  							----- 二维码过期时候覆盖框
		 *			<div class="qrcode-refresh-content">								----  覆盖框内容展示容器
		 *				<div class="qrcode-refresh-message">当前二维码已过期</div>    		--  文本提示
		 *				<div class="qrcode-refresh-btn">刷新</div>						-----  刷新按钮
		 *			</div>
		 *		</div>
		 *	</div>
		*  2. 需要根据 `invisible` 这个样式 class 来规范控制对应dom的隐藏
		*/
	login.initQRCode({
		//参数
	});
})
```

其中`initQRCode`的参数结构为说明：

```typescript
export interface QRCodeArgs {
	/**
		 * 创建二维码控件所在的父容器,
		 * 
		 * 如果不传入dom，则视为，已经准备好了登录二维码的dom,将不会进行dom创建：
		 *  - 取 class 为 `qrcode-content` 作为控件的根dom容器
		 *  - 取 class 为 `qrcode` 作为显示二维码图片所展示在的dom容器
		 *  - 取 class 为 `qrcode-refresh-mask` 作为二维码过期后，覆盖在二维码容器的上半透明罩dom容器
		 */
	dom?: HTMLElement;

	/**
		 * 显示在登录界面上的二维码登录提示
		 *
		 * 用于提示用户使用什么app扫码等
		 */
	qrcodeTips?: string;

	/**
		 * 单点登录方案id如果传递了表明单独为这个单点登录方案单独生成一个二维码。
		 * 
		 * - 如果不传则默认生成的二维码URL格式为：
		 *  `{contextPath}/api/auth/qrcode?id={qrcodeId}`
		 * 
		 * -传了参数，则默认生成的二维码URL格式为：
		 *  `{contextPath}/api/auth/qrcode/{ssoid}?id={qrcodeId}&ssoid={ssoid}`
		 *   在url中和参数中都添加ssoid的意义在于，如果为微信小程序生成二维码会占用整个URI的后缀。比如：
		 * 		https://baidu.com/api/auth/qrcode?id=xxxxx&ssoid=wxminiprogram 执行微信小程序二维码，
		 * 		https://baidu.com/api/auth/qrcode?id=xxxxx&ssoid=wxoa 指向微信公众号授权信二维码，
		 * 		使用微信扫码上述两个url都会进入微信小程序
		 * 
		 * 		导致相同的URI但是不同参数的情况下，使用微信扫码都会进入微信小程序
		 */
	ssoid?: string;

	/**
		 * 二维码大小的参数，不同模板需要生成的二维码大小不同，若不指定，则默认生成一个256*256大小的二维码
		 * 高度
		 */
	height?: number;

	/**
		 * 二维码大小的参数，不同模板需要生成的二维码大小不同，宽度
		 */
	width?: number;

	/**
		 * 二维码图片的生成方式
		 * 
		 * 如果传入了方法，则不会使用默认的方式生成二维码图片
		 * @param target 生成二维码所存放的父dom
		 * @param qrcodeLink 二维码信息包含的url
		 */
	create?(target: HTMLElement, qrcodeLink: string): void;

	/**
		 * 当二维码状态发生变化的时候的事件
		 * 
		 * 比如： 
		 * 1. 用户使用手机完成扫码  -- 状态值 scan
		 * 2. 用户已经使用完成扫码并确定登录 --- 状态值 done
		 * @param state 二维码的状态值
		 * @returns 如果返回 `false` 或者 `Promise<false>`，则表明处理了状态值的改变，二维码将不会根据状态值默认调整展示状态
		 */
	onstatechange?(state: string): Promise<boolean> | boolean;
}
```

说明：

1. 二维码的ID来自于[API接口getQRCode](../references/web-api/auth/getQRCode.md)。
2. 二维码生成后，会调用[API接口awaitAuthQRCode](../references/web-api/auth/awaitAuthQRCode.md)轮询向后台监听二维码状态的变化。

若是不期望使用系统默认的生成方式，可参考这两个api接口自定义生成二维码图片，并监听二维码变化。

### 为一种单点登录方式特殊生成一个登录二维码{#create-qrcode-for-sso}

仅需要在调用[登录二维码的URL](#urllogin-qrcode-url)生成方法`initQRCode`时候，传递参数`ssoid`用于指定为哪种单点登录方式生成二维码即可。
