微现场IM互动

标题: 微信扫描登录 [打印本页]

作者: eoiioe    时间: 2014-2-2 21:55
标题: 微信扫描登录
用户通过扫描网页提供的二维码实现登陆信息获取
8 W$ J1 V; c6 a4 J) U$ b
  1. <?php
    ; c8 P: h  o! |- G8 H
  2. /**$ V0 t' p' E# k3 V6 j
  3. *  微信公众平台PHP-SDK- Q0 U: o( g( ?- ~3 R+ Z& a) Q
  4. *  Wechatauth为非官方微信登陆API& d$ ?+ E1 ^$ ]( h# ^# A% _9 G
  5. *  用户通过扫描网页提供的二维码实现登陆信息获取! p1 J+ z2 A6 a3 I
  6. *  主要实现如下功能:
    ! O. @+ m/ m4 _. i& j
  7. *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码' T" V6 S1 u3 l  Z4 A( l
  8. *  get_code_image($code='') 将上面获取的授权码转换为图片二维码
    2 y7 o; I4 j' u2 d. r) j
  9. *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
    8 N% E4 l8 b/ F: v+ ^! D2 N$ T
  10. *  get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息
    / J) [& ~$ E$ h! \  O  P
  11. *  sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息% g+ o+ H2 j) A8 {8 k
  12. *  get_avatar($url) 获取用户头像图片数据
    - D& q/ q9 ^/ l# F% J' U" Z
  13. *  @author dodge <dodgepudding@gmail.com>6 ]6 A4 f; E$ O- o: K" t3 x: L
  14. *  @link https://github.com/dodgepudding/wechat-php-sdk# d$ k* b  \8 @) a, f! o) W
  15. *  @version 1.1, n! O3 A- E0 `3 k! l& D+ T
  16. *  
    8 b: ?* x- n: Z7 p
  17. */3 u, o6 k1 E! g  e- [1 L
  18. include "snoopy.class.php";! G% q) K; P0 Z4 }+ E/ {
  19. class Wechatauth
    & }# s  M; H0 \) ]
  20. {/ ]1 k4 r! \: ~7 Y2 A
  21.         private $cookie;( n4 P: p8 O6 E( B
  22.         private $_cookiename;$ A* e) U# u" C  v9 u5 |
  23.         private $_cookieexpired = 3600;
    6 c0 p4 X8 m. K! ?  J4 ]( [
  24.         private $_account = 'test';% n5 G' N" `8 V# ~; f0 D% h0 u4 ?
  25.         private $_datapath = './data/cookie_';6 r8 L6 K9 U4 a9 T3 X1 E
  26.         private $debug;( Q* V( v1 ~3 B! J, `
  27.         private $_logcallback;7 m  y# G, a2 z1 a! y
  28.         public $login_user; //当前登陆用户, 调用get_login_info后获取1 g/ J$ G4 S2 U& T4 q% I
  29.         
    # i0 q# |/ x' I0 ^9 ?! d
  30.         public function __construct($options)
    1 u7 [9 U% ~4 `# B. b0 S
  31.         {8 b6 W  E, c: q( }8 x
  32.                 $this->_account = isset($options['account'])?$options['account']:'';- W* H- P: W: B  {( g" ^
  33.                 $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;! ?! L' M6 t! L" H& M$ ^) H' Q2 O
  34.                 $this->debug = isset($options['debug'])?$options['debug']:false;
    , y0 B  h( G  B# W
  35.                 $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;& Y' q3 w  r- q
  36.                 $this->_cookiename = $this->_datapath.$this->_account;
    0 e' J7 ]0 ~. [& Q3 b+ Z
  37.                 $this->getCookie($this->_cookiename);
    $ G6 @$ u8 g; W+ o
  38.         }
    8 S; z$ w- V4 Q( F
  39.         /**, ^, E7 }5 r5 i3 y2 B
  40.          * 把cookie写入缓存; |( R) c$ ]5 O; H9 G) j
  41.          * @param  string $filename 缓存文件名
    ) x8 U* L( I" N" @1 p9 p2 h, Y/ _8 T
  42.          * @param  string $content  文件内容
    + C" |& `, \' X( J9 y2 y
  43.          * @return bool
    . O( H8 r; |) ^. V
  44.          */
    . U: B: Q  \8 I6 Q1 U" O
  45.         public function saveCookie($filename,$content){
    " I' t+ m& K" I+ ]
  46.                 return file_put_contents($filename,$content);: {, A/ O% U9 q1 n1 x. z
  47.         }/ t1 [( M  D. n- U+ O3 R. S6 e) i
  48. * ]$ Y: }1 k3 B* C
  49.         /**
    5 u+ e2 E: s- Z; m4 L
  50.          * 读取cookie缓存内容4 Q) o3 i  d" b* X* b$ P" O6 D
  51.          * @param  string $filename 缓存文件名
    * m: h4 u& O# w% [4 |- e
  52.          * @return string cookie
    $ d- Y& t4 R& i: @0 s9 e2 f7 N
  53.          */  y! x4 m+ p3 C$ M3 c; I
  54.         public function getCookie($filename){8 S4 w3 O1 A: v* h
  55.                 if (file_exists($filename)) {( ^$ O! f7 C, f$ l3 z0 b2 g
  56.                         $mtime = filemtime($filename);7 I& ?1 c0 U/ N7 Q6 A7 Q' e+ [
  57.                         if ($mtime<time()-$this->_cookieexpired) return false;' q# g) `& Y1 ^+ c
  58.                         $data = file_get_contents($filename);: P# T( I4 ]/ \. O3 G+ S4 h4 w. K
  59.                         if ($data) $this->cookie = $data;
    8 X% W4 }6 D5 u+ q8 W
  60.                 } 6 x* q. O( z) d. S2 N
  61.                 return $this->cookie;
    , q7 @6 L  T) z) R
  62.         }
    ( l- A# R- q/ J- I
  63.         / K5 Z+ O0 B3 Y  l5 K+ C2 b5 W
  64.         /*
    + H5 Q& I3 g! P; K; x; ~0 `
  65.          * 删除cookie3 |# M7 \; j: o$ j1 ?, t, p
  66.          */9 ~1 w2 K& A1 h" a- e+ |
  67.         public function deleteCookie($filename) {" f. W/ T) s# Q, x. F' G4 y: e' c' c4 k
  68.                 $this->cookie = '';
    2 z+ E% B2 F  j! J2 M
  69.                 @unlink($filename);, f3 \( K2 D0 K/ m) f$ k
  70.                 return true;+ l- M. T; D' b
  71.         }2 ^6 D# ^/ A% g2 ?  Q* v/ B; b
  72.         3 I. a2 X) ^; X$ G- \
  73.         private function log($log){# B) f6 v+ z5 N1 c4 F
  74.                 if ($this->debug && function_exists($this->_logcallback)) {
    ) n7 x" G) ^2 |9 O" i
  75.                         if (is_array($log)) $log = print_r($log,true);
    " B+ {$ _0 k5 x* |* }: s
  76.                         return call_user_func($this->_logcallback,$log);
    2 `# m. g+ m' i: h: j* ^
  77.                 }$ t4 b0 r; o! _2 ~: a" ?1 R
  78.         }
    * V3 r/ k' a/ [  g7 }; {  ~
  79.         
    / f, g: b  _7 `. T$ W; w% u* R, E0 g
  80.         /**
    ( V( T7 i, F% A. b
  81.          * 获取登陆二维码对应的授权码
    + S* c0 h' v( T5 l
  82.          */& U# S( ]- }# P' o$ z% ]+ }
  83.         public function get_login_code(){
    & r/ `! h" p3 ]5 F4 ^* [4 A, {; {
  84.                 if ($this->_logincode) return $this->_logincode;  S/ ~% V4 {# \' ~' s0 H. K$ p
  85.                 $t = time().strval(mt_rand(100,999));
    7 M( N% p6 T. s
  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;
    6 f# b. V. j4 u0 ^
  87.                 $send_snoopy = new Snoopy; 2 _# N1 o7 v7 B$ l- a
  88.                 $send_snoopy->fetch($codeurl);  X! {$ y" I& [. e  Y6 a5 I
  89.                 $result = $send_snoopy->results;
    3 Z1 e! i5 W, n# W+ G9 V
  90.                 if ($result) {
    3 Y7 G# O, C- P! C6 Z) x% L
  91.                         preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
    & G4 u/ v9 u7 y6 m% o! _- ~. f
  92.                         if(count($matches)>1) {2 W1 i6 v7 W+ z" |7 _
  93.                                 $this->_logincode = $matches[1];7 D5 Q  p$ _3 X
  94.                                 $_SESSION['login_step'] = 0;
    / \: W# g3 i/ o# n0 ]" S0 y
  95.                                 return $this->_logincode;" o- }- L- f7 G! X3 a
  96.                         }8 j9 J* K5 |& F
  97.                 }  [. V- a$ |1 F1 D$ ~0 }1 o
  98.                 return $result;
    ; T6 b1 r+ e5 B
  99.         }: a) B- D0 Q$ m# D

  100. 9 a0 y, n+ D! L9 j& X, X
  101.         /**
    * {; ?. p; p8 x: U0 s& B
  102.          * 通过授权码获取对应的二维码图片地址8 q, Q' h* C7 [9 z( C
  103.          * @param string $code% Q0 A+ P1 g5 v2 J" v; Y: i! W
  104.          * @return string image url; e( p$ c& N9 t
  105.          */! F: O% Y$ Z4 x7 f" _, \
  106.         public function get_code_image($code=''){  M: J' ]# g/ K
  107.                 if ($code=='') $code = $this->_logincode;
    8 _( j$ u- j% k( m1 i& ]
  108.                 if (!$code) return false;. u; ^. }- W; t! D
  109.                 return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';. M4 N, P8 l0 l* b1 Y$ C
  110.         }0 l% K1 W2 A+ j2 K
  111.         
    9 h) [1 {8 I% s9 H2 |& D  {3 Y
  112.         /**; W; l' x' ^# y- g" U7 L
  113.          * 设置二维码对应的授权码
    / l& ~* i# z; Y- V5 _% n* G+ W
  114.          * @param string $code6 ^# j  S& ~% V% g9 ~5 I/ |; d
  115.          * @return class $this
    4 I1 K$ r* J/ d# o3 X' Z9 j
  116.          */
    , p! n" o! ]0 e5 A& \
  117.         public  function set_login_code($code) {
    & k1 W! F& L5 B
  118.                 $this->_logincode = $code;
    ! w* g, ^4 ?( O  O  `- v2 n
  119.                 return $this;
    0 B% r0 A) g$ n9 _! i  ^& a0 n
  120.         }8 b. N! b& I! \# W; X: I$ Q
  121.         ( J$ A; X' Q2 i- x
  122.         /**: N: [; `0 C: }7 _: |
  123.          * 二维码登陆验证
    9 E& G+ p% J+ a8 U/ D
  124.          *3 F: Z5 W& c# C# {
  125.          * @return status:6 T9 ^2 K* @$ k1 y
  126.          * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired
    3 J- U  p: `( a$ T- I! |
  127.          * 201: just scaned but not confirm: ?6 }$ D0 v4 Z9 G  M
  128.          * 200: confirm then you can get user info7 q. q9 q6 c0 u7 ?0 a
  129.          */& q( {' y1 y% C4 Y% U% S+ b# g  p/ e
  130.         public function verify_code() {4 g! p" A$ D8 [* P# n
  131.                 if (!$this->_logincode) return false;9 Z1 f: \) u2 r. G) z' J% w
  132.                 $t = time().strval(mt_rand(100,999));
    * z5 m2 |* f, X5 u# s1 ]

  133. " u% E+ }6 O3 c& C2 l3 b" s$ P
  134.                         $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;' w3 A4 Y% [, _
  135.                         $send_snoopy = new Snoopy; , P0 c3 _; i% p$ N8 U
  136.                         $send_snoopy->referer = "https://wx.qq.com/";
    % a* X) B$ V* I8 B7 {% r* Q4 q4 c5 w
  137.                         $send_snoopy->fetch($url);  h# @0 X) I' W' }# G
  138.                         $result = $send_snoopy->results;: Y6 L! D4 w. A1 j
  139.                         $this->log('step1:'.$result);
    / y4 u3 t1 h1 `) ]1 z
  140.                         if ($result) {1 ~/ m, y6 r/ |5 Y
  141.                                 preg_match("/window\.code=(\d+)/",$result,$matches);  y" B0 _* s- q
  142.                                 if(count($matches)>1) {
    " _; T3 w3 ~/ O8 I3 k4 P' H/ U: E
  143.                                         $status = intval($matches[1]);
    # b1 h2 I7 E( ~2 q
  144.                                         if ($status==201) $_SESSION['login_step'] = 1;2 o" u# H, D- G' l
  145.                                         if ($status==200) {+ v/ T  W  R( \; y# v" N. D
  146.                                                 preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
    9 S) J+ d1 y$ B) q
  147.                                                 $this->log('step2:'.print_r($matches,true));
    , p  V% t8 D4 K$ D6 \) [5 h9 m/ L' i
  148.                                                 if (count($matches)>1) {
    - O+ O# m' k4 @7 y6 Y
  149.                                                         $ticket = $matches[1];, q/ N0 _/ W! R0 P- J, H
  150.                                                         $scan = $matches[2];0 k/ W% ^, ?+ q0 e5 c3 g
  151.                                                         $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';
    , D4 \$ Q. j0 D& \
  152.                                                         $send_snoopy = new Snoopy; 1 z! E7 y4 g# \; `
  153.                                                         $send_snoopy->referer = "https://wx.qq.com/";! ^" M1 j" m: B; s. q
  154.                                                         $send_snoopy->fetch($loginurl);
    % A3 [" p  t. F0 v
  155.                                                         $this->log('step3:'.print_r($send_snoopy->headers,true));
    : y; o: p  M# W3 [, j
  156.                                                         foreach ($send_snoopy->headers as $key => $value) {
    1 j! o  p; ~: O6 K) P$ S% T
  157.                                                                 $value = trim($value);' u+ V3 q- I3 S$ X$ C. c; z
  158.                                                                 if(strpos($value,'Set-Cookie: ') !== false){2 |4 k* v+ a& [, P+ P0 d8 Z* h
  159.                                                                         $tmp = str_replace("Set-Cookie: ","",$value);
    3 |1 [: D$ x$ y) G8 n4 A. K( }
  160.                                                                         $tmp = str_replace("Path=/","",$tmp);
    ) b$ c& D: f2 O4 o8 ?
  161.                                                                         $tmp = str_replace("Domain=.qq.com; ","",$tmp);
    3 l4 f; @, r1 a6 \2 U6 \/ h
  162.                                                                         $cookie.=$tmp;
    ' g& T, h% H) y
  163.                                                                 }- f' H+ o1 \6 h! ^( Y8 `
  164.                                                         }
    8 i+ r8 O9 B8 }) t
  165.                                                         $cookie .="Domain=.qq.com;";6 x, v: J) G- |% O9 \& P4 c
  166.                                                         $this->cookie = $cookie;" [6 Y1 \# h) S1 {
  167.                                                         $this->saveCookie($this->_cookiename,$this->cookie);* X8 S2 ~+ O- q0 n7 ?9 G' A' w
  168.                                                 }
    " g( I* p; S1 b2 P
  169.                                         }' i# l# e8 V0 U7 K
  170.                                         return $status;
    : c8 b6 v& @$ v1 n
  171.                                 }6 {4 Q' @) g- Q: _% X3 \
  172.                         }
    # ]/ {% m/ U. [8 r$ m* @
  173.                 return false;2 O- u; G8 N( W- `
  174.         }
    / t. N: s& _8 }' A! m
  175.         4 M7 \: c) D5 I  h- d; G
  176.         /**
    7 U4 @8 u7 ^2 K
  177.          * 获取登陆的cookie
    , U. Q& d8 ~/ A" O# r
  178.          *
      f* i0 M: t- A
  179.          * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
    / y  k- n* H  Z7 Y6 [6 D
  180.          * @return string|array
    ) i5 I" ^- R1 [: ^- b$ |
  181.          */
    # I$ C; k" x1 L% @! l: j) U0 I
  182.         public function get_login_cookie($is_array = false){
    8 P; ~0 m, i* J; B/ A' N
  183.                 if (!$is_array)        return $this->cookie;) Z9 [* n1 C  y! Q' s( t# [: ^
  184.                 $c_arr = explode(';',$this->cookie);9 P9 t* g( O; |, r8 l% f( u0 j/ ~* I
  185.                 $cookie = array();
    5 @* T* [: x: s# g0 K
  186.                 foreach($c_arr as $item) {* J4 m  [- Y" u5 [! r+ P
  187.                         $kitem = explode('=',trim($item));
    + u1 ?% d5 T0 E1 p: A
  188.                         if (count($kitem)>1) {
    " @+ t( [) B# a" i; j* P" U/ Z
  189.                                 $key = trim($kitem[0]);, B5 w8 [; P' e9 U3 q3 b3 e4 g# u
  190.                                 $val = trim($kitem[1]);: D) ^6 J- n9 r6 t3 @' O
  191.                                 if (!empty($val)) $cookie[$key] = $val;
    ' @% |; ?5 q+ x2 i6 h
  192.                         }5 I& ]- v7 b( k! ]3 R% M
  193.                 }
    2 `, e: D1 t+ K( ~# I
  194.                 return $cookie;* {1 N9 A0 @, _, L! z' K
  195.         }
    - s6 E% }; R- ^/ e5 E; o
  196.         3 ?, w) L# r; f( f) Y. V$ ~' U
  197.         /**
    $ S( q2 N& X3 K/ q! z7 _
  198.          *          授权登陆后获取用户登陆信息
    5 p: g" r1 P7 E" V# W
  199.          */& \8 I$ C; b! N) o6 b8 R/ P
  200.         public function get_login_info(){, A3 j- I" v. l& S* @& O
  201.                 if (!$this->cookie) return false;8 x3 D& ^% D$ g9 U
  202.                 $t = time().strval(mt_rand(100,999));
    : [. H% _+ C& d* i
  203.                 $send_snoopy = new Snoopy;
    $ i- L7 I$ y' S, |
  204.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
    0 ^0 ~" s* A, S' D6 {& }  n  b" }
  205.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    / S* {7 n7 J. t7 T& k$ _
  206.                 $send_snoopy->referer = "https://wx.qq.com/";
    2 s8 j+ I7 x' p6 ^5 |1 h& }
  207.                 $send_snoopy->submit($submit,array());
    7 |- x4 S* v) w
  208.                 $this->log('login_info:'.$send_snoopy->results);
    6 P8 g/ Q9 g# s6 Z: }9 E  D
  209.                 $result = json_decode($send_snoopy->results,true);: E# i$ \) x; M( N4 d7 f* v& a
  210.                 if ($result['BaseResponse']['Ret']<0) return false;
    * t! t. I$ B% n0 X4 k; M, l
  211.                 $this->_login_user = $result['User'];. p( B, F- }0 N+ w
  212.                 return $result;
    " u0 ?/ ?, [+ R. _3 V
  213.         }
    ' f$ u/ Q/ \6 m3 \8 ^1 R4 l
  214.         " M2 X2 B$ s9 M# o2 f/ i" O4 Q: I
  215.         /**
    0 Y4 c; U# X9 D4 M: y, M
  216.          *  获取头像
    % _7 V9 t5 Z5 O* W! P. A! Z
  217.          *  @param string $url 传入从用户信息接口获取到的头像地址7 D. b) S( Y% E. B6 `% @
  218.          */
    ! F+ S& f* v* q' p4 D" i
  219.         public function get_avatar($url) {, s" C/ e- I& M. D' x# `
  220.                 if (!$this->cookie) return false;9 z: h( g& x8 z9 @2 @
  221.                 if (strpos($url, 'http')===false) {. D$ M) u! ^" A/ w* D
  222.                         $url = 'http://wx.qq.com'.$url;
    # D# U! }8 U8 F' t  [
  223.                 }1 p# W: e; J# I! V7 b8 v5 r
  224.                 $send_snoopy = new Snoopy; # h8 x- g0 g% X  X
  225.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;- J- O( P* E8 S. K
  226.                 $send_snoopy->referer = "https://wx.qq.com/";( F& k& T& [! [$ v6 e! P, r" M
  227.                 $send_snoopy->fetch($url);/ N7 F( G& P0 w, ^# k) s
  228.                 $result = $send_snoopy->results;0 v  }( c2 g% U$ A6 X% o. n3 v, K6 j& r
  229.                 if ($result) # y, e5 x) z/ ?+ a  ^; O# u
  230.                         return $result;
    3 l* _; k6 z0 Q! z
  231.                 else
    9 i# W: t' [, v% j
  232.                         return false;
    # K) V, F1 F& A6 U& n  Z/ B
  233.         }% |* P+ Y$ Z0 v: y9 x" N
  234.         " D! j" O: |3 l1 A: i6 Q
  235.         /**
    & I3 O9 k9 T9 t7 ~7 h1 n+ v
  236.          * 登出当前登陆用户
    ' o8 N9 o' K" h4 [0 `" p6 l' a, ^0 R
  237.          */
    + W& M8 Y: Y+ Y: R
  238.         public function logout(){: N4 n# w9 o" M/ G0 X# l# Y/ t
  239.                 if (!$this->cookie) return false;5 s! r* `; o. K  e
  240.                 preg_match("/wxuin=(\w+);/",$this->cookie,$matches);
    2 K# \5 Q. O) [9 l  ]
  241.                 if (count($matches)>1) $uid = $matches[1];
    5 Y: }4 Q# P" w; j6 m
  242.                 preg_match("/wxsid=(\w+);/",$this->cookie,$matches);+ v' `/ O6 N6 V* W0 i8 ]/ ]5 I# z
  243.                 if (count($matches)>1) $sid = $matches[1];! I( I, I, _6 C2 I- q
  244.                 $this->log('logout: uid='.$uid.';sid='.$sid);
    1 _# W2 Q( A0 P0 _- s% L9 A, ]
  245.                 $send_snoopy = new Snoopy;
    ( B( d0 g+ w1 S
  246.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
    " s5 ^) m8 d; B) U
  247.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    , l2 ?( ]1 N/ g3 H5 @# R, j
  248.                 $send_snoopy->referer = "https://wx.qq.com/";
    3 C9 y# \  U8 p1 v$ G& q" F
  249.                 $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
    * C" ^  G7 ], Z9 [3 t
  250.                 $this->deleteCookie($this->_cookiename);7 p! ~2 c7 M2 s  h8 z8 Z
  251.                 return true;
    * t1 e* N; v! i) l1 t  n7 |. _
  252.         }% I: H6 A5 h, K6 p. \' g9 }
  253. }
复制代码

, x6 k, N# B3 x" C




欢迎光临 微现场IM互动 (https://www.qnwall.com/) Powered by Discuz! X3.4