色总的微信小程序开发记录(一)--获取openid

微信小程序开发记录(一)--获取openid

  • 通过微信登录凭证code获取openid
    • 获取微信登录凭证code
      • 小程序前端的示例代码
    • 到微信服务器换取微信用户身份openid
      • 小程序后端的示例代码

遇到的项目是微信小程序后台,登陆是后台自己的账号验证逻辑,要求将微信和已存在的平台账号关联起来。关于微信小程序的注册和配置,请到微信公众平台查看。这里不进行记录。

通过微信登录凭证code获取openid

获取微信登录凭证code

首先说到登录,微信为了防止黑客获取黑客伪装成任意身份来操作获取任意账户下的数据,所以使用wx.login方法,只要在小程序前端调用wx.login方法就会生成一个带有时效性的凭证,就像是一个会过期的临时身份证一样,在wx.login调用时,会先在微信后台生成一张临时的身份证,其有效时间仅为5分钟。然后把这个临时身份证返回给小程序方,这个临时的身份证我们把它称为微信登录凭证code。如果5分钟内小程序的后台不拿着这个临时身份证来微信后台服务器换取微信用户id的话,那么这个身份证就会被作废,需要再调用wx.login重新生成登录凭证。
在wx.login的success回调中拿到微信登录凭证,紧接着会通过wx.request把code传到开发者服务器,为了后续可以换取微信用户身份id。如果当前微信用户还没有绑定当前小程序业务的用户身份,那在这次请求应该顺便把用户输入的帐号密码一起传到后台,然后开发者服务器就可以校验账号密码之后再和微信用户id进行绑定。

小程序前端的示例代码

//小程序前端的示例代码:
loginas:function(){
 	wx.login({
        success: function(res) {
          if (res.code) {
            	wx.request({
		              url: 'http://localhost:8088/ankeWxSmall/login/manualBindAccount',//自己的后台登陆地址   
		              method: 'POST',//指定使用的post请求
		              header: {  //拼装需要的header,form表单提交
		                'content-type': 'application/x-www-form-urlencoded'
		             },      
	               	data: { //传送的数据
		                code:res.code,//wx.login获取到的code
		                username: 'phr', // 用户输入的账号
		                password: '12345678' // 用户输入的密码
	               	},
	              	success: function(res) {
	                	if (res.statusCode === 200) {
	                      	console.log(res.data.message)// 服务器回包内容,格式根据返回内容决定
	                	}
	              	}
            	});
        }else {
            console.log('获取用户登录态失败!' + res.errMsg);
   		}
	  }
  });
}

到微信服务器换取微信用户身份openid

将code,username,password信息传递给开发者的后台,就拿到了前边wx.login()所生成的微信登录凭证code,此时就可以拿这个code到微信服务器换取微信用户身份。微信服务器为了确保拿code过来换取身份信息的人就是刚刚对应的小程序开发者,到微信服务器的请求要同时带上AppId和AppSecret,这两个信息在小程序管理平台的开发设置界面可以看到,由此可以看出,AppId和AppSecret是微信鉴别开发者身份的重要信息,AppId是公开信息,泄露AppId不会带来安全风险,但是AppSecret是开发者的隐私数据不应该泄露,如果发现泄露需要到小程序管理平台进行重置AppSecret,而code在成功换取一次信息之后也会立即失效,即便凭证code生成时间还没过期。
开发者服务器和微信服务器通信也是通过HTTPS协议,微信服务器提供的接口地址是:

https://api.weixin.qq.com/sns/jscode2session?appid=AppId&secret=AppSecret&js_code=code&grant_type=authorization_code

URL的query部分的参数中 AppId, AppSecret, code 就是前文所提到的三个信息,请求参数合法的话,接口会返回以下字段

字段 描述
openid 微信用户的唯一标识
session_key 会话密钥
unionid 用户在微信开放平台的唯一标识符。本字段在满足一定条件的情况下才返回。

小程序后端的示例代码

Controller接收

 /**
     * 开放接口--手动绑定账号
     * @param code
     * @param username
     * @param password
     * @return
     */
    @ResponseBody
    @ApiOperation(value="手动绑定账号", response = SimpleMessage.class)
    @RequestMapping(value = "/manualBindAccount" ,method = RequestMethod.POST)
    public SimpleMessage manualBindAccount(@RequestParam String code,@RequestParam String username,@RequestParam String password){
        return loginService.manualBindAccount(code,username,password);
    }

ServiceImpl实现

	@Value("${spring.wx.jsCode2session}")
    private String jsCode2session;
    
	@Override
    public SimpleMessage manualBindAccount(String code, String username, String password) {
        String msg=null;
        logger.info("获取code-----------------{}", code);
        if(StringUtils.isBlank(code)){
            msg = "code为空";
        }else {
            try {
                //第一步---账号密码登陆
                Map<String, String> map = new HashMap<String, String>();
                UserInfoWx userInfo = loginMapper.getUserInfoByUserName(username,password);//这里就是自己的账号密码验证方法。
                if(userInfo==null){
                    msg = "用户名或密码错误!";
                }else {
                        //第二步---根据code获取openId
                        String url = jsCode2session + "?appid=" + AppId + "&secret=" + AppSecret + "&js_code=" + code + "&grant_type=" + grantType;//拼装换取微信用户身份url,grantType="authorization_code",为常值。jsCode2session=https://api.weixin.qq.com/sns/jscode2session
                        //到微信服务器换取微信用户身份id
                        JSONObject userObject = ConnectUtil.HttpGet(url);//封装的get请求,获取微信用户对象
                        if (userObject != null) {
                            String openid = userObject.getString("openid");//用户唯一标识
                            String session_key = userObject.getString("session_key");  //会话密钥-未使用
                            if (StringUtils.isEmpty(openid)) {
                                msg = "未获取到openid";
                            } else {
                                //第三步---添加关系
                                //将获取的的openid和登陆验证成功的账号信息关联起来,保存在数据库中。略过。。。
                                return SimpleMessage.info("成功");
                            }
                        }
                    }
                }
            }catch (Exception e){
                msg=e.getMessage();
            }
        }
        return SimpleMessage.warn(msg);
    }

你可能感兴趣的:(微信,小程序)