小程序(3):授權登錄

小程序自身攜帶龐大流量基显,又提供了各種強大的API,今天只說授權登錄善炫。以前可以直接默認調起授權撩幽,最近在做的時候發(fā)現(xiàn)改版了,需要用戶手動觸發(fā)授權按鈕箩艺。

1摸航、login.wxml

<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo" class="weui-btn" type="primary" style='margin-top:15%'>授權登錄</button>
<view wx:else>請升級微信版本</view>

判斷是否授權,如果沒有舅桩,則顯示授權按鈕酱虎。注意上面的open-type="getUserInfo",這個會自動調起授權框擂涛《链看一下js

// pages/login/login.js
var util = require('../../utils/util.js');
Page({

  /**
   * 頁面的初始數(shù)據
   */
  data: {
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },

  bindGetUserInfo: function (e) {
    if (e.detail.userInfo) {
      // 登錄
      wx.login({
        success: res => {
          // 發(fā)送 res.code 到后臺換取 openId, sessionKey, unionId
          wx.request({
            url: '{你的https域名}/api/login/applet',
            data: { code: res.code },
            method: 'POST',
            header: { 'content-type': 'application/x-www-form-urlencoded' },
            success: function (res1) {
              wx.setStorageSync("sessionId", res1.data.data);
              wx.getUserInfo({
                success: res => {
                  // 可以將 res 發(fā)送給后臺解碼出 unionId
                  wx.request({
                    url: '{你的https域名}/api/login/user-info',
                    data: {
                      encryptedData: res.encryptedData,
                      iv: res.iv,
                      sessionId: wx.getStorageSync("sessionId")
                    },
                    method: 'POST',
                    header: { 'content-type': 'application/x-www-form-urlencoded' },
                    success: function (res1) {
                      wx.setStorageSync("storeMemberId", res1.data.data.id);
                      var member = res1.data.data;
                    //這里獲取到了用戶信息,可以執(zhí)行自己的操作
                      wx.switchTab({
                          url: '/pages/index/index',
                        })
                      
                    }
                  })
                }
              })
             
            }
          })
        }
      })
      //用戶按了允許授權按鈕
    } else {
      //用戶按了拒絕按鈕
      wx.redirectTo({
        url: '/pages/login/login',
      })
    }
  }
})

2撒妈、后臺獲取用戶信息

基本流程:拿到上面js獲取的code換取openid和session_key恢暖,如果你只需要openid,下面這一步就夠了狰右。
下面可以看到杰捂,我把獲取到的session_key放redis了,因為我需要用它獲取用戶詳情棋蚌。

    @ResponseBody
    @RequestMapping("applet")
    public ResultModel<String> login4applet(String code) {
        try {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + AppletInfo.appid + "&secret=" + AppletInfo.secret +
                    "&js_code=" + code + "&grant_type=authorization_code";

            String res = HttpClientUtil.post(url);
            Map<String,String> data = FastJsonUtils.toBean(res,Map.class);
            String openid = data.get("openid");
            String session_key = data.get("session_key");
            String sessionId = IDGen.genId();
            stringRedisTemplate.opsForValue().set(sessionId, session_key + "," + openid,7200,TimeUnit.SECONDS);
            return new ResultModel<>(ResultStatus.SUCCESS, sessionId);
        } catch (NormalException e) {
            return ResultModel.defaultError("授權失敗");
        }

    }

3嫁佳、換取用戶信息

第一步中第一個ajax請求后,又發(fā)送一次請求谷暮,三個參數(shù)
encryptedData: 加密數(shù)據
iv:偏移
sessionId: 上面第二步的sessionId蒿往,其實就是一個標識
通過sessionId取到上面存在redis中的sessionKey,因為官方建議最好不要直接傳輸這個湿弦,因此我用了本地緩存瓤漏。

    @ResponseBody
    @RequestMapping("user-info")
    public ResultModel<Member> getUserInfo(String sessionId, String iv, String encryptedData) {
        String sessionKeyAndOpenId = stringRedisTemplate.opsForValue().get(sessionId);
        if (StringUtil.isBlank(sessionKeyAndOpenId)) {
            throw new NormalException("登錄信息失效");
        }
        String sessionKey = sessionKeyAndOpenId.split(",")[0];
        // 被加密的數(shù)據
        try {
            byte[] dataByte = Base64.decode(encryptedData);
            // 加密秘鑰
            byte[] keyByte = Base64.decode(sessionKey);
            // 偏移量
            byte[] ivByte = Base64.decode(iv);
            String result = AESUtil.decrypt(dataByte, keyByte, ivByte);

            Map<String, String> map = FastJsonUtils.toBean(result, HashMap.class);
            if (map.get("openId") == null) {
                throw new NormalException("獲取用戶信息失敗");
            }

            //先判斷是否存在unionId
            String unionId =map.get("unionId");

            ResultModel<Member> resultModel = memberService.getByUnionId(unionId);
            Member member = resultModel.getData();
            if (member == null){

               
                String  openId = map.get("openId");
                member.setOpenId(openId);
                String avatarUrl = map.get("avatarUrl");
              
                member = new Member();
                member.setId(IDGen.genId());
                member.setUnionId(unionId);
                memberService.save(member);
            }

            return new ResultModel<>(ResultStatus.SUCCESS, member);
        } catch (NormalException e) {
            return new ResultModel<>(ResultStatus.FAIL, null);
        }
    }

