1. 程式人生 > >微信PC二維碼登陸的一種思路

微信PC二維碼登陸的一種思路

一、思路:

思路關鍵在於如何與微信端互動起來,畢竟目前微信登入只能是在微信端。
但是微信有一個特殊的方法用於生成自定義的二維碼,這就讓我們能夠在PC上顯示二維碼,而二維碼的值可以是我們定義的。另外看微信開發文件中存在一個scan事件,可以檢測使用者使用微信掃描二維碼並獲取值。其實問題的關鍵就在於這個值,這個值算是一個聯通PC和微信的通訊ID了。

二、具體實現流程(下面程式碼使用了TP5的框架,有個大前提是存在一個服務號的公眾號)

1、生成PC端的二維碼:

程式碼如下:
控制器:

namespace app\home\controller;

class Recognition
extends Base{
public function seeLoginQrcode(){ $qrcode_return = model('Recognition')->getLoginQrcode(); if($qrcode_return['error_code']){ return $this->returnJson("獲取失敗!",0); }else{ $data=array( 'url'=>$qrcode_return['ticket'
], 'qrcode_id'=>$qrcode_return['id'], ); return $this->returnJson("獲取成功!",1,$data); } } }

model:

namespace app\common\model;

use think\Model;
class Recognition extends Model{
    protected $autoWriteTimestamp = false;
    //生成登入用的臨時二維碼
public function getLoginQrcode(){ $appid = config('THINK_SDK_WEIXIN.APP_KEY'); $appsecret = config('THINK_SDK_WEIXIN.APP_SECRET'); if(empty($appid) || empty($appsecret)){ return(array('error_code'=>true,'msg'=>'請聯絡管理員配置【AppId】【 AppSecret】')); } $database_login_qrcode = model('LoginQrcode'); $database_login_qrcode->where(array('add_time'=>array('lt',($_SERVER['REQUEST_TIME']-604800))))->delete(); $data_login_qrcode['add_time'] = $_SERVER['REQUEST_TIME']; $database_login_qrcode->save($data_login_qrcode); $qrcode_id = $database_login_qrcode->getLastInsID(); if(empty($qrcode_id)){ return(array('error_code'=>true,'msg'=>'獲取二維碼錯誤!無法寫入資料到資料庫。請重試。')); } import('Net.Http'); $http = new \Http(); //微信授權獲得access_token $access_token_array = model('AccessTokenExpires')->getAccessToken(); if ($access_token_array['errcode']) { return(array('error_code'=>true,'msg'=>'獲取access_token發生錯誤:錯誤程式碼' . $access_token_array['errcode'] .',微信返回錯誤資訊:' . $access_token_array['errmsg'])); } $access_token = $access_token_array['access_token']; $qrcode_url='https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.$access_token; $post_data['expire_seconds'] = 604800; $post_data['action_name'] = 'QR_SCENE'; $post_data['action_info']['scene']['scene_id'] = $qrcode_id; $json = $http->curlPost($qrcode_url,json_encode($post_data)); if (!$json['errcode']){ $condition_login_qrcode['id']=$qrcode_id; $data_login_qrcode['id'] = $qrcode_id; $data_login_qrcode['ticket'] = $json['ticket']; if($database_login_qrcode->isUpdate(true)->save($data_login_qrcode)){ return(array('error_code'=>false,'id'=>$qrcode_id,'ticket'=>'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($json['ticket']))); }else{ $database_login_qrcode->where($condition_login_qrcode)->delete(); return(array('error_code'=>true,'msg'=>'獲取二維碼錯誤!儲存二維碼失敗。請重試。')); } }else{ $condition_login_qrcode['id'] = $qrcode_id; $database_login_qrcode->where($condition_login_qrcode)->delete(); return(array('error_code'=>true,'msg'=>'發生錯誤:錯誤程式碼 '.$json['errcode'].',微信返回錯誤資訊:'.$json['errmsg'])); } } }

可以看到成功後返回:

return(array('error_code'=>false,'id'=>$qrcode_id,'ticket'=>'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($json['ticket'])));

其中有一個id值,其實代表的就是二維碼的值!
然後ticket就是二維碼的連結。也就是掃描這個二維碼在scan事件獲取的值就是這個id。

下面檢視微信端處理

1、掃描二維碼之後:

namespace app\mobile\controller;

class Wechat extends Base{

    public function index()
    {
        import('Wechat.Wechat');
        $wechat = new \Wechat();
        $data = $wechat->request();
        list($content, $type) = $this->reply($data);
        if ($content) {
            $wechat->response($content, $type);
        }
        else {
            exit();
        }
    }
    public function reply($data)
    {
        if ($data['MsgType'] == 'event') {
            $id = $data['EventKey'];
            switch (strtoupper($data['Event'])) {
                case 'SCAN':
                    return $this->scan($id, $data['FromUserName']);
                case 'CLICK':
                    //回覆?
                    return array('click', 'text');
                    break;
                case 'SUBSCRIBE':
                    //關注
                    return array('Welcome', 'text');
                    break;
                case 'UNSUBSCRIBE':
                    //取關

                    return array('BYE-BYE', 'text');
                case 'LOCATION':
                    //定位

                    break;
            }
        }
        else {
            if ($data['MsgType'] == 'text') {
                return array("測試成功!",'text');
            }

            if ($data['MsgType'] == 'location') {

            }

            if (import('@.ORG.' . $data['MsgType'] . 'MessageReply')) {

            }
        }

        return false;
    }
    private function scan($id, $openid = '', $issubscribe = 0)
    {
        if ((1000000000 < $id) && $openid) {
             if ($user = model('Member')->field('id')->where(array('third_id' => $openid))->find()) {
                 $data=array(
                     'id'=>$id,
                     'uid'=> $user['id']
                 );
                 model('LoginQrcode')->isUpdate()->save($data);
                 return array('登陸成功', 'text');
             }
             $data=array(
                 'id'=>$id,
                 'uid'=>-1
             );
             model('LoginQrcode')->isUpdate(true)->save($data);
            $return[] = array('點選授權登入', '',config('SITE_LOGO'), config('SITE_URL') . '/mobile/WechatBind/ajaxWebLogin?qrcode_id=' . $id);
            return array($return, 'news');
        }
    }
}

上面的Scan方法有這個判斷,可以看到是:

if ((1000000000 < $id) && $openid) {

其中的$id,就是對應的二維碼的值,也就是之前我們生成的那個id(其實我們為了區分Scan中的各種事件,特意將id所在的login_qrcode表自增id從1000000000開始)。
然後看if後面的處理:

if ($user = model('Member')->field('id')->where(array('third_id' => $openid))->find()) {
                 $data=array(
                     'id'=>$id,
                     'uid'=> $user['id']
                 );
                 model('LoginQrcode')->isUpdate()->save($data);
                 return array('登陸成功', 'text');
             }

如果滿足條件,並且存在該openid的使用者,則更新login_qrcode表,將uid改為使用者id。(這裡就是關鍵,為什麼更新了id對應的那條資料的uid為使用者id就算登入了呢)。

3、繼續看PC端,PC段在獲取1中的二維碼之後並沒有停止請求,而是輪訓了一個方法:

* 微信登入非同步請求
     * @return \think\response\Json
     * created by sunnier<[email protected]126.com>
     */
    public function ajaxWechatLogin(){
            for ($i = 0; $i < 6; $i++) {
                $database_login_qrcode = model('LoginQrcode');
                $condition_login_qrcode['id'] = input('get.qrcode_id');
                if(empty($condition_login_qrcode['id'])){
                    return $this->returnJson('未獲取到qrcode_id!',0);
                }
                $now_qrcode = $database_login_qrcode->field('`uid`')->where($condition_login_qrcode)->find();
                if (!empty($now_qrcode['uid'])) {
                    if ($now_qrcode['uid'] == -1) {
                        $data_login_qrcode['uid'] = 0;
                        $database_login_qrcode->where($condition_login_qrcode)->isUpdate(true)->save($data_login_qrcode);
                        return $this->returnJson('請在微信公眾號點選授權登入!',0);
                    }
                    $database_login_qrcode->where($condition_login_qrcode)->delete();
                    $result = model('Member')->autologin('id', $now_qrcode['uid']);
                    if (empty($result['error_code'])) {
                        return $this->returnJson('登入成功!',1,$result['user']);
                    } else if ($result['error_code'] == 1001) {
                        return $this->returnJson('沒有查詢到使用者,請重新掃描二維碼!',0);
                    } else if ($result['error_code']) {
                        return $this->returnJson('登陸失敗!',0);
                    }
                }
                if ($i == 5) {
                    return $this->returnJson('登陸失敗',0);
                }
                sleep(3);
            }
    }

可以看到上面方法獲取了qrcode_id,也就是1中返回的那個id,另一個返回就是二維碼了。
輪訓過程就是用這個id不斷檢視login_qrcode表的狀態,如果存在了uid那麼證明登陸成功!也就可以用其中的uid自動登入了。

4、以上

關鍵就是login_qrcode這個中間表起了橋樑的作用,一邊用來生成二維碼,一邊用來在微信端插入使用者uid,同時PC端檢測表的狀態變化從而實現了登入。

三、程式碼倉庫

https://git.oschina.net/kebenxiaoming/erwmlogin

直接clone即可,有問題提issue或者單獨私我

相關推薦

PC登陸思路

一、思路: 思路關鍵在於如何與微信端互動起來,畢竟目前微信登入只能是在微信端。 但是微信有一個特殊的方法用於生成自定義的二維碼,這就讓我們能夠在PC上顯示二維碼,而二維碼的值可以是我們定義的。另外看微信開發文件中存在一個scan事件,可以檢測使用者使用微信掃

支付native原生支付開發模式

開發前,商戶必須在公眾平臺後臺設定支付回撥URL。URL實現的功能:接收使用者掃碼後微信支付系統回撥的productid和openid;URL設定詳見回撥地址設定。 1.業務流程時序圖 圖6.8:原生支付介面模式一時序圖 業務流程說明: 1)商戶後

掃描登錄網站技術原理

js對象 hit 適合 ace pass 文件 head src get 微信掃描二維碼登錄網站 網站應用微信登錄開發指南 微信掃描二維碼登錄網站是微信開放平臺下網站應用的一種接口實現的功能。微信開放平臺的網址是 https://open.weixin.qq.com 準

收款怎麼做?多個合併收款!

我有幾個微訊號,可以同時收款嗎?當然,使用這個方法,簡單又安全,直接在微信裡就可以操作! 上傳不同的微信收款碼,合成一個微信收款活碼,收款碼隨機展示。 ① 好處 智慧切換,打破收款限額,讓您收款更高效 將幾個微信收款碼合併在一起,隨機分配給客戶掃碼付款

java後臺獲取分享 並返回給前端

最近公司業務需求 微信小程式需要分享 從後臺請求生成二維碼圖片 並顯示 給大家分享一下 經驗 第一步 :獲得 微信token(這個token兩個小時會過期 所以需要token生成相對應的二維碼) String wxspAppid = "yourAppid";

動態生成支付

實現步驟 一、開發前奏 開發工具:eclipse jar管理:maven 資料庫:oracle 架構:SpringMvc + Spring +Mybatis 微信公眾號:企業號(個人訂閱號和公眾測試號無此許可權) 二、開發步驟 1、開發前請先檢視文件微信掃碼支付流程,統一下單

掃描參與拼團,搶1折好課

sha vpd .com text mar alt 分享圖片 微信 掃描二維碼 長按或掃描二維碼即可參與咯~ 搶1折好課 微信掃描二維碼參與拼團,搶1折好課

下載apk跳轉瀏覽器開啟的方式(及遮蔽下載解決方案)

需求:想讓使用者在微信掃描二維碼或者點選就能下載APP,並統計被掃描次數。 兩種實現方法: 1.一般我們用草料生成二維碼,如果沒有註冊的話只能生成一個包含下載網址的靜態碼,沒有統計功能,而且出了自己截圖儲存外,草料是不會儲存你的二維碼的。 如果註冊草料後,可以選擇生成活碼。所謂活碼,就是一個指向頁面,然

掃描網頁跳轉顯示資訊

新建EngineeringPower.html,裡面包含工程動力各專業網格化分工的表格資訊,是一個表格。<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title

下載-遮蔽下載解決方案

需求:想讓使用者在微信掃描二維碼或者點選就能下載APP,並統計被掃描次數。 兩種實現方法: 1.一般我們用草料生成二維碼,如果沒有註冊的話只能生成一個包含下載網址的靜態碼,沒有統計功能,而且出了自己截圖儲存外,草料是不會儲存你的二維碼的。 如果註冊草料後,可以選擇生成活碼。所謂活碼,就是一個指向頁面,然

渠道

功能細節描述:1、本功能呼叫的是公眾號“帶引數的二維碼”介面,僅限認證的服務號使用;2、生成的二維碼是永久二維碼,累計最多可生成10萬個(微信規定的上限數);3、生成的渠道二維碼,每一個二維碼的引數都不相同,但是關注都是同一個公眾號(您的服務號);4、每一個渠道二維碼可以設定

關於 下載apk 的方法

   最近在弄微信掃描二維碼直接下載,記錄下。 有兩種方式,1、掃面後展示 應用在應用寶的 資訊 ;2、微信掃描二維碼後,直接跳轉到對應瀏覽器,並且直接彈出下載框 方式一 1、應用上傳 應用寶 2、進入騰訊開放平臺的管理中心,找到對應應用,進入詳情後,找到 微下載,見下圖

生成認證網頁

一.引入相關jar <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>2.

QRCode 掃描、掃描條形碼、相簿獲取圖片後識別、生成帶 Logo 、支援 QQ 掃描樣式

目錄功能介紹根據之前公司的產品需求,參考 barcodescanner 改的,希望能幫助到有生成二維碼、掃描二維碼、識別圖片二維碼等需求的猿友。修改幅度較大,也就沒準備針對 barcodescanner 庫提交PR。 ZXing 生成可自定義顏色、帶 logo 的二維碼 ZX

第三方掃描登入

微信二維碼掃描登入 最近做了微信二維碼掃描登入的工作。實則非常簡單。 其實就是各種介面互相呼叫,收取引數跳頁的過程。不過不熟練 的情況下,會比較麻煩,無從下手。從查閱開發文件到工作

遮蔽下載APK 手機APP應用 如何解決

很多朋友的APP推廣連結需要在微信中進行的網頁宣傳、傳播、下載等等,但是各位朋友一定發現了微信中是遮蔽掉了APP的下載連結的。但是微信最為一個最大的社交平臺,為了自身的利益,遮蔽掉了所有APK的下載連結。我們要怎麼解決這個問題呢? 解決方案: 我們基於微信介面開發了一款全

生成長按識別

1.引入JS庫 <script src="jquery-1.8.3.js" type="text/javascript" charset="utf-8"></script> <script src="jquery.qrcode.min.js"

掃描跳轉頁面

最近在完成一個大作業,反正一個小部分就是掃描二維碼,跳轉到一個介面去,搜網上也沒有什麼太有用的資訊,覺得難死了。。 後來想想,以前寫過一個程式,就是把字串生成相應的二維碼,然後我就抱著試試看的心態,把url 放進去,掃一下看看,結果,成功了。。。瞎貓碰著死老鼠,真幸運~~

高仿仿介面掃描效果 之 Android 基於google Zxing實現、條形碼掃描

    絕大多數android開發者都是使用google Zxing來實現二維碼、條形碼掃描,但官方和網上很多demo的掃描介面讓人不忍直視,今天我也做了一個,介面和執行效都是高仿微信最新版的掃描效果,執行效果圖如下: 主要是修改了ViewfindView類,我就不多解

js / 前端 / 支付寶,合併功能

支付寶,微信合併二維碼 近期專案要優化支付頁面,希望將兩個二維碼合成一個。研究整理一下: 首先做這件事,要明白原理哦: 網站的支付功能,一般都是生成一個( 後臺大哥與支付寶或微信介面授權好了的ur