客户身份(CIAM)

微信登录

# 文档说明

本文为您介绍Android客户端如何接入微信授权登录功能。微信登录使用场景下,用户手机上已安装了微信APP,用户点击客户端APP上微信登录按钮,IDaaS SDK调起微信APP里的授权页面,用户点击“授权登录”按钮,授权成功后,微信APP重定向回到客户端APP,此时IDaaS SDK自动接收到临时票据,带着票据到IDaaS 服务端请求认证。最终认证结果返回给客户端APP。

# 流程说明

# 登录流程

集成流程说明

  1. 用户点击APP客户端的微信登录按钮。

  2. APP客户端拉起IDaaS SDK的微信登录方法。

  3. IDaaS SDK发送登录授权请求到微信SDK。

  4. 微信SDK拉起手机上的微信APP,并显示授权登录页面。

  5. 用户点击授权登录按钮。

  6. 微信授权成功,拉起客户端APP,并且带上微信授权票据,此时,IDaaS SDK在调起中自动获取到微信授权票据。

  7. IDaaS用微信授权票据请求IDaaS服务端认证。

  8. IDaaS服务端查询是否绑定手机号,如果已经绑定手机号,IDaaS服务端认证成功,返回sessionToken给IDaaS SDK。

  9. IDaaS SDK将sessionToken返回给APP 客户端。

  10. 如果IDaaS服务端查询到未绑定手机号,返回需要绑定或注册的标识。

  11. IDaaS服务端展示绑定或注册页面。

  12. 用户输入手机号,点击获取验证码,完成滑块验证。

  13. IDaaS SDK带着滑块验证码到IDaaS服务端请求滑块验证。

  14. IDaaS 服务端校验滑块成功,返回token给IDaaS SDK。

  15. IDaaS SDK用token和手机号到IDaaS 服务端请求发送短信验证码。

  16. 用户收到短信验证码,填入验证码输入框,并且点击绑定或注册按钮。

  17. IDaaS SDK提交绑定或登录数据到IDaaS 服务端。

  18. 绑定或注册成功,IDaaS服务端返回sessionToken给IDaaS SDK。

  19. IDaaS SDK返回sessionToken给客户端APP。

# 准备工作

# 获取clientID

登录IDaaS企业中心平台,点击 “资源-->应用” 选择跟自己相关的应用点击即可查看到。

# 配置认证源

  1. 登录到IDaaS企业中心平台,点击 “认证—>认证源管理—>微信” 。

  2. 点击添加认证源。

  3. 填入微信开发平台 (opens new window)注册应用后得到的AppKey和AppSecrete。并且渠道选择框为‘移动应用’。显示名称填入名称。

  4. 点击确定,就会得到如下图的一条认证源。

  5. 再到资源-->应用,自建应用。

  6. 点击进入新建的应用详情。

  7. 在登录配置—>移动应用—>配置。

  8. 会到如下图窗口,微信的那一条点击后面开启的按钮。

  9. 弹出如下图的窗口,选择刚才配置好的认证源,保存。

# 引入依赖包

在进行微信OAuth授权登录接入之前,需在微信开放平台 (opens new window)注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID 和 AppSecret,申请微信登录且通过审核后,可开始接入流程。

将 aar包导入 lib,如下图所示:

# 配置包名

在你的包名相应目录下新建一个wxapi目录,并在该 wxapi 目录下新增一个WXEntryActivity类,该类继承自Activity(直接复制DEMO中的这个类):

# 配置build.gradle