此時我們已經獲取了用戶的openid,unionId(如果綁定了開放平臺的話)颊埃,頭像蔬充,昵稱,省市等信息班利,剩下的就自己隨便玩兒了

4饥漫、爬坑

既然寫代碼,沒坑怎么行肥败?
Q:報錯:invalid appid
A:可是建項目開始就綁定了appid啊趾浅,原來在通過code獲取session_key的時候,不小心發(fā)成了get請求馒稍。
ps:鄙視一下騰訊的同行皿哨,你這時候是不是提示method not support更合適呢?害的我找了半天bug~~~

其實整體來說根據api一步一步來還是沒什么問題的纽谒,就是他的文檔有的寫的確實有點坑证膨,希望踩過的童鞋一起來吐槽~~~

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鼓黔,隨后出現(xiàn)的幾起案子央勒,更是在濱河造成了極大的恐慌,老刑警劉巖澳化,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崔步,死亡現(xiàn)場離奇詭異,居然都是意外死亡缎谷,警方通過查閱死者的電腦和手機井濒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來列林,“玉大人瑞你,你說我怎么就攤上這事∠3眨” “怎么了者甲?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長砌创。 經常有香客問我虏缸,道長,這世上最難降的妖魔是什么嫩实? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任寇钉,我火速辦了婚禮,結果婚禮上舶赔,老公的妹妹穿的比我還像新娘扫倡。我一直安慰自己,他們只是感情好竟纳,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布撵溃。 她就那樣靜靜地躺著,像睡著了一般锥累。 火紅的嫁衣襯著肌膚如雪缘挑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天桶略,我揣著相機與錄音语淘,去河邊找鬼诲宇。 笑死,一個胖子當著我的面吹牛惶翻,可吹牛的內容都是我干的姑蓝。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼吕粗,長吁一口氣:“原來是場噩夢啊……” “哼纺荧!你這毒婦竟也來了?” 一聲冷哼從身側響起颅筋,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宙暇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后议泵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體占贫,經...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年先口,在試婚紗的時候發(fā)現(xiàn)自己被綠了靶剑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡池充,死狀恐怖桩引,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情收夸,我是刑警寧澤坑匠,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站卧惜,受9級特大地震影響厘灼,放射性物質發(fā)生泄漏。R本人自食惡果不足惜咽瓷,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一设凹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茅姜,春花似錦闪朱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至素标,卻和暖如春称诗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背头遭。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工寓免, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留癣诱,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓袜香,卻偏偏與公主長得像撕予,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子困鸥,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容

  • 一嗅蔬、遇到授權 最近開發(fā)微信小程序剑按,做登錄功能時遇到下圖疾就。 看太懂,有幾處疑惑地方: 同事告訴我這是認證和授權艺蝴,之前...
    dkvirus閱讀 14,672評論 3 21
  • 這算是我練習水彩以來的“大作”了猬腰,看原圖覺得挺難,猶豫了好久猜敢,沒想到畫下來還挺滿意姑荷。用的新剁手的白夜固彩和寶虹中粗...
    薇雨青蕪閱讀 995評論 15 34
  • 一鼠冕、1、作為參數(shù)傳遞2胯盯、作為函數(shù)的返回值3懈费、聲明成員變量 二、對象類型博脑?NSObjectidBOOLblockSE...
    光明程輝閱讀 584評論 1 2
  • 2017.9.27 晚兩位高三班主任找我聊天憎乙,檢查完宿舍后回復一位高三班主任的疑問。 2017.9....
    恭華閱讀 93評論 0 0