一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|

服務器之家 - 編程語言 - JAVA教程 - 詳解微信開發之Author網頁授權

詳解微信開發之Author網頁授權

2020-07-11 14:05liliangel JAVA教程

微信開發中,經常有這樣的需求:獲得用戶頭像、綁定微信號給用戶發信息,那么實現這些的前提就是授權!本文對此進行系統介紹,需要的朋友一起來看下吧

微信開發中,經常有這樣的需求:獲得用戶頭像、綁定微信號給用戶發信息.. 那么實現這些的前提就是授權!

1.配置安全回調域名:

詳解微信開發之Author網頁授權

在微信公眾號請求用戶網頁授權之前,開發者需要先到公眾平臺官網中的“開發 - 接口權限 - 網頁服務 - 網頁帳號 - 網頁授權獲取用戶基本信息”的配置選項中,修改授權回調域名,值得注意的是這里就是直接寫全域名,如: 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

詳解微信開發之Author網頁授權

微信更新后,授權頁也變化了。其實習慣了綠色的那個經典頁面..

js:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
   * 授權后獲取用戶的基本信息
   */
  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換取用戶信息

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * 微信授權
 * @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配置在我的第一篇博客中有詳細介紹。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
   * 根據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!

微信返回的值:

詳解微信開發之Author網頁授權

參考鏈接:

微信公眾平臺官方文檔: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

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持服務器之家!

原文鏈接:http://www.cnblogs.com/liliangel/p/6045201.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美精品v日韩精品v国产精品 | 天天操婷婷 | 国产精品99精品久久免费 | 国产精品亚洲va在线观看 | 消息称老熟妇乱视频一区二区 | 亚洲国产综合另类视频 | 欧美成人tv | 成人au免费视频影院 | 糖心在线观看网 | 香蕉eeww99国产精选播放 | 俄罗斯海滩厕所偷窥 | 欧美兽皇video | 98成人| 视频大全在线观看网址 | 日韩成人精品在线 | 青青视频国产依人在线 | 国产特级毛片aaaaaa | 亚洲 欧美 日韩 综合 | 国产精品免费_区二区三区观看 | 男人操男人 | 女人张开腿让男人做爽爽 | 美女张开腿让男人桶的 视频 | 国产爽视频 | 美女把小内内脱个精光打屁屁 | 国产aaa伦理片 | 亚洲www在线| nxgx在线观看国产中文 | 情欲满载2012美国dvd | 精品久久洲久久久久护士免费 | 亚洲黄色免费在线观看 | 男女性刺激爽爽免费视频 | 日韩精品一区二区三区中文字幕 | 深夜在线观看网站 | 欧美一级专区免费大片俄罗斯 | 国产123区在线视频观看 | 午夜国产精品影院在线观看 | 亚洲 欧美 国产 视频二区 | 欧美一级特黄刺激大片视频 | 毛片网站免费观看 | 久久精品免视看国产 | 男人狂躁女人下面狂叫图片 |