用户通过扫描网页提供的二维码实现登陆信息获取
$ ]# I3 d4 X$ V" d c: I- <?php, s n1 V: k8 k# {* P Z% A4 E
- /**
' @: C. J5 q$ h8 R1 |- p4 ^ - * 微信公众平台PHP-SDK2 V P# }0 X1 W/ p
- * Wechatauth为非官方微信登陆API
" s: n1 s- e$ } - * 用户通过扫描网页提供的二维码实现登陆信息获取& u* w1 Q8 w4 u' |; f; w$ V
- * 主要实现如下功能:
! Q! P, A6 z6 u9 }# T1 e& N - * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码5 u2 u/ v2 ]5 }6 _( @+ O' H, ]2 z
- * get_code_image($code='') 将上面获取的授权码转换为图片二维码4 N" w- G. U5 R T- q% @
- * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
2 x8 e1 z' R5 L0 y - * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息5 x1 x! A1 H3 _/ I8 z3 a* d
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
4 d- n" ~ ?+ K3 P3 T - * get_avatar($url) 获取用户头像图片数据. Q6 [8 X+ F$ b$ D5 @) A
- * @author dodge <dodgepudding@gmail.com>- l6 T. ~8 [3 s, m# Y0 Q1 x" \
- * @link https://github.com/dodgepudding/wechat-php-sdk
$ V1 B+ L6 J, L - * @version 1.1
# [$ i/ ] D! Q6 s - * 8 t7 c- ^, O4 k) h0 c! ?# d+ {
- */
/ y i2 {! W4 B, A4 A6 T) ~ - include "snoopy.class.php";
: D' P7 X) k$ j* D/ ^; x1 J - class Wechatauth8 K, v- C4 o" `( Z% {
- {
1 h( B% H6 s" W4 I2 B9 p - private $cookie;; B6 S0 A6 k& b
- private $_cookiename;
/ J# U" C+ j3 O" ] - private $_cookieexpired = 3600;3 H8 K$ _) ^ Z7 h( e
- private $_account = 'test';# E$ w6 S, x$ W" S
- private $_datapath = './data/cookie_';1 H/ p* N; u" M7 f4 T
- private $debug;/ v& w$ w# z1 D6 x2 f' d
- private $_logcallback;
9 U: @6 S/ y( K0 I% O9 D - public $login_user; //当前登陆用户, 调用get_login_info后获取 d( |& q" y6 N; m2 k$ L
-
+ S' G: i- X, f8 A3 e% p( b: Y4 f - public function __construct($options)* B7 M3 |: M$ I- Y( R
- {$ u' E! [$ y! `. t. N* P; j4 n- K; |+ V
- $this->_account = isset($options['account'])?$options['account']:'';
6 `! C# f7 J' i3 x8 `8 l - $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
; W7 b _5 ^6 F: g2 s: v* R - $this->debug = isset($options['debug'])?$options['debug']:false;
" C/ H: s) M& K$ p+ h* T9 v3 _ - $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;3 z6 @: Z' h) B* u U# x! T: [* i
- $this->_cookiename = $this->_datapath.$this->_account;
* B6 y. e2 G( B - $this->getCookie($this->_cookiename);
2 y4 S0 u, i5 ~; h8 L - }6 I: N# t/ k1 h( M9 Q+ ~
- /**$ t* h5 Q) {8 ]' O5 E
- * 把cookie写入缓存
2 u8 a' u0 r8 e4 |( U - * @param string $filename 缓存文件名
; G! L3 ]/ E' v9 L! I3 ] - * @param string $content 文件内容9 A. P2 a' l& _" `2 C
- * @return bool, ~/ a6 [. M( S# N0 {0 W6 Q
- */
7 a! E; J% K. \+ N - public function saveCookie($filename,$content){* d+ p1 ~1 M/ h5 I& Q; n+ E
- return file_put_contents($filename,$content);
% Y# G; D- E) ^3 H - }( Z- `) M0 _" Q( B1 z+ `
9 }$ }8 e6 K6 K- /**2 y9 n5 W. v! t5 G+ O8 p8 F
- * 读取cookie缓存内容
% u8 V9 T; r* [3 z- |" D! q - * @param string $filename 缓存文件名
( m+ D/ P( a9 H" ?( C5 J+ {4 f2 f - * @return string cookie4 i1 v1 q! h2 P V
- */% i1 r2 X, P% U+ s2 h2 x. p
- public function getCookie($filename){% {$ ?0 `7 ` F4 k3 u
- if (file_exists($filename)) {8 s, ?* `- q& y0 g1 B7 Z
- $mtime = filemtime($filename);! \9 S$ \ D0 d7 n4 C1 V5 p; I
- if ($mtime<time()-$this->_cookieexpired) return false; I0 `0 c O. X0 ]2 H
- $data = file_get_contents($filename);* G* j8 ~ w, L; e, ?
- if ($data) $this->cookie = $data;, P, W, x+ P" z$ h B4 s4 p4 ]
- }
4 r* r. w7 Z' p g$ j8 b. w% n - return $this->cookie;- u! }4 `& {/ ]: U
- }
1 M1 B) w' X, S4 K0 { - 3 |6 T1 O, S0 r2 y* N! D5 B. y& G
- /*' f6 q$ e! a2 E& L
- * 删除cookie5 W& T/ _; M) o9 j+ E
- */
6 w' w' N' ] ~( M5 r! S, V - public function deleteCookie($filename) {0 v) s9 G1 e7 V, d, V, Y
- $this->cookie = ''; c% [. `! _* }3 E0 D& w5 |6 h
- @unlink($filename);6 g5 j* E; H! E- C6 }
- return true;
/ H4 W* J6 J* T( R! ^# Z& \" \- z - }
( _* u u9 n% r. N" P -
5 f1 ]9 g9 A5 X - private function log($log){, l; H1 ]0 C$ w# q8 y1 x* u
- if ($this->debug && function_exists($this->_logcallback)) {
& n0 a% z1 Z; I - if (is_array($log)) $log = print_r($log,true);
( W6 N" J) r4 z3 m - return call_user_func($this->_logcallback,$log);5 H, _9 @6 _; z
- }
4 I" d! h1 k0 E# P - }
( y6 T: M# x2 { -
: F$ e) X5 }) N4 ]! d( ] - /**
0 L$ T4 {' E3 A; E3 z - * 获取登陆二维码对应的授权码& { | @, O; F$ C+ L7 Z& p
- */3 B& V1 S3 w% V+ i
- public function get_login_code(){
+ u& C6 K# n- z. N0 K - if ($this->_logincode) return $this->_logincode;0 @6 g. |) y' n, T
- $t = time().strval(mt_rand(100,999));* C8 {$ Z8 j' k2 M& P {( n- X. U
- $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;2 Y5 a3 m& J0 ?# Z" {8 ^* e
- $send_snoopy = new Snoopy; " g8 n3 x. d9 [4 U
- $send_snoopy->fetch($codeurl);$ w2 T: e2 F8 }
- $result = $send_snoopy->results;
, n" s6 N3 s! A; W/ W3 s - if ($result) {) L1 {) j! r3 X R2 l+ p$ G" P
- preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);4 Y- p7 q5 z) E! {) R4 b% W
- if(count($matches)>1) {
) X1 ^' G0 i0 v1 b" T Z% X - $this->_logincode = $matches[1];
( ?. c% ~) d( X7 \& f$ i - $_SESSION['login_step'] = 0;
: X) L! K6 j0 p/ T* r2 j& ?$ _ - return $this->_logincode;" D |# F9 l* O n
- }0 U2 _$ Z3 I% E N! P5 f2 Q* q
- }
, N* i8 w/ u1 N0 f: x+ w - return $result;
" L% ` N8 p6 P, o& A0 `! o! t( p9 Z - }
7 A; k B1 I" N7 w. ^1 C. y* G - 6 I8 @! s" J0 }( [7 ~/ {4 Z: r( y
- /**2 |/ m4 ], L8 W1 d( _, ]/ o, x
- * 通过授权码获取对应的二维码图片地址4 @3 N) V ]6 G7 B1 P
- * @param string $code& A& C; {& M. N7 l7 Z
- * @return string image url% J, L( T6 }4 z2 @
- */8 r! Z* d2 \# @2 \
- public function get_code_image($code=''){
1 \+ R; F" g* | @ - if ($code=='') $code = $this->_logincode;( t2 S% @( y9 b! M
- if (!$code) return false;8 X3 D) ^+ x7 I: \4 `
- return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';/ d( D% [1 o: Z+ N0 J9 p
- }
/ F& v# Z& `1 Z0 g. N -
! `7 I) C/ m) q3 T" i5 s1 f - /**6 \ D% V3 H% t/ d# @* o
- * 设置二维码对应的授权码
! x8 ]& u$ i& R. V" L# U/ x) ?; ` - * @param string $code
+ D# U- `3 _9 g, ]0 T( R8 x - * @return class $this
! g) g4 S3 g6 C* S& i2 q - */8 R% n* d& \, y! j
- public function set_login_code($code) {+ N; |) P: {0 L& B' H. @* `3 @
- $this->_logincode = $code;
" n8 N( _, L+ B0 P h - return $this;
8 _" t \- u/ f0 K( v5 E - }
B# f. K% w! `! V8 w5 S - 6 `( H- C4 y$ t4 ~+ p* J
- /**2 [3 ` \3 K0 l1 ?
- * 二维码登陆验证
4 @+ ]* u. i u7 g7 C" ]* j - *
% h: a0 O2 Y& g/ M0 n1 r. s - * @return status:
4 i) P' ]& P" @: u$ I8 E0 a - * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired
" Y o9 v; @) c& N4 L - * 201: just scaned but not confirm
. A5 C$ T7 t9 K2 c - * 200: confirm then you can get user info
5 K( f0 o' @- i" B( l5 x - */6 F2 w; a/ K. m( L: T8 b6 K {9 N/ w+ W
- public function verify_code() {$ z& N0 E, d& g- d" ?& I( n2 {
- if (!$this->_logincode) return false;- J; |$ ?5 B: U
- $t = time().strval(mt_rand(100,999));
0 }3 c5 p; `% n4 W$ }
+ s$ o" e3 [! Y; A8 o, L2 @) D3 \- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;
# h% j2 T @) a7 X) M# P - $send_snoopy = new Snoopy;
. v. g$ g1 ?; i- N5 C5 V - $send_snoopy->referer = "https://wx.qq.com/";% O" {/ I9 s/ h
- $send_snoopy->fetch($url); y$ a* i6 c: U8 f
- $result = $send_snoopy->results;' u6 r5 _- N+ f4 R
- $this->log('step1:'.$result);! d: v. L$ ~' x
- if ($result) {
- X: _ Z8 ?2 k$ p4 z- U* m: M8 z( u - preg_match("/window\.code=(\d+)/",$result,$matches);2 U6 `* G4 B4 {, _* F
- if(count($matches)>1) {
8 ]1 _, I4 j" V) c% i - $status = intval($matches[1]);
7 N& x8 o, l) Z - if ($status==201) $_SESSION['login_step'] = 1;9 }+ |( _* y/ H5 d. j* D* ]
- if ($status==200) {
/ J- s6 I% |* e9 v0 U2 ]! d - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);" [/ a" v* v$ A: L/ E# |# ~
- $this->log('step2:'.print_r($matches,true));$ N; ?- _ g/ P0 ~, ]
- if (count($matches)>1) {- U- j% F/ b& A& e6 b* [* Q
- $ticket = $matches[1];( X. X0 ? \' X* m- [5 r
- $scan = $matches[2];
8 A" n8 k. d! `' P5 p - $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';
! J' M& ?/ ?0 k6 [! ]# S7 b - $send_snoopy = new Snoopy; % l2 }$ D) f+ P- I
- $send_snoopy->referer = "https://wx.qq.com/";
& U$ @/ d# o' x! s0 }% C - $send_snoopy->fetch($loginurl);
% q5 [, k' i) b" F% j) ]! f3 D - $this->log('step3:'.print_r($send_snoopy->headers,true));
2 ^! Z: S" o- V0 v, l - foreach ($send_snoopy->headers as $key => $value) {$ q4 U1 }3 ~) E& c( N: z" @# n
- $value = trim($value);8 T1 o9 f. U+ l( J
- if(strpos($value,'Set-Cookie: ') !== false){
* @; W- m; p: b6 g1 c5 q" B - $tmp = str_replace("Set-Cookie: ","",$value);
" Y7 _/ d+ d7 @' X7 Q/ J3 b r, l1 g - $tmp = str_replace("Path=/","",$tmp);% D6 _6 d ^% Y. L/ Q4 ~% f8 S Z& b. O# f
- $tmp = str_replace("Domain=.qq.com; ","",$tmp);2 N7 h2 X% q" ^
- $cookie.=$tmp;, h7 ?/ g$ J2 |( v4 L7 W
- }
! Z, F7 G/ `+ |# c+ r - }
5 L. M, i0 p1 ` - $cookie .="Domain=.qq.com;";
3 v& _2 [' H5 ~* N - $this->cookie = $cookie;+ a+ t! y. f, X
- $this->saveCookie($this->_cookiename,$this->cookie);
6 W! a# s+ i. [! z - }( @/ d' J7 h& i i
- }
% [ {5 q6 a2 _# J3 j4 g - return $status;6 C! d- k; p# x+ H# Y% [+ S
- }9 _7 L# g/ m L! { }
- }
) h$ A4 s2 @! ?- |: l4 @ - return false;
( [$ W$ A( {; n8 v - }' ]( j8 \3 W6 ?
- ! A4 M* I; @$ s8 O
- /**
- C! U4 g$ K# n' f7 i! l8 n' B - * 获取登陆的cookie
0 Q$ m7 n! y6 T" n - *
' t+ I$ c) ~, t; g. m% K( |$ d - * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
4 m/ A% @+ M0 J/ N/ k2 c - * @return string|array
, o9 F% z- d+ k F( u - */- N5 f3 r3 O" ?/ f
- public function get_login_cookie($is_array = false){, {# i- e1 j* a2 a6 K) d8 k: e
- if (!$is_array) return $this->cookie;
* u$ I' E& f2 _( O! n g2 P( k - $c_arr = explode(';',$this->cookie);
, n3 i( |: f1 U* m% [& l - $cookie = array();8 J4 [! M! |5 v
- foreach($c_arr as $item) {
8 S9 t$ o# T+ J f+ \5 o/ i5 g- _ - $kitem = explode('=',trim($item)); t: L, n& R* r9 n3 X
- if (count($kitem)>1) {; [, N! U3 V5 a& h# A7 w7 d
- $key = trim($kitem[0]);
1 E" k, g8 h7 G( P - $val = trim($kitem[1]);
% b# K7 C9 x. d- E8 N$ c - if (!empty($val)) $cookie[$key] = $val;$ f4 c$ @0 L" @( `! O; {
- }
1 `9 t8 i0 n7 y1 G - }
* U% m y4 ]! b* N) F - return $cookie;
; c! Y5 h3 T' `7 L' f* Y. a2 x& u8 [ ~ - }% {" l) {5 K$ U& @
- , e' t" L g1 E+ k- K
- /**# N- d' z& [$ t- t0 W. F
- * 授权登陆后获取用户登陆信息
& {' C8 _9 e- C4 }) m. \2 x9 d - */
7 l* d. Q; c- t4 a- ? - public function get_login_info(){/ t6 e& ?3 u7 h& v6 [) A0 c
- if (!$this->cookie) return false;+ ]) ^" N+ U' A* J* \
- $t = time().strval(mt_rand(100,999));
0 V& A5 j( A, F - $send_snoopy = new Snoopy;
! U: m: D0 i$ Y+ ?' r - $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;% _4 w+ U8 B S5 }0 \! i: S1 [
- $send_snoopy->rawheaders['Cookie']= $this->cookie;
3 u" Z4 p* ~) `9 u/ l' }# T - $send_snoopy->referer = "https://wx.qq.com/";5 t/ s* n9 U, c3 E. e0 ]
- $send_snoopy->submit($submit,array());! Z5 S! h9 ^2 G- x
- $this->log('login_info:'.$send_snoopy->results);' q, `) L9 Z, c9 P8 b! c
- $result = json_decode($send_snoopy->results,true);
7 c( W; F5 g, v' R+ v - if ($result['BaseResponse']['Ret']<0) return false;: ] d% @) @5 h( K
- $this->_login_user = $result['User'];3 K/ H+ r3 \' V# i( D- b: l
- return $result;
) V7 a5 {. N7 \8 s- I9 ~8 t - }
) X8 ^; k& ^/ h& w) f9 z - / d! ~9 Q$ r1 _/ D* u9 x& a" T
- /**% N" h$ \) h1 s* D6 L) K4 Q
- * 获取头像
3 ] R! [1 L! e- x - * @param string $url 传入从用户信息接口获取到的头像地址
W' U7 l! o6 r8 C - */- e8 W& ~8 {& W" Z) g# s7 ~
- public function get_avatar($url) {/ Z- v/ Z5 I6 }5 [& ]- G
- if (!$this->cookie) return false;
3 e3 }. q; s, {: w# e1 l - if (strpos($url, 'http')===false) {
: m7 w' o# M7 L) D - $url = 'http://wx.qq.com'.$url;5 P$ S" v; Q! t5 j {4 W& { B8 Z2 k
- }& g' P& G% S8 G$ O5 q
- $send_snoopy = new Snoopy; ; M$ B) X4 T' t' h
- $send_snoopy->rawheaders['Cookie']= $this->cookie;8 T1 e4 L0 C, G+ n$ U( E7 d
- $send_snoopy->referer = "https://wx.qq.com/";# [+ F0 @7 R* q$ l ~" ?
- $send_snoopy->fetch($url);8 I+ x1 [& {, m, M, J
- $result = $send_snoopy->results;
4 D( M/ h9 `, V4 f1 i8 P - if ($result)
# R: y% y0 `) L: s - return $result;
& K" E: M1 l# A4 u2 D4 u9 O - else8 [/ @" `: a3 D/ P# z- |
- return false;4 O# L& j+ ?% V }5 j
- }" S- o- b5 d# H8 T) @& U) S
-
/ B3 J( K0 g( X# [ - /**
* U- a% D- E- ~% c& a2 j - * 登出当前登陆用户% ?) o E& U4 H! D
- */% g- D' ?+ j$ F% V$ {
- public function logout(){3 A: z/ V' M: J2 A% ?# D+ J; u
- if (!$this->cookie) return false;
0 H7 d4 n, A. j( m2 | - preg_match("/wxuin=(\w+);/",$this->cookie,$matches);4 {3 V8 `5 q' q& i9 D
- if (count($matches)>1) $uid = $matches[1];
) m+ G1 H% d d! T9 W - preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
, s) L& O2 s& K( W - if (count($matches)>1) $sid = $matches[1];+ T: h# s/ P- Q& S; w9 V& j
- $this->log('logout: uid='.$uid.';sid='.$sid);! |: H {" [* C1 Q: |5 u/ A* x" v
- $send_snoopy = new Snoopy; % i+ f0 @2 ?1 F5 p/ ]& v
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
4 }& X+ b6 B3 l8 M8 i8 P/ c - $send_snoopy->rawheaders['Cookie']= $this->cookie;
2 E3 ]" E8 U! v- o! P' r7 M1 A - $send_snoopy->referer = "https://wx.qq.com/";" ?8 ^0 b8 m9 G/ J
- $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
- ~+ [) _9 F5 a: s9 C - $this->deleteCookie($this->_cookiename);
" d/ c/ T$ x+ v! G) a' Q6 o - return true;
0 | n" y+ w, X; }; } - }
" u- ~4 U0 B7 n7 x- i! o1 X - }
复制代码 ; F( G" p* h; W9 f; v9 m1 b
|