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

1.配置安全回调域名:

在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名,值得注意的是这里就是直接写全域名,如: www.liliangel.cn。然而我们开发h5中一般用的是二级域名,如:h5.liliangel.cn 也同样在安全回调域名中。
 
 

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

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页。
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。 
 

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

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权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{
//没有微信用户信息,没有授权-->> 需要授权,跳转授权页面
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:保存用户信息

通常情况下,授权后我们会将用户信息保存数据库表,openid为唯一主键,外键关联起我们自己的用户表,这样一来,无论是后续要开展什么业务,还是做运营数据统计,都有了一个跟微信公众号的关联关系。值得注意的是:我们获取到的headimgurl是微信提供的一个url地址,当用户修改头像后可能导致原来的地址失效,所以最好是通过将图片保存到本地服务器然后保存本地的地址url!
微信返回的值:

参考链接:

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

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

微信网页授权,获取微信code,获取access_tocken,获取用户信息的更多相关文章

  1. 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP)

    wechat github 手把手实现微信网页授权和微信支付,附源代码(VUE and thinkPHP) 概述 公众号开发是痛苦的,痛苦在好多问题开发者文档是没有提到的,是需要你猜的. 在开发过程中 ...

  2. VueJs单页应用实现微信网页授权及微信分享功能

    在实际开发中,无论是做PC端.WebApp端还是微信公众号等类型的项目的时候,或多或少都会涉及到微信相关的开发,最近公司项目要求实现微信网页授权,并获取微信用户基本信息的功能及微信分享的功能,现在总算 ...

  3. 服务号使用微信网页授权(H5应用等)

    获取授权准备 AppId 服务号已经认证且获取到响应接口权限 设置网页授权域名 公众号设置 - 功能设置 - 网页授权域名.注意事项: 回调页面域名或路径需使用字母.数字及"-"的 ...

  4. php 微信登录 公众号 获取用户信息 微信网页授权

    php 微信登录 公众号 获取用户信息 微信网页授权 先自己建立两个文件: index.php  和  getUserInfo.php index.php <?php //scope=snsap ...

  5. Java微信公众平台开发(十六)--微信网页授权(OAuth2.0授权)获取用户基本信息

    转自:http://www.cuiyongzhi.com/post/78.html 好长时间没有写文章了,主要是最近的工作和生活上的事情比较多而且繁琐,其实到现在我依然还是感觉有些迷茫,最后还是决定静 ...

  6. 微信网页授权多次回调code请求

    最近在做微信网页授权的时候遇到一个问题如果直接从后台把微信授权的url参数什么的拼装好,然后直接redirect 这个url 会导致时不时的多次请求回调的url .网上说是因为网络原因,如果10s没有 ...

  7. 玩玩微信公众号Java版之六:微信网页授权

    我们经常会访问一些网站,用微信登录的时候需要用到授权,那么微信网页授权是怎么一回事呢,一起来看看吧!   参考官方文档:https://mp.weixin.qq.com/wiki?t=resource ...

  8. 微信网页授权,错误40163,ios正确,安卓错误?

    2017-07-29:结贴昨天研究了半天,也没解决,看到出错的http头里面有PHPSESSID,回头去修改了一下程序里的session部分的代码(这部分代码在微信网页授权之后),,也不知道是腾讯那边 ...

  9. 微信网页授权access_token与基础支持的access_token

    问题1:网页授权access_token与分享的jssdk中的access_token一样吗? 答:不一样.网页授权access_token 是一次性的,而基础支持的access_token的是有时间 ...

随机推荐

  1. 2019-2020-2 20174318张致豪《网络对抗技术》Exp1 PC平台逆向破解

    Exp1_PC平台逆向破解 前期准备 一.逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数 ...

  2. DEV GridControl控件使用(CheckBox全选、操作按钮、事件处理,获取值)

    1.GridControl控件使用 (1)绑定数据源 //绑定DataTable gridControl1.DataSource = DbHelper.ExecuteDataTable("S ...

  3. PageRank 算法初步了解

    前言 因为想做一下文本自动摘要,文本自动摘要是NLP的重要应用,搜了一下,有一种TextRank的算法,可以做文本自动摘要.其算法思想来源于Google的PageRank,所以先把PageRank给了 ...

  4. def跨域+jwt

    1.跨域 由于浏览器具有“同源策略”的限制.如果在同一个域下发送ajax请求,浏览器的同源策略不会阻止.如果在不同域下发送ajax,浏览器的同源策略会阻止. 总结 域相同,永远不会存在跨域. crm, ...

  5. 利用mnist数据集进行深度神经网络

    初始神经网络 这里要解决的问题是,将手写数字的灰度图像(28 像素 x28 像素)划分到 10 个类别中(0~9).我们将使用 MINST 数据集,它是机器学习领域的一个经典数据集,其历史几乎和这个领 ...

  6. mongo密码的设置

    MongoDB 版本 v4.0.7 系统 Win10 注意: 要为数据库创建用户,必须先切换到相应的数据库: 要为数据库创建用户,必须先切换到相应的数据库: 要为数据库创建用户,必须先切换到相应的数据 ...

  7. (转)协议森林10 魔鬼细节 (TCP滑窗管理)

    协议森林10 魔鬼细节 (TCP滑窗管理) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在TCP协议与"流" ...

  8. VS配置C++依赖包

    处理好三个东西 1.头文件,Configuration Properties → VC++ Directories → Include Directories 2.静态库,Configuration ...

  9. Netty源码分析一<序一Unix网络I/O模型简介>

    Unix网络 I/O 模型   我们都知道,为了操作系统的安全性考虑,进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer.以下 ...

  10. 面向对象第四单元(UML)及期末总结

    前言 统一建模语言(英语:Unified Modeling Language,缩写 UML),是软件架构设计建模和规约的语言. 在UML系统开发中有三个主要的模型: 功能模型:从用户的角度展示系统的功 ...