App接入微信登录以及支付(多端用户唯一标识之Unionid)

1 https://open.weixin.qq.com/ 注册开放平台

2 https://pay.weixin.qq.com/index.php/core/home/login? 注册 微信商户 认证之后 300块

3 创建应用 ,提交审核,通过之后会有微信支付 登录等 接入 300块

4 签名工具下载地址https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

微信 api 目录 : https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5

小程序及app实现双端合一的唯一标识
首先,简单说下我遇到的问题是我们的程序调用微信小程序得到openid,然后通过openID得到用户的唯一标识,用户得以登录,然而,当我们调用微信公众号也同样的到openid,同一用户两个不同的openid,不能区分是否为同一用户,然后发现无论调用微信小程序还是微信公众号同一个用户的到unionid是相同的,所以我们就用unionid来区分是否为同一用户。

UnionID机制说明:

如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

1、对于小程序获取unionid:

    我们一般都是先获取到微信的 unionid,然后再通过 unionid 去登录自己的网站,就可以关联到用户在自己网站上的 user_id,但是在小程序登录中,有时候可以获取到 unionid,有时候获取不到,在获取不到 unionid 的情况下,用户无法正常登录网站。

原因:同一个微信开放平台下的相同主体的 App、公众号、小程序,如果用户已经关注公众号,或者曾经登录过App或公众号,则用户打开小程序时,开发者可以直接通过 wx.login 获取到该用户UnionID,无须用户再次授权
(解读:用户如果没有登录过app,也没有登录过公众号,也没有关注过公众号的情况下,小程序中通过 wx.login 是获取不到 unionid的)

所有就有两种情况:

一般情况,用户登录过关联的其他公众号

使用 wx.login 获取code,传到后端,code换openid,unionId

   //1.login
   wx.login({
     success: function(data) {

       wx.request({
         url: openIdUrl,
         data: {
           code: data.code
         },
         success: function(res) {
           self.globalData.openid = res.data.openid
         },
         fail: function(res) {
           console.log('拉取用户openid失败,将无法正常使用开放接口等服务', res)
         }
       })

     },
     fail: function(err) {
       console.log('wx.login 接口调用失败,将无法正常使用开放接口等服务', err)
       callback(err)
     }
   })

用户没有用过关联的公众号等

这时候 wx.login 就获取不到 unionId 了。需要使用 wx.getUserInfo

解决思路:通过带登录态的 wx.getUserInfo 获取到用户的加密数据 encryptedData 和加密算法的初始向量iv,然后将 encryptdata、iv 以及 code传给后端,后端再去通过接收到的encryptedData、iv以、code 以及之前的 session_key 解密出用户的 openid、unionid 等

  wx.getUserInfo({
    withCredentials:false,
    success:(obj)=>{
     
        wx.request({
            url: openIdUrl,
            data: {
                code: data.code,
                encryptedData : obj.encryptedData,
                iv : obj.iv,
            },
            success: function(res) {
                self.globalData.openid = res.data.openid
            },
            fail: function(res) {
                console.log('拉取用户openid失败,将无法正常使用开放接口等服务', res)
            }
        })


    }
  })

实际项目中,需要将两种情况整合使用

两种方案:

第一种:( 前端判断是否有 unionid )wx.login 向后端上传 code 并且后端返回数据以后,前端判断返回值中是否有 unionid 或者 unionid 是否为 null,null 的情况下去调用带有用户登录态的wx.getUserInfo(),然后再将微信返回的 encryptedData 和 iv 返回给后端,后端解密出相应的信息后再返回给前端;

第二种:( 后端判断是否有 unionid )前端调用 wx.login(), wx.getUserInfo() ,把 code,encryptedData 和 iv 返回给后端,后端在拿到前端 code 之后去请求微信的接口拿 unionid,如果返回的 unionid 为空,再用的 encryptedData、iv以及之前的 session_key 解密出 unionid,后端解密出相应的信息后再返回给前端

1、 (JAVA 后台)向微信服务器发起请求附带js_code、appId、secretkey和grant_type参数,以换取用户的openid和session_key(会话密钥)

用code (前端调用微信接口得到)换取 session_key,openid

这是一个 HTTPS 接口,开发者服务器使用登录凭证 code 获取 session_key 和 openid。
其中 session_key 是对用户数据进行加密签名的密钥。为了自身应用安全,session_key 不应该在网络上传输。后台解密用到。

接口地址:

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

请求参数说明:

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

 Map<String, String> params = new HashMap<String, String>();
 params.put("appid", APPID);
 params.put("secret", SECRET);
 params.put("js_code", "js_Code");
 params.put("grant_type", "authorization_code");
 String openidtoken = HttpClientUtil.invokeGet(https://api.weixin.qq.com/sns/jscode2session, proxy, params,
 utf-8, 60000);

返回参数:

参数 说明
openid 用户唯一标识
session_key 会话密钥

2、AES解密核心代码:(包含用户敏感信息的encryptedData信息由前端提供,后台负责解密数据,得到unionId)

