1 应用授权登录

1.1 应用授权登录

第三方应用可以使用此接口构造外勤365授权完成后自动跳转的URL
avatar

1.1.1 构造用户授权oauth2链接

请求方式: GET(HTTPS
请求地址: https://cloud.waiqin365.com/service/oauth/authorize?response_type=code&app_id=APP_ID&redirect_uri=REDIRECT_URI&scope=user&state=1342

GET /service/oauth/authorize?response_type=code&app_id=10001&state=1342&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: cloud.waiqin365.com

参数说明:

参数 是否必须 说明
response_type 用户访问模式:code-授权码模式
app_id 应用ID
redirect_uri 重定向URI,代表当授权完成之后,返回的路径
scope 当前需要访问的授权信息
state 由于后续步骤验证时用的随机字符串

服务端授权成功后跳转地址:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=XXXX&state=1342

参数说明:

参数 说明
redirect_uri 重定向URI,代表当授权完成之后,返回的路径
code 用户授权码
state 由于后续步骤验证时用的随机字符串

服务端授权失败后跳转地址:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?error=access_denied&state=1342

参数说明:

参数 说明
redirect_uri 重定向URI,代表当授权完成之后,返回的路径
error 错误码:
invalid_request-请求错误
unauthorized_client-访问未授权链接
access_denied-服务器拒绝访问
unsupported_response_type-不支持响应类型
invalid_scope-请求授权信息失败
server_error-服务器错误
state 由于后续步骤验证时用的随机字符串

1.1.2 外勤365授权登录入口

请求方式: GET(HTTPS
请求地址: REDIRECT_URI?code=XXXX&state=1342

服务端授权成功后跳转地址:

HTTP/1.1 302 Found
Location: REDIRECT_URI?code=XXXX&state=1342

参数说明:

参数 说明
code 用户访问授权码
redirect_uri 企业在外勤365配置的重定向URI,代表当授权完成之后,返回的路径
state 由于后续步骤验证时用的随机字符串

服务端授权失败后跳转地址:

HTTP/1.1 302 Found
Location: REDIRECT_URI?error=access_denied&state=1342

参数说明:

参数 说明
redirect_uri 重定向URI,代表当授权完成之后,返回的路径
error 错误码:
invalid_request-请求错误
unauthorized_client-访问未授权链接
access_denied-服务器拒绝访问
unsupported_response_type-不支持响应类型
invalid_scope-请求授权信息失败
server_error-服务器错误
state 由于后续步骤验证时用的随机字符串

1.2 应用获取AccessToken

第三方应用可以使用此接口获取企业授权的AccessToken用于获取企业及用户信息,以及其他授权的业务操作

请求方式: POST(HTTPS
请求地址: https://openapi.waiqin365.com/service/oauth/token
请求包体:

{
        "app_id":"app1029034344",
        "app_secret":"NX09FRERZAFERERT96KL=",
        "tenant_id":"6692513571099135446"
}

参数说明:

参数 是否必须 说明
app_id 服务商应用APPID
app_secret 服务商应用授权KEY
tenant_id 企业ID

返回结果:

{
    "return_code":0,
    "return_msg":"success",
    "return_data": {
        "access_token":"2019040189580858920907506625723500936366986112",
        "expires_in":7200
    }
}

参数说明:

参数 说明
return_code 响应码
return_msg 对返回码的文本描述内容
access_token 第三方应用access_token,最长为512字节
expires_in 有效期,单位秒

1.3 获取访问用户身份

第三方应用可以使用此接口获取当前授权的企业用户基本信息

请求方式: POST(HTTPS
请求地址: https://openapi.waiqin365.com/service/oauth/userinfo?access_token=2019040189580858920907506625723500936366986112&code=2019040409119168303823765016020d9cd24aa343ecb0c4047ba67a5e24

参数说明:

参数 是否必须 说明
access_token 应用授权AccessToken
code 通过成员授权获取到的code,最大为512字节。
每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

返回结果:

{
    "return_code":0,
    "return_msg":"success",
    "return_data": {
        "tenant_id":"7102807924041722259",
        "id":"7102807924041722259",
        "name":"张三",
        "user_type": "1"
    }
}

参数说明:

参数 说明
return_code 响应码
return_msg 对返回码的文本描述内容
tenant_id 企业ID
id 企业用户唯一ID,最长为32字节
name 用户名称,最长为100字节
user_type 用户类型:1-用户,2-客户

1.4 应用请求数据签名生成方法

第三方应用访问外勤365服务接口时需要对请求数据做签名处理,签名信息包含(access_token-服务商授权码, timestamp-访问时间戳, nonce-随机字符串, echoStr-请求数据体)。
签名方法,根据签名数据值自然顺序排序后拼接成一个字符串,然后获取SHA-1签名。

import java.security.MessageDigest;
import java.util.Arrays;

public class OAuth2Utils
{
	/**
	 * 根据数据生成签名信息(1.根据数据排序 2.排序后拼接成字符串生成SHA-1签名信息)
	 * @param accessToken 服务商授权Token
	 * @param timeStamp 时间戳
	 * @param nonce 随机字符串
	 * @param echoStr 请求数据体
	 * @return 签名信息
	 * @throws AesException
	 */
	public static String makeSignature(String accessToken, long timeStamp, String nonce, String echoStr) throws AesException
	{
		try {
			String[] array = new String[] { accessToken, String.valueOf(timeStamp), nonce, echoStr };
			StringBuffer sb = new StringBuffer();
			// 字符串排序
			Arrays.sort(array);
			for (int i = 0; i < 4; i++) {
				sb.append(array[i]);
			}
			String str = sb.toString();
			// SHA1签名生成
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			md.update(str.getBytes());
			byte[] digest = md.digest();

			StringBuffer hexstr = new StringBuffer();
			String shaHex = "";
			for (int i = 0; i < digest.length; i++)
			{
				shaHex = Integer.toHexString(digest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexstr.append(0);
				}
				hexstr.append(shaHex);
			}
			return hexstr.toString();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new AesException(AesException.ComputeSignatureError);
		}
	}