Android 集成微信登录

今天项目中集成微信登录,以为非常顺利的事情,却还是多多少少出现了一些问题。所以记录一下集成过程中出现的问题。

开发环境:
  • [x] 系统环境:windows10

  • [x] AndroidStudio 版本: 3.3.2

  • [x] Gradle 版本:4.10.1

集成过程(参照微信接入指南(https://open.weixin.qq.com/cgibin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=60cf535dd0331502a793d5f32051b033b24b9e9d&lang=zh_CN))
  1. 在项目gradle添加依赖
//微信
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'

2.注册申请好的AppId到微信(必须在调用登录功能之前)

// APP_ID
private static final String APP_ID = "自己的appId";
api = WXAPIFactory.createWXAPI(context, APP_ID, true);

// 将应用的appId注册到微信
api.registerApp(APP_ID);

3.发送登录请求()

 SendAuth.Req req = new SendAuth.Req();
 req.scope = "snsapi_userinfo";
 req.state = "111";
 api.sendReq(req);

参数说明

来源: https://open.weixin.qq.com/cgi-bin/showdocument?action=doc&id=open1419317851&t=0.2650837650069082

参数 是否必须 说明
appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
scope 应用授权作用域,如获取用户个人信息则填写snsapi_userinfo( 什么是授权域? )
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

4.在项目包名下创建wxapi包并且创建WXEntryActivity,并且在AndroidManifest中配置,配置必须与下图中一致。

image.png



5.在WXEntryActivity中,实现 IWXAPIEventHandler 接口。在oncreate方法中注册回调

api.handleIntent(getIntent(), this);

如果不注册,则收不到回调(我刚开始没有注册该回调,导致一直收不到回调信息)。

6.在项目gradle中配置签名文件,必须与平台中的签名一致。

android {
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
    }

    debug{
        signingConfig signingConfigs.debug // 配置debug包的签名
    }
}

signingConfigs {
    debug {
        storeFile file("签名路径/debug.keystore")
        storePassword "android"
        keyAlias "androiddebugkey"
        keyPassword "android"
    }
}
}

到这里就集成成功了,我遇到的问题主要是没有注册回调,导致收不到信息。

关于WXEntryActivity中,实现 IWXAPIEventHandler 接口后,根据微信提供的文档以及业务需要继续下去就好了:

 @Override
public void onReq(BaseReq baseReq) {
    
}

@Override
public void onResp(BaseResp baseResp) {
Log.e(TAG, ((SendAuth.Resp) baseResp).code + 
"--" + ((SendAuth.Resp) baseResp).url + 
"--" + baseResp.getType() + 
"--" + baseResp.errCode + 
"--" + ((SendAuth.Resp) baseResp).state + 
"--" + ((SendAuth.Resp) baseResp).lang);
}

返回说明

用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。

返回值 说明
ErrCode ERR_OK = 0(用户同意) ERR_AUTH_DENIED = -4(用户拒绝授权) ERR_USER_CANCEL = -2(用户取消)
code 用户换取access_token的code,仅在ErrCode为0时有效
state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
lang 微信客户端当前语言
country 微信用户当前国家信息

第二步:通过code获取access_token

获取第一步的code后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

参数说明

参数 是否必须 说明
appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 填写第一步获取的code参数
grant_type 填authorization_code

返回说明

正确的返回:

{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN","openid":"OPENID", "scope":"SCOPE","unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"}
参数 说明
access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔
unionid 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段

错误返回样例:

{"errcode":40029,"errmsg":"invalid code"}

刷新access_token有效期

access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

1\. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;2\. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。

refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。

请求方法

获取第一步的code后,请求以下链接进行refresh_token:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

参数说明

参数 是否必须 说明
appid 应用唯一标识
grant_type 填refresh_token
refresh_token 填写通过access_token获取到的refresh_token参数

返回说明

正确的返回:

{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE"}
参数 说明
access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔

错误返回样例:

{"errcode":40030,"errmsg":"invalid refresh_token"}

注意:

1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

建议将Appsecret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。

第三步:通过access_token调用接口

获取access_token后,进行接口调用,有以下前提:

  1. access_token有效且未超时;
  2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。

对于接口作用域(scope),能调用的接口有以下:

授权作用域(scope) 接口 接口说明
snsapi_base /sns/oauth2/access_token 通过code换取access_token、refresh_token和已授权scope
/sns/oauth2/refresh_token 刷新或续期access_token使用
/sns/auth 检查access_token有效性
snsapi_userinfo /sns/userinfo 获取用户个人信息

其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。

接口调用方法可查阅《微信授权关系接口调用指南》

F.A.Q

1. 什么是授权临时票据(code)?

答:第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次保障了微信授权登录的安全性。第三方可通过使用https和state参数,进一步加强自身授权登录的安全性。

2. 什么是授权作用域(scope)?

答:授权作用域(scope)代表用户授权给第三方的接口权限,第三方应用需要向微信开放平台申请使用相应scope的权限后,使用文档所述方式让用户进行授权,经过用户授权,获取到相应access_token后方可对接口进行调用。

3.开放平台移动应用微信登录目前是否收费?

答:“微信登录”和第三方网站共享微信庞大的用户价值,同时为微信用户提供更便捷服务和更优质内容,实现双向共赢,目前不收取任何费用。

文章部分内容转载微信开放平台 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=60cf535dd0331502a793d5f32051b033b24b9e9d&lang=zh_CN

你可能感兴趣的:(Android 集成微信登录)