微现场IM互动

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

作者: eoiioe    时间: 2014-2-2 21:55
标题: 微信扫描登录
用户通过扫描网页提供的二维码实现登陆信息获取
: n. D! V, g2 g
  1. <?php: a4 a4 z, b, r
  2. /**
    # u/ w% H% M7 A: R  s
  3. *  微信公众平台PHP-SDK% s: J$ D7 n2 t% S5 d, c  |
  4. *  Wechatauth为非官方微信登陆API
      ~3 h  R( d3 s$ Y" Z' p9 t
  5. *  用户通过扫描网页提供的二维码实现登陆信息获取9 p0 ]6 K0 I3 n8 @/ B* T
  6. *  主要实现如下功能:
    / c# g0 Q  a+ l$ H  [' K
  7. *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码2 ?: F2 K; [7 |" a+ I
  8. *  get_code_image($code='') 将上面获取的授权码转换为图片二维码
    $ {& i( B4 U: c3 t' I# e" {
  9. *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
    ! W3 g" ~, a1 n7 C5 ]
  10. *  get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息' S# ~; u0 T  z: F. T% ^
  11. *  sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
    6 R  K% l/ z' Y( S5 V9 n2 E
  12. *  get_avatar($url) 获取用户头像图片数据- f) U8 s) k  K4 C, X9 f& M
  13. *  @author dodge <dodgepudding@gmail.com>- A& w4 |% ]0 V2 w& v8 z8 K( S
  14. *  @link https://github.com/dodgepudding/wechat-php-sdk) o$ d7 E2 v: h
  15. *  @version 1.1- S" A% ~# I7 q, E2 K
  16. *  
    : O# \# H- s9 g' Q! x3 h5 w
  17. */
    6 ?9 g# T* z7 _. q$ w! C
  18. include "snoopy.class.php";
    ( v3 j) N- U( ^0 f6 _9 v+ `3 W
  19. class Wechatauth
    3 v1 ~5 X/ }; C  F" L
  20. {
    3 ]% d: i/ B& l6 ?& O3 A, ]
  21.         private $cookie;* R3 c' D" N" h/ i0 o
  22.         private $_cookiename;
    7 ?8 m8 A  N+ ]7 I
  23.         private $_cookieexpired = 3600;; p( i! Q) \3 H, a6 ]- Z7 E
  24.         private $_account = 'test';4 g* P8 [2 P+ Y3 q+ q3 @. ]
  25.         private $_datapath = './data/cookie_';# X: I. R, v6 q( J( M
  26.         private $debug;
    ; I9 z- T, ]0 t- I- E
  27.         private $_logcallback;( _; ?' j( T! Q/ d$ P" V
  28.         public $login_user; //当前登陆用户, 调用get_login_info后获取$ _' e; a6 M1 D
  29.         
      p' L2 D  l. i. t+ N$ e% S% A
  30.         public function __construct($options)
    0 {( q# p( `; p/ O
  31.         {% k) h  a/ h& F2 v( G0 R% F
  32.                 $this->_account = isset($options['account'])?$options['account']:'';
    5 q- K4 f! @) `
  33.                 $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
    ( v+ T5 @7 R  k% \
  34.                 $this->debug = isset($options['debug'])?$options['debug']:false;
    5 C2 \" C3 U7 Z8 O1 [
  35.                 $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;$ E: Z9 n  h0 W; L8 U1 a; z7 W, w
  36.                 $this->_cookiename = $this->_datapath.$this->_account;
    8 G/ Q. }& x* `3 ?
  37.                 $this->getCookie($this->_cookiename);
    # k. ^6 F3 L. J% I, p
  38.         }: J: [- g% D) o/ L, n9 b% d
  39.         /**; i# J$ T! ~4 m1 Z7 l. K
  40.          * 把cookie写入缓存8 t' K  e  j" d3 u; `
  41.          * @param  string $filename 缓存文件名
    / e( |9 {+ o) F( W8 C. e& }
  42.          * @param  string $content  文件内容
    ( E( v' C0 {4 I5 @
  43.          * @return bool% R: h7 D& f1 _5 f+ q
  44.          */
    + Q) K% o+ L9 @& q6 {
  45.         public function saveCookie($filename,$content){9 P& F! S4 J. i
  46.                 return file_put_contents($filename,$content);  q9 \$ a0 ]" W% C
  47.         }
    & Q6 d$ n* I4 q7 I; `% T/ t

  48. ' g( r5 E1 Y" W3 ]
  49.         /**( s$ l/ L1 U2 l, n* [: r* J
  50.          * 读取cookie缓存内容
    ! E* O$ x$ V& X1 f0 W
  51.          * @param  string $filename 缓存文件名" _6 `" S0 [- Q/ {
  52.          * @return string cookie- S, s3 n0 r1 o* k) y
  53.          */
    0 \( I4 g  A: S9 e
  54.         public function getCookie($filename){
    / p9 f. K7 L: Q$ f+ M( \6 f
  55.                 if (file_exists($filename)) {
    " B/ G, l' T: A
  56.                         $mtime = filemtime($filename);
    - P" ~& Q/ @! w# J8 G  J) m+ i* i
  57.                         if ($mtime<time()-$this->_cookieexpired) return false;
    ' d# E. O4 r3 d4 b7 B
  58.                         $data = file_get_contents($filename);( V5 H* o+ c, ]
  59.                         if ($data) $this->cookie = $data;
    + \: z3 d- ^4 C' d
  60.                 } " b& ~$ j, U6 w6 [9 ^2 w4 {# p
  61.                 return $this->cookie;
    4 P/ I0 B& X' a! }+ O/ V
  62.         }
    4 j, U4 H7 |( D; {% ~
  63.         
    + D7 ~. V7 w" e( o. F) e
  64.         /*( _) \4 b3 J3 k# |
  65.          * 删除cookie- N! \% `4 N. ~. T4 \% Q8 O
  66.          */
    2 N. D/ W; g- @* Q8 j9 w7 ~
  67.         public function deleteCookie($filename) {2 l$ Q+ U3 f" Y4 w7 S' D3 h
  68.                 $this->cookie = '';( g5 |0 t2 Y0 T( Z7 w) `3 n' B
  69.                 @unlink($filename);
    4 X5 X3 E/ @5 m, J' [
  70.                 return true;1 S) F/ D$ _; N7 H, _! n
  71.         }- T9 q7 d" C+ c2 E/ a3 s6 l
  72.         
    ! Z/ [( C, o% I) X% F( Z6 W- o" K
  73.         private function log($log){
    0 @) E9 F: H& `) `% W- f
  74.                 if ($this->debug && function_exists($this->_logcallback)) {" B; k; T! p: B# F6 c
  75.                         if (is_array($log)) $log = print_r($log,true);
    " Y) q3 e/ w% ?' W
  76.                         return call_user_func($this->_logcallback,$log);
    2 B, Z: n$ y) L
  77.                 }
    6 v7 T! n% ?! N  c+ E; N- P
  78.         }
      U% n3 p+ I% h7 W8 p* Y1 m& a
  79.         
    0 [! \. k. p. b3 ^- R: ]
  80.         /**3 f+ D4 A* x- O- d. |
  81.          * 获取登陆二维码对应的授权码
    , [. w9 I( G+ k( |5 x
  82.          */
    6 M1 q4 z3 a# O9 T+ C) v3 }
  83.         public function get_login_code(){
      K! v# g3 D8 x. a% z- p' {
  84.                 if ($this->_logincode) return $this->_logincode;. v! z1 L1 f8 V2 J* l  N' J
  85.                 $t = time().strval(mt_rand(100,999));
    ( T4 j! a  M9 a; G7 p7 m3 ?
  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;$ x) T: Y8 h" j. O
  87.                 $send_snoopy = new Snoopy;
    ) X/ F; f: f' {% D# h3 R+ ?! g! \
  88.                 $send_snoopy->fetch($codeurl);$ o6 \6 w7 G5 ]! u' K/ M4 l
  89.                 $result = $send_snoopy->results;' D2 g8 X1 S( |0 C1 {8 c
  90.                 if ($result) {
    4 q1 H8 I0 i0 t
  91.                         preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);/ g6 _( n) N, \  W* ], @. j6 r# m
  92.                         if(count($matches)>1) {
    8 p# c% v2 D/ o
  93.                                 $this->_logincode = $matches[1];8 G. k) o9 Y* a
  94.                                 $_SESSION['login_step'] = 0;5 D' d8 `0 c/ `% j/ }( k6 R2 k$ D- Z
  95.                                 return $this->_logincode;
    4 e8 ]1 x1 l6 X6 U' c. U
  96.                         }
    % D" B; S- p: x' A( l+ W7 j
  97.                 }' n0 n. K! w1 ]0 F
  98.                 return $result;
    8 l, r% Z. @; Z' S2 t8 U
  99.         }
    # E4 u6 _2 {* e, d. o7 T) J
  100. . x3 b$ r; w$ k2 I' W
  101.         /**
    8 [- F8 r2 L& |1 C
  102.          * 通过授权码获取对应的二维码图片地址
    / D8 S5 J' E+ i1 e# E% q+ r- P
  103.          * @param string $code
    + A! ~$ B- Z. {. P2 s# H
  104.          * @return string image url
    5 ^, O; z. g& V3 d
  105.          */
    + a& D2 r0 i1 r5 k! [
  106.         public function get_code_image($code=''){; p, S1 }, v7 [4 M2 L- i
  107.                 if ($code=='') $code = $this->_logincode;
    6 R  d9 J' u. |7 y9 J
  108.                 if (!$code) return false;
    4 i& P" w0 R$ `( F  h6 W" o
  109.                 return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
    $ E6 m/ S. I* D; G; A
  110.         }
    , m5 m6 N+ U, J3 u
  111.         8 m, p/ O, c( t" E/ G
  112.         /**
    3 r# s6 G) L; ~4 b. R0 v
  113.          * 设置二维码对应的授权码
    / e; E( v6 a, Q! Z0 C
  114.          * @param string $code2 n% H% r' v$ n/ n" M
  115.          * @return class $this
    3 g4 f, W" x! q
  116.          */
    0 x4 i7 i, H& ~/ P2 l
  117.         public  function set_login_code($code) {
    ' @1 I' k% Y* \# T
  118.                 $this->_logincode = $code;) E% K' H) I! r% v
  119.                 return $this;! k6 |% \% }# J
  120.         }" v2 I7 n1 y0 m6 n7 u$ v4 X' u
  121.         
    # F  A: i+ X- v8 ^
  122.         /*** e* ?1 v& r$ X7 F5 o
  123.          * 二维码登陆验证
    * N' E% ~0 a! ]  B# n! e
  124.          *
    2 b0 h1 H" T7 |/ w) X+ h& u2 g  \
  125.          * @return status:
    5 K+ C3 @, Y1 ?% w% U. _. [1 m
  126.          * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired
    9 h+ z3 y$ k  x6 c
  127.          * 201: just scaned but not confirm# C# x; H6 V) R7 z
  128.          * 200: confirm then you can get user info
      v3 E6 j  G$ R8 {* g
  129.          */
    * c, k) |8 v8 }" s
  130.         public function verify_code() {
    & ?& L0 g, X- R. V% i2 H( b/ H! g
  131.                 if (!$this->_logincode) return false;
    " Z+ S: H( e' c# P* S# n! O
  132.                 $t = time().strval(mt_rand(100,999));0 _  {, p% o7 w% {: ^4 y! s0 a: G
  133. ( I3 ?# g2 a2 d- P
  134.                         $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;1 ^8 O" q' G+ S, W- |; V
  135.                         $send_snoopy = new Snoopy;
    + e$ n0 m, G* a$ g
  136.                         $send_snoopy->referer = "https://wx.qq.com/";
    * y8 b6 S6 N5 {* t# I
  137.                         $send_snoopy->fetch($url);* M8 L6 Q8 p% ?% f% W$ A8 D  ^
  138.                         $result = $send_snoopy->results;# q! u) a4 G( G9 I
  139.                         $this->log('step1:'.$result);/ V! I5 h$ l; `' m6 o% s
  140.                         if ($result) {" g9 n7 f$ H" p! z+ b
  141.                                 preg_match("/window\.code=(\d+)/",$result,$matches);1 l* K$ E# A# x7 `* D) W- u
  142.                                 if(count($matches)>1) {# d' P1 U4 E7 E$ G! x6 r
  143.                                         $status = intval($matches[1]);
    ! i+ w6 _* }5 B* j
  144.                                         if ($status==201) $_SESSION['login_step'] = 1;+ K9 F( [& B- j
  145.                                         if ($status==200) {
    0 E* G. L; ^+ p' t. ^7 Q6 t
  146.                                                 preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
    % P0 A2 d9 W: O4 M9 R
  147.                                                 $this->log('step2:'.print_r($matches,true));1 S/ d, o2 p5 L( w8 a1 ~, R
  148.                                                 if (count($matches)>1) {
    3 H8 m0 T$ K- C& {% S
  149.                                                         $ticket = $matches[1];: S8 ]/ C' V" W6 G3 K4 l, e$ `
  150.                                                         $scan = $matches[2];
    ; Q5 A# P/ j6 k/ f% R- U; |+ ~4 o
  151.                                                         $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';) s9 S8 @, E% P2 t
  152.                                                         $send_snoopy = new Snoopy; 8 Q. }1 h( U" E4 z8 n
  153.                                                         $send_snoopy->referer = "https://wx.qq.com/";* w# o$ g8 w# z! D8 j% {
  154.                                                         $send_snoopy->fetch($loginurl);5 p0 p: a6 j. b1 Y
  155.                                                         $this->log('step3:'.print_r($send_snoopy->headers,true));
    4 y; N1 i( J+ O/ J6 j. O
  156.                                                         foreach ($send_snoopy->headers as $key => $value) {7 B0 Z# y* x# P# W/ ~2 G6 r
  157.                                                                 $value = trim($value);* Y! L4 l1 P) z. p/ h
  158.                                                                 if(strpos($value,'Set-Cookie: ') !== false){
    2 t7 u' Y; H5 d2 x0 p& B( l1 b: R
  159.                                                                         $tmp = str_replace("Set-Cookie: ","",$value);
    % ^1 N! C9 K! D
  160.                                                                         $tmp = str_replace("Path=/","",$tmp);; R; V1 l5 i# x4 Z8 [
  161.                                                                         $tmp = str_replace("Domain=.qq.com; ","",$tmp);2 O! C# g! d3 x) X& q
  162.                                                                         $cookie.=$tmp;7 M/ B+ o! v+ s2 |3 R, Q
  163.                                                                 }
    / A6 b0 p- h# k3 k# h$ }
  164.                                                         }
    6 o* W( L3 L$ P0 R, j
  165.                                                         $cookie .="Domain=.qq.com;";8 q+ h8 O! s$ L) z2 _6 v/ L
  166.                                                         $this->cookie = $cookie;* [* Y1 W/ H4 {7 [$ V, x
  167.                                                         $this->saveCookie($this->_cookiename,$this->cookie);) M4 B$ t, Q1 J9 m
  168.                                                 }$ |1 ?  i  C% b( @( x- m
  169.                                         }
    7 s( l" v' y. d) z
  170.                                         return $status;2 w* Y# \, N0 I7 E8 C$ C- @
  171.                                 }
    ; j) U- A( d* S
  172.                         }
    " `7 T7 B, U5 y7 x8 ?) n
  173.                 return false;8 J$ K/ v6 c8 `0 S
  174.         }
    % f- z3 F$ Z- C( M% M1 D
  175.         
    ( Z+ F) a. P4 N3 }% e6 B% o
  176.         /**5 i  i  U" Q; `6 i8 u; p5 V
  177.          * 获取登陆的cookie
    2 l' E! ]# E( l  s/ H$ r+ O
  178.          *
    $ T' f. w! P0 T
  179.          * @param bool $is_array 是否以数值方式返回,默认否,返回字符串6 \. z3 O6 J/ u9 X6 Y: H$ e
  180.          * @return string|array
    * z2 S9 ]; e' D/ V; [
  181.          */; o2 o: V& ^4 Y: T1 W- R
  182.         public function get_login_cookie($is_array = false){
    - d& E5 b% K2 z3 f- @! N
  183.                 if (!$is_array)        return $this->cookie;. r  ~2 {0 I$ N1 S
  184.                 $c_arr = explode(';',$this->cookie);
    * [2 ?* N+ d7 F3 f9 v
  185.                 $cookie = array();5 I2 s$ a! _+ j! o" Z# D7 \8 s
  186.                 foreach($c_arr as $item) {
    1 F. z  Y4 L2 Z; \
  187.                         $kitem = explode('=',trim($item));% Y4 T9 t. V8 [& d# _; f. v4 Z7 Q2 G
  188.                         if (count($kitem)>1) {4 w+ D$ a0 M. u1 F4 {: o4 ^
  189.                                 $key = trim($kitem[0]);$ m& {4 V3 N, _, k- m9 d
  190.                                 $val = trim($kitem[1]);
    + |5 h. {, X0 H* I4 B
  191.                                 if (!empty($val)) $cookie[$key] = $val;+ \; b! |" C! C& D
  192.                         }1 }' l4 d0 U: q+ }, ~9 `
  193.                 }
    ) M4 k- A, e* B# ^8 P8 L  v" t
  194.                 return $cookie;
    & B1 k' ?" L2 J$ x
  195.         }1 K# p5 k" D/ D6 ~; A, H' T
  196.         7 R& r" h5 B$ h' Z) G/ C: F
  197.         /**
    4 D3 ^5 \- e2 X" E% N! x
  198.          *          授权登陆后获取用户登陆信息+ a$ Y* o1 J1 }$ Z3 i1 \- {
  199.          */$ `8 q4 y, s9 R8 M3 P$ k0 ?
  200.         public function get_login_info(){! O; Z- M( S9 A4 v* J% L  s$ n9 v
  201.                 if (!$this->cookie) return false;
    4 u$ G) U4 F* z6 M5 [3 |
  202.                 $t = time().strval(mt_rand(100,999));
    9 u+ Y  R: i/ u8 y
  203.                 $send_snoopy = new Snoopy; ' W* e- G: F0 Z1 G
  204.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;$ b  ^" r! l/ ~- h9 U/ y
  205.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;: A# b: O! S1 W9 A7 T
  206.                 $send_snoopy->referer = "https://wx.qq.com/";, `4 h2 m2 B) U! A- E0 F: S
  207.                 $send_snoopy->submit($submit,array());: k8 e1 F3 A$ c" H: L. K; L# D
  208.                 $this->log('login_info:'.$send_snoopy->results);: H- h, ~. G& G2 I1 M* l4 ^
  209.                 $result = json_decode($send_snoopy->results,true);7 p% ?% b+ i7 A& U6 ]* Z
  210.                 if ($result['BaseResponse']['Ret']<0) return false;
    ) m6 f. \* @% u8 v! x. D
  211.                 $this->_login_user = $result['User'];
    - i; N! g8 C4 Q9 c1 `
  212.                 return $result;
    3 L3 f4 [' P: i  S& a$ K& M, P. [
  213.         }
    8 t, u9 Y0 J. B! `2 r- P$ I
  214.         
    & s) m  a2 y1 e; y: j
  215.         /**
    # W6 F% a8 l* \4 T
  216.          *  获取头像4 ~% A5 R$ ?, k6 r
  217.          *  @param string $url 传入从用户信息接口获取到的头像地址
    8 w- y% j) F7 [6 Y! |/ i% k) T" ?
  218.          */
    . y! k" G2 ~+ h" e! y+ E
  219.         public function get_avatar($url) {2 }+ m: t0 i  C( K: Q! w3 r. r+ A) A
  220.                 if (!$this->cookie) return false;
    / F7 J0 f+ t+ H, {! I3 j
  221.                 if (strpos($url, 'http')===false) {: x/ ]3 D6 L; Z( j0 z
  222.                         $url = 'http://wx.qq.com'.$url;, b; C4 [; Y+ @# G5 o4 G! ?" l/ l
  223.                 }$ C: e5 Z( _' f2 I  b
  224.                 $send_snoopy = new Snoopy; % k/ b" l8 c5 f" K$ l! \/ @
  225.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    : [' M7 A# \+ C  U9 Y
  226.                 $send_snoopy->referer = "https://wx.qq.com/";
    & M* j1 `1 v: G
  227.                 $send_snoopy->fetch($url);9 }& {# Z6 ]3 m
  228.                 $result = $send_snoopy->results;
    " O2 Y  b* l7 r* K. k
  229.                 if ($result)
    . h+ M9 \/ w% O8 \( h
  230.                         return $result;! x5 W3 g( u1 C# \
  231.                 else* }" ^% ?3 w1 Q7 C
  232.                         return false;
    0 D/ l$ g. |$ _0 h: d: Y4 Y! ]
  233.         }. h& j, j! I+ \; p
  234.         ' S: }* a$ B! p8 g
  235.         /**
    $ R  O7 |6 G7 b2 e6 |
  236.          * 登出当前登陆用户$ d; }9 ^! Y9 i8 g
  237.          */
    4 T& R$ |7 a8 a  _
  238.         public function logout(){
      @& K* Z9 E) g6 y" j0 |' S$ @
  239.                 if (!$this->cookie) return false;
    ) |3 W( K5 k; j: |
  240.                 preg_match("/wxuin=(\w+);/",$this->cookie,$matches);* j" g0 n0 g+ [/ K! v5 n
  241.                 if (count($matches)>1) $uid = $matches[1];
    % |* ]! E: Z) n7 t
  242.                 preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
    " K3 c" Z- W! z1 X+ h
  243.                 if (count($matches)>1) $sid = $matches[1];
    ) c0 F' X& M! }0 K
  244.                 $this->log('logout: uid='.$uid.';sid='.$sid);+ a1 i* t: L# ]
  245.                 $send_snoopy = new Snoopy; + z0 p8 C- s: Z* F8 [
  246.                 $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
    . W5 w- R6 _4 T+ P2 {
  247.                 $send_snoopy->rawheaders['Cookie']= $this->cookie;
    ; g/ h8 a4 s  ?7 n3 {! h6 S' g! P
  248.                 $send_snoopy->referer = "https://wx.qq.com/";
    * [! }6 ~1 `5 i! r4 t: {
  249.                 $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
    ) q" D# G* A. H# W1 Z# I7 ]! W$ F6 ]
  250.                 $this->deleteCookie($this->_cookiename);
    . P' a: F  {8 e
  251.                 return true;" d9 ^% L% Y) Q2 S; C
  252.         }
    $ q3 a$ w4 {2 U& j: T1 f7 M) ^
  253. }
复制代码

& {3 j- ?( O- o* G* G




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