微信移動應(yīng)用掃描登陸記錄

功能概述

掃碼登錄能力裆装,指的是開發(fā)者可在移動應(yīng)用內(nèi)使用此能力,拉取二維碼排作,用戶使用微信客戶端掃描二維碼后可以登錄此移動應(yīng)用。此能力可被應(yīng)用在多設(shè)備登錄亚情、智能硬件妄痪、電視盒子等場景。

第一步:

很簡單楞件,就是先創(chuàng)建應(yīng)用衫生,集成微信SDK。

第二步:

開始寫代碼土浸,首先APP通過IDiffDevOAuth.auth()接口發(fā)起授權(quán)罪针,然后在OAuthListener.onAuthGotQrcode()回調(diào)接口中獲取二維碼,在APP中展示二維碼黄伊,最后用戶通過微信掃碼泪酱,授權(quán)。

    lateinit var oauth: IDiffDevOAuth
    override fun onCreate(savedInstanceState: Bundle?) {
        //初始化oauth
        oauth = DiffDevOAuthFactory.getDiffDevOAuth()
    }

    override fun onDestroy() {
        super.onDestroyView()
        oauth.removeAllListeners()
        oauth.detach()
    }

初始化完成后还最,就要掉接口了墓阀。
接口
IDiffDevOAuth
boolean auth(String appId, String scope, String noncestr, String timestamp, String signature, OAuthListener listener)

參數(shù)說明

參數(shù) 是否必須 說明
appId 應(yīng)用唯一標(biāo)識
scope 應(yīng)用授權(quán)作用域,擁有多個作用域用逗號(,)分隔拓轻,APP所擁有的scope
noncestr 一個隨機(jī)的盡量不重復(fù)的字符串斯撮,用來使得每次的signature不同
timestamp 時間戳
signature 簽名
listener 授權(quán)流程,回調(diào)接口

appId:自己上應(yīng)用上查看悦即。
scope:snsapi_userinfo吮成,官方demo中的snsapi_login和snsapi_base沒用橱乱,使用后會報一般錯誤。
noncestr:使用MD5加密一串隨機(jī)值

    private fun getNonceStr(): String {
        val r = Random(System.currentTimeMillis())
        return EncryptUtils.encryptMD5ToString((Constant.WXAPPID + 
        r.nextInt(10000) + System.currentTimeMillis()).toByteArray())
    }

timestamp:獲取當(dāng)前時間戳就行

    private fun getTimestamp(): String {
        return System.currentTimeMillis().toString()
    }

signature:官方說明:生成簽名之前必須先獲取對應(yīng)的sdk_ticket粱甫。
sdk_ticket是用于生成簽名的臨時票據(jù)泳叠。正常情況下,sdk_ticket的有效期為7200秒茶宵,通過access_token來獲取危纫。由于獲取sdk_ticket的api調(diào)用次數(shù)非常有限,頻繁刷新sdk_ticket會導(dǎo)致api調(diào)用受限乌庶,影響自身業(yè)務(wù)种蝶,開發(fā)者需在自己的服務(wù)存儲與更新sdk_ticket。

  1. 先獲取token,grant_type參數(shù)固定填client_credential瞒大,另兩個參數(shù)在微信開放平臺應(yīng)用上獲取螃征。
    /**
     * 微信獲取Token
     */
    @GET("https://api.weixin.qq.com/cgi-bin/token")
    Observable<WXTokenEntity> getWXToken(
            @Query("grant_type") String type,//固定值client_credential
            @Query("appid") String appID,
            @Query("secret") String appSecret
    );

正常返回
{"access_token":"ACCESS_TOKEN","expires_in":7200}
錯誤返回(該示例為AppID無效錯誤)
{"errcode":40013,"errmsg":"invalid appid"}

image.png

官方地址

  1. 獲取到token之后,再請求sdk_ticket透敌,type固定值2
    /**
     * 微信獲取Ticket
     */
    @GET("https://api.weixin.qq.com/cgi-bin/ticket/getticket")
    Observable<WXTicketEntity> getTicket(
            @Query("access_token") String token,
            @Query("type") int type
    );

成功返回