/*begin*/
    /*  rxjava2 +  okhttp + retrofit2  */
    api 'io.reactivex.rxjava2:rxjava:2.2.10'
    api 'io.reactivex.rxjava2:rxandroid:2.1.1'
    api 'com.squareup.retrofit2:retrofit:2.6.0'
    api 'com.squareup.retrofit2:adapter-rxjava2:2.6.0'
    api 'com.squareup.retrofit2:converter-gson:2.6.0'
    api 'com.squareup.okhttp3:okhttp:4.3.1'
    api 'com.squareup.okhttp3:logging-interceptor:3.6.0'
    api 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
    api 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0'
    api 'com.alibaba:fastjson:1.2.61'
     /*end*/ 
        
    //公共库,必选      
    implementation(name: 'AuthnCenter_Common-1.5.3', ext: 'aar')   
    //微信登录SDK,必选
    implementation(name: ''AuthnCenter_WeChat-1.5.3', ext: 'aar')
    //微信官方依赖库,必选
    implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.6.23'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 配置AndroidManifest

  <!--权限-->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEM"/>
        
        <!--  微信跳转 必须注册 -->
        <activity
            android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:label="微信界面"
            android:launchMode="singleTask"
            android:taskAffinity="com.authncenter.luzhou"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />  
        <!-- 国际区号界面 按需注册 -->
        <activity
            android:name="com.authncenter.wechat.view.CountryCodeListActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait" />
        <!-- 短信验证界面 按需注册 -->
        <activity
            android:name="com.authncenter.wechat.view.MsgActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 开发集成

# 内置API介绍

基本配置初始化主类AuthnCenterAPI方法简介:

/**
 * 短信验证码 -- 发送短信
 */
public void smsSend(Context context, SendSmsReq req, RequestListener listener)

/**
 * 获取国家区号    注意 如果配置了国家区号需要调用此接口获取国家区号
 */
public void getCountryCode(Context context, RequestListener listener)

/**
 * 社交账号绑定接口
 * @param context      上下文
 * @param stateToken   当前登录之后返回临时token
 * @param otpsmsReq    绑定对象信息
 * @param listener     事件回调
 */
public void socialBind(Context context, String stateToken, OTPSMSReq otpsmsReq, RequestListener listener)

/**
 *  注册
 * @param context      上下文
 * @param stateToken   当前登录之后返回临时token
 * @param otpsmsReq    注册对象信息
 * @param listener     事件回调
 */
public void register(Context context, String stateToken, OTPSMSReq otpsmsReq, RequestListener listener)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

微信登录初始化主类AuthnCenterLoginWeChat方法简介:


/**
 *   微信登录
 * @param context  上下文
 * @param loginListener  事件监听
 * @param loginType       LoginType.DEFAULT(内置) ,LoginType.CUSTOM(自定义)
 */
public void loginByWechat(Context context, WeChatLoginListener loginListener, LoginType loginType)

/**
 *    设置微信回调code  
 * @param context  上下文
 * @param code     微信授权返回code
 */
public void setWechatCode(Context context, String code) 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 手机国际区号获取

如果开启了国际号码支持,请自行先行调用国际区号获取接口,国际区号获取接口返回配置好的国际区号列表,并附有电话号码的正则表达式。下图中就是如何配置国际区号列表和首选区号。

获取国际区号列表示例代码:

AuthnCenterAPI.Builder().getCountryCode(this, new RequestListener<CountryCodeInfoRsp>() {
    @Override
    public void success(CountryCodeInfoRsp codeInfoRsp) {
  
    }

    @Override
    public void error(String code, String errorMessage) {
    }
});

1
2
3
4
5
6
7
8
9
10
11

成功示例code=0,data的值:

{
	"phoneAreaCodeDefinitions": [
		{
			"areaCode": "86",
			"displayMapping": {
				"zh-TW": "中國大陸",
				"en": "China",
				"zh-CN": "中国大陆"
			},
			"countryCode": "CN",
			"mobileRegex": "^(\\+86){0,1}\\-?1\\d{10}$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "852",
			"displayMapping": {
				"zh-TW": "中國香港",
				"en": "Hong Kong",
				"zh-CN": "中国香港"
			},
			"countryCode": "HK",
			"mobileRegex": "^(\\+852){1}\\-?0{0,1}[1,4,5,6,7,8,9](?:\\d{7}|\\d{8}|\\d{12})$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "886",
			"displayMapping": {
				"zh-TW": "中國臺灣",
				"en": "Taiwan",
				"zh-CN": "中国台湾"
			},
			"countryCode": "TW",
			"mobileRegex": "^(\\+886){1}\\-?[6,7,9](?:\\d{7}|\\d{8})$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "853",
			"displayMapping": {
				"zh-TW": "中國澳門",
				"en": "Macau",
				"zh-CN": "中国澳门"
			},
			"countryCode": "MO",
			"mobileRegex": "^(\\+853){1}\\-?0{0,1}[1,4,5,6,7,8,9](?:\\d{7}|\\d{8}|\\d{12})$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "93",
			"displayMapping": {
				"zh-TW": "阿富汗",
				"en": "Afghanistan",
				"zh-CN": "阿富汗"
			},
			"countryCode": "AF",
			"mobileRegex": "^(\\+93){1}\\-\\d{6,11}",
			"areaCodeSuffixes": []
		}
	],
	"preferredAreaCode": "CN"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
58
59
60

返回参数:

参数名 中文名称 类型 描述
preferredAreaCode 首选国际区号 String 当前企业中心配置的首选国际区号
countryCode 国家地区代码 String 国家地区代码
areaCode 国际电话区号 String 国际电话区号
areaCodeSuffixes 国际电话区号后缀 String 国际电话区号后缀
mobileRegex 手机号格式正则 String 手机号格式正则
displayMapping 多语言显示名映射 String 多语言显示名映射

# 内置滑动校验

在发送验证码时需要调用人机交互验证


BlockPuzzleDialog mBlockPuzzleDialog = new BlockPuzzleDialog(mContext);
mBlockPuzzleDialog.setOnResultsListener(new OnResultsListener() {
        @Override
        public void onResultsClick(String result) {
            LogUtil.getInstance().d("二次校验回调结果 mCaptchaToken:" + result);
            //这个回调结果就是短信校验的captchaToken参数
        }
        @Override
        public void onError(String code, String msg) {
            ToastUtils.ShowToast(mContext, String.format("错误码 : %s  错误信息 : %s", code, msg));
        }
    });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 发送验证码

App客户端需要有自己的UI界面,界面包含几个必要组件:手机号输入框,验证码输入框,触发获取验证码的按钮(或者事件),登录的按钮(或者事件)。

  1. 在用户填入手机号码后,点击(触发)发送验证码事件之前,App客户端做手机号格式检查。

  2. 点击(触发)发送验证码事件,App客户端调用IDaaS SDK的发送验证码方法,示例如下:

//发送验证码
SendSmsReq sendSmsReq = new SendSmsReq();
sendSmsReq.setMobile(getPhoneNum());
sendSmsReq.setType(SendSmsType.login);//类型枚举
sendSmsReq.setCaptcha_token(“滑动验证码成功之后返回结果”);
AuthnCenterAPI.Builder().smsSend(mContext, sendSmsReq
        , new RequestListener<BaseResponse>() {
            @Override
            public void success(BaseResponse rsp) {
            }
            @Override
            public void error(String code, String errorMessage) {
            }
        });
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 内置UI开发集成

# 初始化

AuthnCenterSDK.Builder()
                .init(this)
                .setBaseUrl("https://xxx.xxx.com")      //租户域名 
                .setClientId("xxxx") //租户后台应用client-id
                .isCheckSSL(false) //是否检测SSL证书
                .logEnable(false).build(); //是否打开http请求log
PlatformConfig.Builder().init(this).setWechatAppId(wechatAppId); //设置微信APPID
1
2
3
4
5
6
7

# UI定制化

调用方通过BindThemeConfig可设置绑定界面的文字,说明以及颜色等,具体属性如下:

//自定义界面
BindThemeConfig.Builder().setBindTitle("我是标题")
        .setBindDes("我是详情")
        .setBindButtonText("我就想改变一下按钮得文字")
        .setBindButtonTextDefaultColor("#367517")
        .setBindButtonTextColor("#C8E2B1")
        .setBindButtonTextOnPressColor("#F9F400")
        .setSendMsgColor("#976D00")
        .setSendMsgNoActiviColor("#50A625")
        .setDialogTitle("我就是想自定义")
        .setDialogBtnConfirmColor("#FFB6C1");
1
2
3
4
5
6
7
8
9
10
11

# 属性说明

参数 类型 说明 示例
setBackFont String 更改返回文字
setBackFontColor String 更改返回文字颜色 16进制颜色 例如: #FFFFFF
setBackImg int 设置返回图标 资源文件R
setBackFontSize int 设置返回文字大小 14sp
setCountryCodeVisibility boolean 设置国际区号是否展示 默认为true
setBindTitle String 绑定界面标题
setBindDes String 绑定界面说明
setBindButtonText String 绑定按钮文字
setBindButtonTextDefaultColor String 绑定按钮文字背景默认颜色 16进制颜色 例如: #FFFFFF
setBindButtonTextColor String 绑定按钮文字颜色 16进制颜色 例如: #FFFFFF
setBindButtonTextOnPressColor String 绑定按钮文字背景点击之后颜色 16进制颜色 例如: #FFFFFF
setSendMsgColor String 发送短信按钮文字颜色 16进制颜色 例如: #FFFFFF
setSendMsgNoActiviColor String 倒计时文字颜色 16进制颜色 例如: #FFFFFF
setDialogTitle String 解绑弹出框标题
setDialogBtnConfirmColor String 解绑弹出框确认按钮颜色 16进制颜色 例如: #FFFFFF
sendMsgNoActiveBackground int 发送短信按钮背景资源 Android 颜色或者背景资源文件 (R)
setButtonBackground int 发送短信按钮默认背景资源 Android 颜色或者背景资源文件 (R)
setSendMsgBackground int 绑定按钮钮背景资源 Android 颜色或者背景资源文件 (R)

# 微信登录内置界面

 AuthnCenterLoginWeChat.Builder().loginByWechat(this, new WeChatLoginListener() {
            @Override
            public void success(String code, String data) {
                 //成功回调
            }

            @Override
            public void error(String code, String errorMessage) {
               //失败回调
            }
        }, LoginType.DEFAULT);
1
2
3
4
5
6
7
8
9
10
11

# 以API开发集成

选择此方式集成的话在登录返回之后需要根据返回的状态自行处理绑定或者注册业务同时验证手机号相关的基础操作。

同时 AndroidManifest 文件 相关注册信息可填写自己的即可。

# 调用顺序说明

在登录成功之后如果返回状态为绑定,那么此时需要调用:

  1. 获取国家区号(这个根据是否配置支持国际化选择调用) (getCountryCode)

  2. 滑动校验 (BlockPuzzleDialog )

  3. 发送短信 (smsSend)

  4. 绑定或者注册 (socialBind/register)

# 初始化

AuthnCenterSDK.Builder()
                .init(this)
                .setBaseUrl("https://xxx.xxx.com")      //租户域名 
                .addGlobalHeader("X-client-id", "xxxx") //租户后台应用client-id
                .isCheckSSL(false) //是否检测SSL证书
                .logEnable(false).build(); //是否打开http请求log
PlatformConfig.Builder().init(this).setWechatAppId(wechatAppId); //设置微信APPID
1
2
3
4
5
6
7

# 微信登录(自定义界面)

AuthnCenterLoginWeChat.Builder().loginByWechat(this, new WeChatLoginListener() {
    @Override
    public void success(String code, String data) {
//此处根据 code 返回值进行跳转到自己的界面进行绑定或者注册操作
        Intent intent = new Intent(MainActivity.this, WechatActivity.class);
        intent.putExtra(SocialType.STATETOKEN, data);
        intent.putExtra(SocialType.BINDTYPE, SocialType.WX);
        switch (code) {
   case "10002":   //登录成功
ToastUtils.ShowToast(MainActivity.this, "登录成功 : " + data);  
                return;
            case "10003":   //绑定用户
               intent.putExtra(SocialType.ACTIONTYPE, ActionType.BIND);
                break;
            case "10004": //注册用户
                intent.putExtra(SocialType.ACTIONTYPE, ActionType.REGISTER);
                break;
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

    @Override
    public void error(String code, String errorMessage) {
        ToastUtils.ShowToast(MainActivity.this, "SDK 回调  code : " + code + "---- msg " + errorMessage);
    }
}, LoginType.CUSTOM); 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

此处根据返回code进行判断:

code码 说明
10001 AuthCenter服务器错误
10002 成功
10003 需要绑定用户
10004 需要注册用户

# 返回码

状态码 错误码 (error_code) 错误说明 (error_msg) 处理措施
400 IDAAS.SDK.COMMON.1001 Parameter {0} cannot be left blank
参数 {0} 不能为空
400 IDAAS.SDK.COMMON.1002 The {0} parameter format is incorrect
参数 {0} 格式错误
400 IDAAS.SDK.COMMON.1003 Device information is incomplete
设备信息不完整
400 IDAAS.SDK.COMMON.1004 Signature decryption error
签名解密错误
400 IDAAS.SDK.COMMON.1005 The {0} has failed
{0} 已失效
400 IDAAS.SDK.COMMON.1006 The {0} parameter error
{0} 参数错误
400 IDAAS.SDK.COMMON.1007 The {0} parameter type error
{0}参数类型错误
500 IDAAS.SDK.COMMON.1008 The system is busy. Try again later
系统繁忙。稍后再试
400 IDAAS.SDK.COMMON.1009 Unknown authentication configuration
未知的认证配置
400 IDAAS.SDK.COMMON.1010 Failed to obtain the enterprise center global configuration
获取企业中心全局配置失败
400 IDAAS.SDK.COMMON.1011 Failed to obtain the international area code configuration
获取国际区号配置失败
400 IDAAS.SDK.COMMON.1012 The x-client-ID is incorrect and the corresponding application cannot be found
X-client-id错误,找不到对应的应用
400 IDAAS.SDK.COMMON.1013 The corresponding user is not found
未找到对应的用户
400 IDAAS.SDK.COMMON.1014 Application private key not found
未找到应用私钥
400 IDAAS.SDK.LOGIN.1001 Error calling interface {0}
调用 {0} 接口出错
400 IDAAS.SDK.LOGIN.1002 User not bound
用户未绑定
400 IDAAS.SDK.LOGIN.1003 The user has been locked due to too many unsuccessful login attempts. It will be unlocked in {0} minutes and {1} seconds
由于多次登录失败,用户已被锁定。 它将在 {0} 分钟和 {1} 秒内解锁
400 IDAAS.SDK.LOGIN.1004 Failed to obtain the password policy
获取密码策略错误
400 IDAAS.SDK.LOGIN.1005 Invalid username or password. Remaining login attempts: {0}
无效的用户名或密码。 其余登录尝试次数:{0}
400 IDAAS.SDK.LOGIN.1006 Configuration error, unable to find wechat authentication source
配置错误,找不到微信认证源
400 IDAAS.SDK.LOGIN.1007 Configuration error, unable to find alipay authentication source
配置错误,找不到支付宝认证源
400 IDAAS.SDK.LOGIN.1008 The configuration is incorrect. The one-click login authentication source cannot be found
配置错误,无法找到一键登录认证源
400 IDAAS.SDK.SMS.1001 {0} slide base map is not initialized successfully, please check the path
{0} 滑动底图未初始化成功,请检查路径
400 IDAAS.SDK.SMS.1002 {0} verification code coordinate resolution failed
{0} 验证码坐标解析失败
400 IDAAS.SDK.SMS.1003 {0} verification code coordinate verification fails
{0} 验证码坐标校验失败
400 IDAAS.SDK.SMS.1004 The graphic verification code is incorrect
图形验证码校验错误
400 IDAAS.SDK.SMS.1005 SMS verification code verification is incorrect
短信验证码验证错误
400 IDAAS.SDK.SMS.1006 The email verification code is incorrect
邮件验证码验证错误
400 IDAAS.SDK.SMS.1007 Sending scenario does not exist
发送场景不存在
400 IDAAS.SDK.SMS.1008 Failed to send the verification code
发送验证码失败
400 IDAAS.SDK.SOCIAL.1001 The social account is unbound incorrectly
社交账号解绑错误
400 IDAAS.SDK.SOCIAL.1002 The social account has been bound, please unbind it first
社交账号已绑定,请先解绑
400 IDAAS.SDK.PWD.1001 The password length is incorrect
密码长度错误
400 IDAAS.SDK.PWD.1002 The password cannot be the username
密码不能为用户名
400 IDAAS.SDK.PWD.1003 Your password complexity is low
你的密码复杂度过低
400 IDAAS.SDK.PWD.1004 The password is weak
密码很弱
400 IDAAS.SDK.PWD.1005 The password is used before, cannot be used again
该密码已被使用过,不能再次使用
400 IDAAS.SDK.PWD.1006 Password cannot username in reverse order
密码不能是用户名的倒序
400 IDAAS.SDK.PWD.1007 The number of repeated password characters exceeded the upper limit
密码重复字符数超过限制
400 IDAAS.SDK.PWD.1008 Password cannot contain :username, phone number, email prefix, name in PinYing
密码不能包含:用户名、电话号码、邮件前缀、拼音名
400 IDAAS.SDK.MFA.1001 The mobile doesn't match the user
手机号和用户不匹配
400 IDAAS.SDK.MFA.1002 The access control policy is incorrect
访问控制策略配置错误
400 IDAAS.SDK.MFA.1003 Access control authentication source type conversion error
访问控制身份验证源类型转换错误