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

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

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

没有公众号福利:测试账号申请 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • 微信开发之网页授权获取用户信息(二)

    在公众号的配置过程中,许多开发者会在菜单中加入HTML5页面,有时在页面内需要访问页面的用户信息,此时就需要网页授权获取用户基本信息 我们提醒大家:本文介绍讲述的内容是基于yii2.0框架 1.设置授权回调域名:开发 ---> 接口权限 找到"网页授权获取用户基本信息",点击后面对应的"修改",在弹框响应位置填写授权回调域名即可,此处的域名不需要加http:// (关于网页授权回调域名的说明详情可参考公众平台开发者文档) 2.获取授权 关于OAuth2.0博主

  • 微信开发 网页授权获取用户基本信息

    微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使用这个的时候失败了或者无法理解其内容,希望我出个教程详细讲解一下,于是便有了这篇文章. 一.什么是OAuth2.0 官方网站:http://oauth.net/   http://oauth.net/2/ 权威定义:OAuth is An open protocol to allow secure authorization in a simple and standard method

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

    微信开发中,经常有这样的需求:获得用户头像.绑定微信号给用户发信息.. 那么实现这些的前提就是授权! 1.配置安全回调域名: 在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的"开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息"的配置选项中,修改授权回调域名,值得注意的是这里就是直接写全域名,如: www.liliangel.cn.然而我们开发h5中一般用的是二级域名,如:h5.liliangel.cn 也同样在安全回调域名中. 2.用户级授权

  • 详解微信开发之access_token之坑

    首先不得不提到access_token的分类,一是普通access_token,二是网页授权access_token.其中前者是用于调用微信提供的各种借口,作为开发者的调用凭证,一般有效期为7200S,获取次数受限:另一种是第三方网页若需要使用用户微信账户登录,需要获取该access_token从而来获取用户微信账户信息.这个一定得区分开. 另外获取用户微信账户信息也有两种情况,一是普通的获取用户信息,它只需要调用微信用户信息接口即可获取,因而使用到的是第一种普通access_token,另一种

  • 详解 Corba开发之Java实现Service与Client

    详解 Corba开发之Java实现Service与Client 1      概述 CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)是由OMG组织制订的一种标准的面向对象应用程 序体系规范.或者说 CORBA体系结构是OMG为解决分布式处理环境(DCE)中,硬件和软件系统的互连而提出的一种解决方案. OMG:Object Management Group,对象管理组织.是一个国际化的.开放成员的.非盈利性的计算机行业标准协

  • 详解微信小程序开发用户授权登陆

    本篇将帮助读者实现基于 微信开发者工具 & C#环境 下的用户在小程序上的授权登陆. 准备: 微信开发者工具下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 微信小程序开发文档:https://developers.weixin.qq.com/miniprogram/dev/index.html 开发: 在开发之初,我们需要先明确微信方已经制定好的授权登陆流程,参看 官方API - 登陆接口.

  • 实例详解IOS开发之UIWebView

    iOS开发之UIWebView 是本文要介绍的内容,UIWebView是iOS sdk中一个最常用的控件.是内置的浏览器控件,我们可以用它来浏览网页.打开文档等等.这篇文章我将使用这个控件,做一个简易的浏览器.如下图: 我们创建一个Window-based Application程序命名为:UIWebViewDemo UIWebView的loadRequest可以用来加载一个url地址,它需要一个NSURLRequest参数.我们定义一个方法用来加载url.在UIWebViewDemoViewC

  • 详解Android开发之MP4文件转GIF文件

    一 基本实现原理 在介绍具体实现过程之前,先简单说下基本原理和实现步骤,在解决相对比较复杂的问题,我习惯先理清主要原理步骤,不要一开始就被繁琐细节绊住,待具体实现时再逐个攻破.下面是主要步骤: 1.视频文件的读取:包括录制和本地文件读取 2.将需要转换的视频部分解析为 Bitmap 序列 3.将解析好的 Bitmap 序列编码生成 GIF 文件 二 视频文件的读取 视频文件的读取比较简单,没什么特别需要说的地方,这里简单贴出视频读取的核心部分代码,详细实现可以Google一下就行了. priva

  • 详解iOS开发之NSURLProtocol的那些坑

    NSURLProtocol NSURLProtocol能够让你去重新定义苹果的URL加载系统 (URL Loading System)的行为,URL Loading System里有许多类用于处理URL请求,比如NSURL,NSURLRequest,NSURLConnection和NSURLSession等,当URL Loading System使用NSURLRequest去获取资源的时候,它会创建一个NSURLProtocol子类的实例,你不应该直接实例化一个NSURLProtocol,NSU

  • 详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现

    详解微信开发中snsapi_base和snsapi_userinfo及静默授权的实现 snsapi_base与snsapi_userinfo属于微信网页授权获取用户信息的两种作用域 snsapi_base只能获取access_token和openID snsapi_userinfo可以获取更详细的用户资料,比如头像.昵称.性别等 首先,这里的access_token与基础access_token(比如自定义菜单用到的)是不一样的.两者区别如下: 网页授权的access_token在每次获取ope

  • .NET微信开发之PC 端微信扫码注册和登录功能实现

    一.前言 先声明一下,本文所注重点为实现思路,代码及数据库设计主要为了展现思路,如果对代码效率有着苛刻要求的项目切勿照搬. 相信做过微信开发的人授权这块都没少做过,但是一般来说我们更多的是为移动端的网站做授权,确切来说是在微信端下做的一个授权.今天遇到的一个问题是,项目支持微信端以及 PC 端,并且开放注册.要求做到无论在 PC 端注册或者是在微信端注册之后都可以在另外一个端进行登录.也就是说无论 PC 或是微信必须做到"你就是你"(通过某种方式关联). 二.寻找解决方案 按传统的方式

  • 详解微信小程序 登录获取unionid

    详解微信小程序 登录获取unionid 首先公司开发了小程序, 公众号网页和app等, 之前都是用的openid来区分用户, 但openid只能标识用户在当前小程序或公众号里唯一, 我们希望用户可以在公司各个产品(比如公众号, 小程序, app里的微信登录)之间, 可以保持用户的唯一性, 还好微信给出了unionid. 下面分两步介绍一下 微信小程序 获取unionid的过程. 1. 首先 在微信公众平台注册小程序 , 然后在小程序上模拟登录流程. 注 : 这里只是简单登录流程, 实际中需要维护

随机推荐