详解微信开发之Author网页授权

网友投稿 279 2023-06-25


详解微信开发之Author网页授权

微信YSkDuXqHG开发中,经常有这样的需求:获得用户头像、绑定微信号给用户发信息.. 那么实现这些的前提就是授权!

1.配置安全回调域名:

2.用户级授权和静默授权

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页。

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

3.网页授权access_token和普通access_token的区别

2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。

4.引导用户进入授权页面同意授权,获取code

微信更新后,授权页也变化了。其实习惯了绿色的那个经典页面..

js:

var center = {

init: function(){

.....

},

enterWxAuthor: function(){

var wxUserInfo = localStorage.getItem("wxUserInfo");

if (!wxUserInfo) {

var code = common.getUrlParameter('code');

if (code) {

common.getWxUserInfo();

center.init();

}else{

//没有微信用户信息,没有授权-->> 需要授权,跳转授权页面

http:// window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+ WX_APPID +'&redirect_uri='+ window.location.href +'&response_type=code&scope=snsapi_userinfo#wechat_redirect';

}

}else{

center.init();

}

}

}

$(document).ready(function() {

center.enterWxAuthor();

}

以scope=snsapi_userinfo为例,页面加载的时候进入授权方法,首先从缓存获取wxUserInfo对象,如果有说明之前已经授权过,直接进入初始化方法。如果没有,判断url是否包含code,有code说明是进入授权页回调后的页面,那么通过code换取用户信息即可。没有code,即用户第一次进入该页面,引导去授权页,redirect_uri为当前页面地址。

getWxUserInfo方法:

/**

* 授权后获取用户的基本信息

*/

getWxUserInfo:function(par){

var code = common.getUrlParameter("code");

if (par) code = par;

$.ajax({

async: false,

data: {code:code},

type : "GET",

url : WX_ROOT + "wechat/authorization",

success : function(json) {

if (json){

try {

//保证写入的wxUserInfo是正确的

var data = JSON.parse(json);

if (data.openid) {

localStorage.setItem('wxUserInfo',json);//写缓存--微信用户信息

}

} catch (e) {

// TODO: handle exception

}

}

}

});

},

5.后台restful-- /wechat/authorization,根据code换取用户信息

/**

* 微信授权

* @param code 使用一次后失效

*

* @return 用户基本信息

* @throws IOException

*/

@RequestMapping(value = "/authorization", method = RequestMethod.GET)

public void authorizationWeixin(

@RequestParam String code,

HttpServletRequest request,

HttpServletResponse response) throws IOException{

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

PrintWriter out = response.getWriter();

LOGGER.info("RestFul of authorization parameters code:{}",code);

try {

String rs = wechatService.getOauthAccessToken(code);

out.write(rs);

LOGGER.info("RestFul of authorization is successful.",rs);

} catch (Exception e) {

LOGGER.error("RestFul of authorization is error.",e);

}finally{

out.close();

}

}

这里有一个授权access_token,切记:授权access_token非全局access_token ,需要使用缓存,这里我使用的redis,具体配置不多说后面写相关配置博文,当然也可以使用ehcache,关于ehcahe配置在我的第一篇博客中有详细介绍。

/**

* 根据code 获取授权的token 仅限授权时使用,与全局的access_token不同

* @param code

* @return

* @throws IOException

* @throws ClientProtocolException

*/

public String getOauthAccessToken(String code) throws ClientProtocolException, IOException{

String data = redisService.get("WEIXIN_SQ_ACCESS_TOKEN");

String rs_access_token = null;

String rs_openid = null;

String url = WX_OAUTH_ACCESS_TOKEN_URL + "?appid="+WX_APPID+"&secret="+WX_APPSECRET+"&code="+code+"&grant_type=authorization_code";

if (StringUtils.isEmpty(data)) {

synchronized (this) {

//已过期,需要刷新

String hs = apiService.doGet(url);

JSONObject json = JSONObject.parseObject(hs);

String refresh_token = json.getString("refresh_token");

String refresh_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid="+WX_APPID+"&grant_type=refresh_token&refresh_token="+refresh_token;

String r_hs = apiService.doGet(refresh_url);

JSONObject r_json = JSONObject.parseObject(r_hs);

String r_access_token = r_json.getString("access_token");

String r_expires_in = r_json.getString("expires_in");

rs_openid = r_json.getString("openid");

rs_access_token = r_access_token;

redisService.set("WEIXIN_SQ_ACCESS_TOKEN", r_access_token, Integer.parseInt(r_expires_in) - 3600);

LOGGER.info("Set sq access_token to redis is successful.parameters time:{},realtime",Integer.parseInt(r_expires_in), Integer.parseInt(r_expires_in) - 3600);

}

}else{

//还没有过期

String hs = apiService.doGet(url);

JSONObject json = JSONObject.parseObject(hs);

rs_access_token = json.getString("access_token");

rs_openid = json.getString("openid");

LOGGER.info("Get sq access_token from redis is successful.rs_access_token:{},rs_openid:{}",rs_access_token,rs_openid);

}

return getOauthUserInfo(rs_access_token,rs_openid);

}

  /**

* 根据授权token获取用户信息

* @param access_token

* @param openid

* @return

*/

public String getOauthUserInfo(String access_token,String openid){

String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+ access_token +"&openid="+ openid +"&lang=zh_CN";

try {

String hs = apiService.doGet(url);

//保存用户信息

saveWeixinUser(hs);

return hs;

} catch (IOException e) {

LOGGER.error("RestFul of authorization is error.",e);

}

return null;

}

当时赶时间,代码命名较乱。可以看到,我用了一个同步的方法,先从缓存中获取key为WEIXIN_SQ_ACCESS_TOKEN,如果取到了说明没有过期,直接通过httpclient调用微信提供的接口,返回用户信息的字符串给前端。如果没有取到,说明没有或者已经过期,则根据refresh_token刷新access_token,再写缓存,由于access_token拥有较短的有效期,为了保险我这里设置了缓存的失效时间微信给的时间再减一个小时。回过头来看代码发现,上面的逻辑有点点小问题,这样写会导致第一次获取或者缓存失效后第一次获取access_token都会去刷新一次,暂时不影响使用,后面做优化修改 TODO。

6:保存用户信息

微信返回的值:

参考链接:

微信公众平台官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842&token=&lang=zh_CN

在线接口调试工具:http://mp.weixin.qq.com/debug


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Mybatis分页插件PageHelper的使用详解
下一篇:清除浏览器缓存的几种方法总结(必看)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~