[java] view plain copy 
public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {  
    initialize();  
    try {  
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");  
        Key sKeySpec = new SecretKeySpec(keyByte, "AES");  
  
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化   
        byte[] result = cipher.doFinal(content);  
        return result;  
    } catch (NoSuchAlgorithmException e) {  
        e.printStackTrace();    
    } catch (NoSuchPaddingException e) {  
        e.printStackTrace();    
    } catch (InvalidKeyException e) {  
        e.printStackTrace();  
    } catch (IllegalBlockSizeException e) {  
        e.printStackTrace();  
    } catch (BadPaddingException e) {  
        e.printStackTrace();  
    } catch (NoSuchProviderException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    } catch (Exception e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }  

3、解密用户信息:

byte[] resultByte = Aes.decrypt(  
                        Base64.decodeBase64(encryptedData),  
                        Base64.decodeBase64(session_key),  
                        Base64.decodeBase64(ivByte));  
  
if (null != resultByte && resultByte.length > 0) {  
    String userInfo = new String(resultByte, "UTF-8");  
    // 结果转json  
    JsonObject jsonobject = null;  
    try {  
        JsonParser par = new JsonParser();  
        JsonElement jsonelement = par.parse(userInfo);  
        jsonobject = jsonelement.getAsJsonObject();  
    } catch (Exception e) {  
        。。。。。。  
    }  
    // 获取unionid  
    unionID = jsonobject.get("unionId").getAsString() + "";  
}  

注:String和字节数组之间的转换:

通过 Base64.decodeBase64(String)就可以得到字节数组。

通过 String userInfo = new String(resultByte, “UTF-8”); 就得到了想要的String

4、解密得到的结果:
加密过程微信服务器完成,解密过程在我们的服务器完成,即由 encryptData 得到如下数据:

 {
 "openId": "OPENID",
 "nickName": "NICKNAME",
 "gender": GENDER,
 "city": "CITY",
 "province": "PROVINCE",
 "country": "COUNTRY",
 "avatarUrl": "AVATARURL",
 "unionId": "UNIONID",
 "watermark":
 {
 "appid":"APPID",
 "timestamp":TIMESTAMP
 }
 }

5、把得到的unionId与用户的唯一标识绑定在一起,通过标识就可以进行下一步操作,系统不同,操作不同,这里不再详谈。

2、对于公众号获取unionId:

1、先拿code获取网页授权access_token以及openid

接口地址:

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

请求参数说明:

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

 Map<String, String> params = new HashMap<String, String>();
 params.put("appid", APPID);
 params.put("secret", SECRET);
 params.put("code", "Code");
 params.put("grant_type", "authorization_code");
 String openidtoken = HttpClientUtil.invokeGet(https://api.weixin.qq.com/sns/oauth2/access_token, proxy, params,
 utf-8, 60000);


 返回参数:
 { 
 "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           用户授权的作用域,使用逗号(,)分隔.

2、可以看到除access_token外,还可以获得openid,用拿到的access_token和openid获取unionID

接口地址:

https://api.weixin.qq.com/sns/userinfo?appid=APPID&secret=SECRET&code=JSCODE&grant_type=authorization_code

请求参数说明:

1 参数 是否必须 说明
2 access_token 是 接口调用凭证
3 openid 是 授权用户唯一标识
4 lang 否 一般为固定值zh_CN

 Map<String, String> params = new HashMap<String, String>();
 params.put("access_token", access_token);
 params.put("openid", openId);
 params.put("lang", "zh_CN");
 String openidtoken = HttpClientUtil.invokeGet(https://api.weixin.qq.com/sns/userinfo, proxy, params,
 utf-8, 60000);

在返回值里就包含有用户的unionID。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Unity接入微信小游戏登录SDK需要进行以下步骤: 1. 下载微信小游戏登录SDK:首先,从微信开放平台下载微信小游戏登录SDK的Unity插件,该插件包含了与微信小游戏服务器通信所需的脚本和配置文件。 2. 导入SDK插件:打开Unity项目,在Assets菜单中选择“Import Package” -> “Custom Package”,选择刚下载的微信小游戏登录SDK插件进行导入。 3. 配置游戏参数:在Unity编辑器中,在“Project”视图下找到WXEntryMenu,并打开进行配置。在配置中,要填写自己的微信小游戏AppIDAppSecret等参数。 4. 创建登录按钮:在Unity场景中,创建一个按钮对象,并添加一个脚本用于处理微信小游戏登录逻辑。在该脚本的代码中,调用微信小游戏登录SDK的接口,实现登录功能。 5. 处理登录回调:微信小游戏登录SDK提供了登录结果回调函数,开发者需要在自己的脚本中进行处理。根据回调结果,可以获取到用户的openidunionid等信息,进一步进行后续操作。 6. 测试登录功能:在Unity编辑器中,点击运行按钮,启动游戏。在游戏中点击登录按钮,会调起微信小游戏客户端进行登录。登录成功后,可以获取到用户的登录信息,并进行相应的游戏逻辑处理。 以上就是Unity接入微信小游戏登录SDK的基本步骤。开发者按照这些步骤进行操作,即可实现微信小游戏的登录功能,并在游戏中使用微信登录

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道1993

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值