{
    "errcode":0,
    "errmsg":"ok",
    "ticket":"-p3A5zVP95IuafPhzA6lRR95_F9nZEBfJ_n4E9t8ZFWKJTDPOwccVQhHCwDBmvLkayF_jh-m9HOExhumOziDWA",
    "expires_in":7200
}
  1. 成功拿到ticket后盯滚,按簽名規(guī)則生成簽名。
    簽名生成規(guī)則如下:
    參與簽名的字段包括第三方appid酗电,noncestr(隨機(jī)字符串), 有效的sdk_ticket, timestamp(時間戳) 魄藕。
    對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1撵术。這里需要注意的是所有參數(shù)名均為小寫字符背率。對string1作sha1加密,字段名和字段值都采用原始值嫩与,不進(jìn)行URL 轉(zhuǎn)義寝姿。即signature=sha1(string1)。
    示例:
    appid=appid
    noncestr=noncestr
    sdk_ticket=-p3A5zVP95IuafPhzA6lRR95_F9nZEBfJ_n4E9t8ZFWKJTDPOwccVQhHCwDBmvLkayF_jh-m9HOExhumOziDWA
    timestamp=1417508194
    1.對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后蕴纳,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1:
    appid=appid&noncestr=noncestr&sdk_ticket=-p3A5zVP95IuafPhzA6lRR95_F9nZEBfJ_n4E9t8ZFWKJTDPOwccVQhHCwDBmvLkayF_jh-m9HOExhumOziDWA&timestamp=1417508194
    2.對string1進(jìn)行sha1簽名会油,得到signature:
    429eaaa13fd71efbc3fd344d0a9a9126835e7303
    private fun getSignature(noncestr: String, timestamp: String, sdk_ticket: String): String {
        val str = "appid=${Constant.WXAPPID}&noncestr=$noncestr&sdk_ticket=$sdk_ticket&timestamp=$timestamp"
        return EncryptUtils.encryptSHA1ToString(str)
    }

注意這里是用SHA1加密的

  1. 最后調(diào)用接口
 override fun auth(ticket: String) {
        val noncestr = getNonceStr()
        val timestamp = getTimestamp()
        val signature = getSignature(noncestr, timestamp, ticket)

        val authRet = oauth.auth(Constant.WXAPPID, "snsapi_userinfo", noncestr,
                timestamp, signature, object : OAuthListener {
            /**
             * 用戶點(diǎn)擊授權(quán)后,回調(diào)改接口
             */
            override fun onAuthFinish(errCode: OAuthErrCode?, authCode: String?) {
                Timber.tag("OAuthListener").i("onAuthFinish,OAuthErrCode->$errCode ,authCode->$authCode")

                val tips: String = when (errCode) {
                    OAuthErrCode.WechatAuth_Err_OK -> "登錄成功,code=$authCode"
                    OAuthErrCode.WechatAuth_Err_NormalErr -> "登錄失敗,一般錯誤"
                    OAuthErrCode.WechatAuth_Err_NetworkErr -> "登錄失敗,網(wǎng)絡(luò)錯誤"
                    OAuthErrCode.WechatAuth_Err_JsonDecodeErr -> "json解碼失敗"
                    OAuthErrCode.WechatAuth_Err_Cancel -> "用戶取消"
                    OAuthErrCode.WechatAuth_Err_Timeout -> "登錄失敗古毛,超時錯誤"
                    else -> ""
                }
                Timber.tag("OAuthListener").i(tips)
            }

            /**
             * auth之后返回的二維碼接口
             *
             * @param qrcodeImgPath 廢棄
             * @param imgBuf 二維碼圖片數(shù)據(jù)
             */
            override fun onAuthGotQrcode(qrcodeImgPath: String?, imgBuf: ByteArray?) {
                Timber.tag("OAuthListener").i("imgBuf->$imgBuf")
                if (imgBuf != null) {
                    val bitmap = BitmapFactory.decodeByteArray(imgBuf, 0, imgBuf.size)
                    onUiThread {
                        img_wx.setImageBitmap(bitmap)
                    }
                }
            }

            /**
             * 用戶掃描二維碼之后翻翩,回調(diào)改接口
             */
            override fun onQrcodeScanned() {
                Timber.tag("OAuthListener").i("onQrcodeScanned")
            }

        })
        Timber.tag("OAuthListener").i("authRet->$authRet")
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市稻薇,隨后出現(xiàn)的幾起案子嫂冻,更是在濱河造成了極大的恐慌,老刑警劉巖塞椎,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桨仿,死亡現(xiàn)場離奇詭異,居然都是意外死亡案狠,警方通過查閱死者的電腦和手機(jī)服傍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門钱雷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吹零,你說我怎么就攤上這事罩抗。” “怎么了灿椅?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵套蒂,是天一觀的道長。 經(jīng)常有香客問我茫蛹,道長操刀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任婴洼,我火速辦了婚禮骨坑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘柬采。我一直安慰自己卡啰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布警没。 她就那樣靜靜地躺著,像睡著了一般振湾。 火紅的嫁衣襯著肌膚如雪杀迹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天押搪,我揣著相機(jī)與錄音树酪,去河邊找鬼。 笑死大州,一個胖子當(dāng)著我的面吹牛续语,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厦画,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼疮茄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了根暑?” 一聲冷哼從身側(cè)響起力试,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎排嫌,沒想到半個月后畸裳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淳地,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年怖糊,在試婚紗的時候發(fā)現(xiàn)自己被綠了帅容。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡伍伤,死狀恐怖并徘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嚷缭,我是刑警寧澤饮亏,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站阅爽,受9級特大地震影響路幸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜付翁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一简肴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧百侧,春花似錦砰识、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辛润,卻和暖如春膨处,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背砂竖。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工真椿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乎澄。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓突硝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親置济。 傳聞我的和親對象是個殘疾皇子解恰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容