打印 上一主题 下一主题

微信扫描登录

[复制链接]
跳转到指定楼层
楼主
发表于 2014-2-2 21:55:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
楼主
用户通过扫描网页提供的二维码实现登陆信息获取
% j" H+ b2 [1 }& ?" l. _; W) E" m, @
  1. <?php
    1 F  ], A( R$ h3 T# \6 @" o, ^
  2. /**1 w* u* b  H6 J* z+ `; {0 E8 A
  3. *  微信公众平台PHP-SDK7 u# y$ t3 `+ y: [4 {( s
  4. *  Wechatauth为非官方微信登陆API" |" b& Q" e. R' m9 j5 G- I- M" U
  5. *  用户通过扫描网页提供的二维码实现登陆信息获取* A! V/ V# f7 V$ c9 n0 q
  6. *  主要实现如下功能:
    $ X  Y" z; \2 L% r# J9 J5 k8 ~& P9 |
  7. *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
    " a+ t! h1 `% f8 ]! ~- D. _& e
  8. *  get_code_image($code='') 将上面获取的授权码转换为图片二维码$ A: Q  o+ `! n0 K) p+ Z
  9. *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
    ) Z, \- I2 S! H. F
  10. *  get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息4 v8 c: G1 h* l7 Z5 y
  11. *  sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息& @/ f( B  r- @. c
  12. *  get_avatar($url) 获取用户头像图片数据7 q1 S  l* Y( r* M7 r" J$ ?! e
  13. *  @author dodge <dodgepudding@gmail.com>. b' D/ d' c! G& P
  14. *  @link https://github.com/dodgepudding/wechat-php-sdk: {. _1 N; W6 s& O
  15. *  @version 1.1
    3 ]' E8 `: z( b% P( q
  16. *  
    3 f9 B4 }# k! ?3 m) S
  17. */
    3 P" }5 @/ z% S2 F- C
  18. include "snoopy.class.php";
    % ~, t! p6 c% I- r" d
  19. class Wechatauth3 S, P2 x( ^$ Z
  20. {3 c2 Q* ]% x6 |- l! U
  21.         private $cookie;
    " R! @5 h& O& O" u
  22.         private $_cookiename;
    " P0 V& G! S! r
  23.         private $_cookieexpired = 3600;- K7 o! L# W4 Q  W  Y
  24.         private $_account = 'test';5 p+ [* R9 ?  r
  25.         private $_datapath = './data/cookie_';
    . B# x6 C4 w) a! V; B6 r7 u+ ?
  26.         private $debug;1 ~9 d2 K: h% N1 F" W
  27.         private $_logcallback;& Q& ]; s- P# Q* I# }0 y
  28.         public $login_user; //当前登陆用户, 调用get_login_info后获取3 o9 v1 D, G5 w; j" U) b
  29.         
    5 P# K+ @. n0 G. e7 O
  30.         public function __construct($options)
    + [3 a! r: [7 r1 X
  31.         {) c$ Z- X+ X  b6 q% g! ?. \/ |) n
  32.                 $this->_account = isset($options['account'])?$options['account']:'';, R7 x' b, M1 B9 G, k
  33.                 $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
    $ X7 g% V+ o* F8 G+ `
  34.                 $this->debug = isset($options['debug'])?$options['debug']:false;
    8 d; q0 Y7 q5 m  I, z
  35.                 $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
    : n% t: g" }7 O  b* t
  36.                 $this->_cookiename = $this->_datapath.$this->_account;
    * x1 t$ ]+ g0 F3 f
  37.                 $this->getCookie($this->_cookiename);. z# @) E0 s- ~' D3 j
  38.         }4 I0 i" {7 Q9 m" o' E
  39.         /**4 {! l2 p) _. |/ U3 X2 B; S
  40.          * 把cookie写入缓存/ ?' O( A1 C9 i; D- d7 X7 M9 Q
  41.          * @param  string $filename 缓存文件名* D5 r- A9 F# X: r. F
  42.          * @param  string $content  文件内容3 m7 C/ ?. S1 O5 ]% e9 \. r
  43.          * @return bool0 H) w2 G, G2 o) d4 ^
  44.          */# c0 p! D. `0 D
  45.         public function saveCookie($filename,$content){8 B0 o: ?( D' V. O7 l( n
  46.                 return file_put_contents($filename,$content);  U7 M, t- \" L9 A
  47.         }5 L) M7 S  u/ p& D% Q' v8 P
  48. 4 I4 S6 C% T2 {1 |
  49.         /**
    3 {4 x1 T  s: V
  50.          * 读取cookie缓存内容
    8 Q/ c4 i3 H6 H+ E3 Z; h
  51.          * @param  string $filename 缓存文件名: M3 f# t9 U" m- ^
  52.          * @return string cookie
    4 b3 d2 R  D# m/ {
  53.          */
    6 O  L' j0 y. @# p1 I1 Z, [% G8 M
  54.         public function getCookie($filename){
    " [& r1 _# R5 j" ^* z
  55.                 if (file_exists($filename)) {0 v8 R. v0 d. H
  56.                         $mtime = filemtime($filename);3 p5 ], S: ^, }0 X- }( x
  57.                         if ($mtime<time()-$this->_cookieexpired) return false;# o. N, r, S- r! d/ d4 W( H2 ~
  58.                         $data = file_get_contents($filename);
    $ N, {6 B8 K8 m- s% _% ?) w% K
  59.                         if ($data) $this->cookie = $data;* n7 M/ X3 ]0 v5 c0 s* C/ H
  60.                 }
    ! H' i8 Y* L9 M  e5 H, n) }# b+ b/ z
  61.                 return $this->cookie;' N* b4 K; X' [: W0 ]9 p) I2 B
  62.         }. O3 l9 l: o4 l& v- V" b
  63.         
    + S7 {7 P; }' H2 n! J4 A8 l1 l
  64.         /*  [8 _. _% N2 V+ y8 g( _
  65.          * 删除cookie; e; D, O  R! e
  66.          */7 o1 n7 B* l. d
  67.         public function deleteCookie($filename) {
    # X7 c6 _" j  Q* s3 N
  68.                 $this->cookie = '';
    2 K: g( s- D7 m; n+ C
  69.                 @unlink($filename);
    # x! F; k4 j- S
  70.                 return true;
      G5 i9 M: v+ j. D+ |% a7 v
  71.         }
    3 s- U/ V* D- A, n
  72.         % d$ C' c! L: r3 z1 O6 |
  73.         private function log($log){3 k5 i! W1 L! J$ E
  74.                 if ($this->debug && function_exists($this->_logcallback)) {9 m5 z: d0 G) r: l1 f3 I7 {
  75.                         if (is_array($log)) $log = print_r($log,true);
    ! j$ b! G  l% a% ~/ G8 W# h+ `
  76.                         return call_user_func($this->_logcallback,$log);
      n) ?( j0 m( ^0 h  q! {
  77.                 }
    3 Z9 r6 c9 Y3 u7 \4 G2 z
  78.         }
    + n) N$ e. ~. |4 G" N
  79.         
    6 `* H" T4 \, i: U. W
  80.         /**
    / y0 {, I, K, y4 X! o* N
  81.          * 获取登陆二维码对应的授权码7 ^' E: O! S  {# n5 l& @
  82.          */+ j' b. D3 O! Q( g' p; `
  83.         public function get_login_code(){4 P0 R- r! x; Y* U
  84.                 if ($this->_logincode) return $this->_logincode;
    % z" T+ j$ ?2 X4 b
  85.                 $t = time().strval(mt_rand(100,999));
    ' \) ^/ y* }6 H! X7 ~3 l: v/ o2 J
  86.                 $codeurl = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$t;  @0 i$ q3 P. K1 c$ K: d
  87.                 $send_snoopy = new Snoopy; ( N/ a; y$ _0 c# o9 E
  88.                 $send_snoopy->fetch($codeurl);
    2 P1 [: m+ x4 C) R
  89.                 $result = $send_snoopy->results;4 g* f: s! K5 V7 v9 T; U6 g1 ?
  90.                 if ($result) {% V3 Z- O$ |2 D6 z* {  D" K& o+ H
  91.                         preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
    . ~8 J5 Y, I4 D
  92.                         if(count($matches)>1) {3 }* q" n# q, |" j( u
  93.                                 $this->_logincode = $matches[1];
    % ~; p) d* N8 r( E
  94.                                 $_SESSION['login_step'] = 0;
    0 t7 i& P9 r2 d; }2 B% n
  95.                                 return $this->_logincode;. p7 W& R8 h! a* o
  96.                         }( C% s# a- c6 E/ z. y. N
  97.                 }
    6 I; f, ~# a& m# r/ r0 m
  98.                 return $result;
    + u# `% m0 Y; I& Q
  99.         }
    " [& b  E  [% d; l1 o; e
  100. 2 Y$ |7 ~* E3 d$ Z1 i
  101.         /**
    1 M  H+ @5 Y" p& C1 z) t. _
  102.          * 通过授权码获取对应的二维码图片地址
    , }& z1 w$ E0 k  T1 j
  103.          * @param string $code5 j* b1 P" \5 k4 t' ]
  104.          * @return string image url
    7 o  z; s3 f7 b, c+ K: O; \/ e
  105.          */
    ' Y  F( w* K1 _
  106.         public function get_code_image($code=''){1 @+ w5 x/ }% g6 |. [
  107.                 if ($code=='') $code = $this->_logincode;
    9 {/ l+ X- t, B4 ~
  108.                 if (!$code) return false;( b) F5 J+ ~* W- o1 l  m
  109.                 return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
    1 ]7 z/ d  A/ A: L! |: i( N
  110.         }
    ! X% Q9 Y. }. ^) N5 {7 ]8 D8 C5 j
  111.         
    , t/ k# n  x& Y, r% e9 c" L  h
  112.         /**( u+ `* j+ w5 g$ y# B
  113.          * 设置二维码对应的授权码6 w- \. D$ h  e! ^) n) K& B
  114.          * @param string $code
    . l( r+ D: ^/ O- }- Z0 b
  115.          * @return class $this
    6 G" R, b' p6 S2 O$ ^
  116.          */
    : X% l# l5 H1 U5 s; V
  117.         public  function set_login_code($code) {% n( s4 h# G' y0 m/ r! o5 m# n0 Q
  118.                 $this->_logincode = $code;4 x$ ~! k, i) x1 H+ ^4 q
  119.                 return $this;& e3 [2 X7 T- Z# h- z5 l
  120.         }
    ! @2 O- B2 a) Q& I, F5 P
  121.         - O. I5 o2 R) P; V. `" H0 L* d/ v
  122.         /**
    , s7 Z& X/ {/ Q5 n% S
  123.          * 二维码登陆验证
    $ W$ S$ {4 X: x6 w; }
  124.          *: p6 G& x1 V7 @: Y
  125.          * @return status:
    5 @* E+ X2 Q2 S% i
  126.          * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired' B& ?2 m2 z7 p7 R, y- b: Z8 ^% l
  127.          * 201: just scaned but not confirm
    & E5 _4 I  [: f8 w
  128.          * 200: confirm then you can get user info* k* m2 s& k5 S- i
  129.          */5 f/ l3 t  ^! K( o9 v9 G1 g6 n
  130.         public function verify_code() {) ]; W2 |6 H9 R; C( q. u7 G
  131.                 if (!$this->_logincode) return false;
    : E' R& {( K' D2 w+ d" A4 x4 y
  132.                 $t = time().strval(mt_rand(100,999));6 t6 s6 {& T4 ~8 @+ P

  133. : U: [% Y' i/ X7 n9 I' O
  134.                         $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;' h9 h3 C: Q( F( K, p( b* B
  135.                         $send_snoopy = new Snoopy;
    9 N6 K, m9 r3 q" B8 ?  |
  136.                         $send_snoopy->referer = "https://wx.qq.com/";+ N" L: u9 H0 z, u
  137.                         $send_snoopy->fetch($url);
    0 Q( w: L* B! f9 y7 i" |+ }" x
  138.                         $result = $send_snoopy->results;9 U- X6 [1 P  O
  139.                         $this->log('step1:'.$result);0 f# ^" Z5 L7 z. `; n
  140.                         if ($result) {' n. X3 G+ N0 o' |  Z5 x
  141.                                 preg_match("/window\.code=(\d+)/",$result,$matches);& A1 k2 p  k% Q2 \3 @+ c: N6 t0 k
  142.                                 if(count($matches)>1) {+ w, {( \; |* `" e+ G1 }
  143.                                         $status = intval($matches[1]);' p0 |& X: N% S$ n* R0 S$ j
  144.                                         if ($status==201) $_SESSION['login_step'] = 1;! E7 M$ u, U6 S. E8 h
  145.                                         if ($status==200) {
    5 V8 ?: ^  s8 H! J: y; }( g6 w
  146.                                                 preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
    : }: o0 r' [' S: w
  147.                                                 $this->log('step2:'.print_r($matches,true));
    : a# \# G4 S7 e" Z4 c
  148.                                                 if (count($matches)>1) {. C! K& y7 _, b6 O
  149.                                                         $ticket = $matches[1];
    + A" [. D. C/ |' w9 g* g
  150.                                                         $scan = $matches[2];
    ) o  l* W6 E( e; q" R
  151.                                                         $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';* S1 w. \( @4 L, `
  152.                                                         $send_snoopy = new Snoopy; : u! ?' C! Z: Y& u* g/ r
  153.                                                         $send_snoopy->referer = "https://wx.qq.com/";) t0 P4 F; y" T* @+ {! V1 J) `3 w* O
  154.                                                         $send_snoopy->fetch($loginurl);
    6 G, R3 [& m6 H- a+ D/ w4 x
  155.                                                         $this->log('step3:'.print_r($send_snoopy->headers,true));
    : y% @) R$ k* g1 k  W) i" g8 U
  156.                                                         foreach ($send_snoopy->headers as $key => $value) {* ]- [+ O5 H& W: D0 s0 R
  157.                                                                 $value = trim($value);
    1 f1 C* J) z6 {( T' f
  158.                                                                 if(strpos($value,'Set-Cookie: ') !== false){5 x' D/ p) c+ r$ h8 z1 J. q% U
  159.                                                                         $tmp = str_replace("Set-Cookie: ","",$value);
    - B- L0 J+ z* ?
  160.                                                                         $tmp = str_replace("Path=/","",$tmp);2 z2 I( l5 `: C; Y) J
  161.                                                                         $tmp = str_replace("Domain=.qq.com; ","",$tmp);( _: b2 K8 g$ @! d. s3 k$ ]
  162.                                                                         $cookie.=$tmp;
    / \0 d7 n8 c& X' v  o
  163.                                                                 }( j+ ~3 x1 v. k  ]- }3 j! S$ S2 J% |* z
  164.                                                         }
    + k# A- ~' R1 `! _7 x8 f
  165.                                                         $cookie .="Domain=.qq.com;";
    4 B8 a, {* |9 \) ?( A4 U7 w
  166.                                                         $this->cookie = $cookie;
    - d- S9 D7 y8 j* b
  167.                                                         $this->saveCookie($this->_cookiename,$this->cookie);
    ) z# q7 n7 y- E, a+ T
  168.                                                 }; ~/ q- C! z) |$ v
  169.                                         }* e! v- ^4 q* \5 A0 `
  170.                                         return $status;, V( e4 ]" ~1 F2 J5 T: V( d
  171.                                 }
      R4 C0 s; K2 E
  172.                         }: g  p+ g$ S3 i6 W5 S; H# l
  173.                 return false;
      f' y) h8 i2 q8 d
  174.         }
    ( V0 J) x  I' _1 w
  175.         ' |- a) V: B- |$ c2 _; @
  176.         /**. L! @: J! P! I* {
  177.          * 获取登陆的cookie
    ' C& H3 U+ s; ^3 ]& i3 L
  178.          *2 [. N' u0 a; z& a$ O6 }6 F1 @0 \
  179.          * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
    4 n$ C$ k' R4 Z+ k: Z+ o
  180.          * @return string|array7 d* @8 o, `% ]: ]
  181.          */
    + \! \; c5 {3 B2 s& k8 h  g
  182.         public function get_login_cookie($is_array = false){
    8 J; D4 t# \3 z) m
  183.                 if (!$is_array)        return $this->cookie;8 _, o: I8 ]- n( f* c9 k0 ~+ c
  184.                 $c_arr = explode(';',$this->cookie);9 d; L6 \* |* k: z& E# k! z- ]
  185.                 $cookie = array();
    8 x3 ?& m: G3 s8 b$ `- Z
  186.                 foreach($c_arr as $item) {
    , u- k/ Z/ b+ F" s& D. a0 P& U4 z
  187.                         $kitem = explode('=',trim($item));
    ) z' c3 L0 U& M
  188.                         if (count($kitem)>1) {$ Q9 r6 P% {6 e- S5 {" Z& M
  189.                                 $key = trim($kitem[0]);8 {; |, g; w! K$ Z
  190.                                 $val = trim($kitem[1]);4 q& f; S$ n4 L$ ~& S
  191.                                 if (!empty($val)) $cookie[$key] = $val;  P  I8 Q4 [( x- D
  192.                         }
    ) p6 G: _5 w2 p
  193.                 }2 }7 d- A  g% W0 {) c3 l9 {" H
  194.                 return $cookie;
    * a" v( x* Q* T2 G
  195.         }
    ( R. ^) z0 F- {! w5 Y
  196.         
    4 y2 v0 a" r, I) w+ v/ s  D
  197.         /**: B7 n( q- \5 b, z" V. r; w
  198.          *          授权登陆后获取用户登陆信息9 i! J/ L9 i- M+ a$ {- g
  199.          */
    * N, G( Z3 j8 [8 }- d. G# }9 {* l4 s
  200.         public function get_login_info(){) o2 D" V- R. H$ h
  201.                 if (!$this->cookie) return false;
    8 E7 x/ a* p' x3 U. T( ^- F3 T
  202.                 $t = time().strval(mt_rand(100,999));
    4 L6 f% Y: l- `! j4 |2 g( H
  203.                 $send_snoopy = new Snoopy;
    $ g( y" {5 P- H( V
  204.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;) y" v2 p* a7 Y; g/ W, j
  205.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;  B; P" A0 d2 K/ Q: R  V" n& d
  206.                 $send_snoopy->referer = "https://wx.qq.com/";4 a6 L* \  x2 @7 S
  207.                 $send_snoopy->submit($submit,array());4 P7 l; t0 t4 [; n" D& d  J0 u1 t* w
  208.                 $this->log('login_info:'.$send_snoopy->results);+ |! M2 t: z0 o' c5 @, t
  209.                 $result = json_decode($send_snoopy->results,true);
    ( T" r: \9 L3 N. e: i: `4 w- F  ^. m
  210.                 if ($result['BaseResponse']['Ret']<0) return false;$ B1 k& A5 T1 {3 @. K8 N
  211.                 $this->_login_user = $result['User'];
    1 F# x* A# h0 `
  212.                 return $result;$ z  |" p8 b% K
  213.         }
    / H6 @- n  \8 W- L8 B6 s
  214.         9 X/ L! M, e5 }" a1 U% g( N
  215.         /**
    ' x: m  P$ H6 u& ^
  216.          *  获取头像& I1 K5 Q( K/ I2 P1 D- Q% q
  217.          *  @param string $url 传入从用户信息接口获取到的头像地址6 t0 O* {. L# b7 ]& B5 T5 i
  218.          */& X5 w" `$ j" P1 h% `! {) [
  219.         public function get_avatar($url) {( g# C! x8 d+ i5 R- G
  220.                 if (!$this->cookie) return false;
    % Q; }5 w9 x; l5 P  M/ y
  221.                 if (strpos($url, 'http')===false) {" o, A! P2 v# P+ T
  222.                         $url = 'http://wx.qq.com'.$url;
    1 v  d( _2 x* o; o
  223.                 }* d; b2 K& c; `
  224.                 $send_snoopy = new Snoopy; 9 M0 d) D( D+ a& o
  225.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;; A# v8 k% X  d% C, @3 E( [
  226.                 $send_snoopy->referer = "https://wx.qq.com/";# k3 W7 f$ S; k5 f
  227.                 $send_snoopy->fetch($url);
    # {+ w- F$ \6 K  u
  228.                 $result = $send_snoopy->results;
    & I% _* m; s8 ^0 ?
  229.                 if ($result) , I, C. F" _+ \) F- n$ M
  230.                         return $result;, z8 h3 @% g0 O# U! }
  231.                 else
      h  ?. m9 ?& a* l, Z1 B
  232.                         return false;
    ! }0 I6 C' B) M# q9 `: d
  233.         }
    + l% _& F7 k  U& s
  234.         
    & q: W' Z: I% t; j- ]1 Z( Y
  235.         /**; m: G. ~- a. M8 L! ^6 Q8 B8 P3 |
  236.          * 登出当前登陆用户
    ! |' s! G& I6 y- y2 V
  237.          */' L+ O* o/ I+ Q* A; A
  238.         public function logout(){8 @5 W& V5 `$ I: ?$ o
  239.                 if (!$this->cookie) return false;. c) F2 _3 s& }
  240.                 preg_match("/wxuin=(\w+);/",$this->cookie,$matches);" z3 h" K3 M' M/ L% P0 S
  241.                 if (count($matches)>1) $uid = $matches[1];
    ! Q4 p" `# c8 e, \9 @
  242.                 preg_match("/wxsid=(\w+);/",$this->cookie,$matches);( s# s/ k" N7 O/ S3 D- R% S& _
  243.                 if (count($matches)>1) $sid = $matches[1];
    3 u: g& v# A. O$ I7 O9 H0 U
  244.                 $this->log('logout: uid='.$uid.';sid='.$sid);1 J9 E( V9 h( u
  245.                 $send_snoopy = new Snoopy; 8 W7 n0 T& l7 G$ s3 k2 g
  246.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
    . Z( o; D% F. i4 H; T$ M  r
  247.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    6 O# @) l% P/ i3 b) u! P4 h* S
  248.                 $send_snoopy->referer = "https://wx.qq.com/";0 c) l5 q8 r. y7 G" h# |6 ]6 F
  249.                 $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
    / ]0 D6 r; W9 m. p+ o) C
  250.                 $this->deleteCookie($this->_cookiename);/ g7 D5 e) a8 t# c0 m! f
  251.                 return true;( n' ~. v$ u; ^' ^% O1 k
  252.         }% T) @! ~1 E% Q$ ]8 b* D+ {
  253. }
复制代码

" C, b& [- N& r




上一篇:[Discuz插件] Discuz!微信登录插件配置前提
下一篇:Emacs逆袭:开发微信公众平台小游戏
回复

使用道具 举报

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

快速回复 返回顶部 返回列表