用户通过扫描网页提供的二维码实现登陆信息获取
0 a5 D& i7 n% Q* f- C& Z- <?php1 `3 w% D; P1 @! G
- /**9 d5 z( `. u- a3 z+ U* V# B
- * 微信公众平台PHP-SDK) K2 I8 G7 V, g. i/ R$ K
- * Wechatauth为非官方微信登陆API
% E, f p4 o+ `' d+ p7 C - * 用户通过扫描网页提供的二维码实现登陆信息获取
7 E; i! E& G6 G4 D0 X0 Z# w" Q - * 主要实现如下功能:( d, p/ @2 I2 L# H0 K! I
- * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码7 P1 Y2 w$ Y2 [' }* O, a
- * get_code_image($code='') 将上面获取的授权码转换为图片二维码
7 X% J3 i) j( F. Z0 a - * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
' y/ m4 p+ o! A - * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息- x/ m+ u5 y" ]" _2 `, n
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
/ B- z. O. a% [- |1 V" x: r - * get_avatar($url) 获取用户头像图片数据
6 @( K8 o2 d1 n4 Q8 r- t - * @author dodge <dodgepudding@gmail.com>* s) z" ?9 }' n* Q9 z i) t
- * @link https://github.com/dodgepudding/wechat-php-sdk7 V- U' ]( Y+ y) x; w: C) P
- * @version 1.1* d, t9 ?5 x: {2 w8 n O
- * 3 h6 R# y& j& W: c2 o7 l
- */7 T1 g+ m) b3 l& P, ?
- include "snoopy.class.php";
9 s X3 z' [$ e; V1 |- E - class Wechatauth1 K& s6 S6 j* n9 \" ~% l1 R
- {/ w% N6 @( o! G- r0 W ~
- private $cookie;
C) L t) s4 s) C - private $_cookiename;
: x) n8 Y6 d. c* A9 m/ T& v' K- a - private $_cookieexpired = 3600;
6 _. y" Y* X" v, T* ]; m7 M8 Y - private $_account = 'test';
7 b N4 c! Q# | - private $_datapath = './data/cookie_';# b7 l* B j0 y: @6 T
- private $debug;' G) p7 X3 U1 M# w
- private $_logcallback;! c0 y# R- l9 r; z) m
- public $login_user; //当前登陆用户, 调用get_login_info后获取# P8 Y+ M$ K8 t3 ^
-
. p- M2 e& i" A6 Q% B- Y - public function __construct($options)8 \/ E- w p; J/ g/ D; K# Y
- {
/ g; n" ^; D# R! l# a2 K/ H - $this->_account = isset($options['account'])?$options['account']:'';6 G2 N( O% L& a/ r
- $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
& V$ L& T0 u$ @# H: r: b" E$ H @# u - $this->debug = isset($options['debug'])?$options['debug']:false;+ F$ j' a6 C# b- |* E. q9 @, W: X
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;9 s+ Z& \ W4 s$ ^
- $this->_cookiename = $this->_datapath.$this->_account;. G$ ? D0 Y: v9 E' ]
- $this->getCookie($this->_cookiename); K2 ~& q( k! n/ I' n
- }
1 t0 Y a, ^" i0 j - /**4 Y' R( i# G8 S* B7 Z+ ]
- * 把cookie写入缓存
: P& O+ Q7 m/ B - * @param string $filename 缓存文件名7 g- H8 ^: n9 n+ B; R ^9 w: d" P
- * @param string $content 文件内容
# G: L# t9 `3 t5 U - * @return bool) \5 [9 [# C& v0 D
- */. O, C. M7 g# u8 j% t
- public function saveCookie($filename,$content){
) ]* @7 q+ D/ U! \1 H+ M8 m! w: ? - return file_put_contents($filename,$content);
6 \/ w9 p* c" Y j2 m4 W - }9 ?7 G* s- m, a6 G% U% Z
- 0 n0 u" J, o) `
- /**
9 C2 |' f; c" K6 J5 ~! K0 \ - * 读取cookie缓存内容
$ u9 P$ u! Y; P, T) m - * @param string $filename 缓存文件名- S( }/ O$ h& \! _9 k
- * @return string cookie# P& F( E$ s) f y% k. o
- */4 [9 w+ f2 `; ~ a4 z) |
- public function getCookie($filename){
' I0 `: k' H2 N* }$ r - if (file_exists($filename)) {" _; @* ~9 Z4 |. R3 J' L
- $mtime = filemtime($filename);1 v8 P4 n7 c4 O" O; L3 k) s( v2 K
- if ($mtime<time()-$this->_cookieexpired) return false;& @) x2 i! X1 _. p' m
- $data = file_get_contents($filename);* t5 b o$ X9 e% S2 k
- if ($data) $this->cookie = $data;
3 N/ j- M; w" Y" ~ - }
: _, M1 y" L5 u1 g7 U# q' { - return $this->cookie;
& M- w0 s3 P+ x* `9 ]5 }2 h# } - }4 X* y( _" U( e2 }
- / b: V1 C7 L" y
- /*
& x# M. _, B1 Y o' W0 |! H" K - * 删除cookie6 ]) E1 r1 v1 I9 R3 Z1 w4 [2 [
- */
W/ X2 ^9 G6 s! \9 |1 a& h - public function deleteCookie($filename) {
! y, c+ o8 x( ^* | - $this->cookie = '';3 x- I' o' E4 {
- @unlink($filename);- [1 e% l* H) ?% F0 Y
- return true;: B/ p9 Q e+ r1 W
- }, ? y: t# }+ _. s
-
: H: ?% S6 a5 [5 g8 L R - private function log($log){
. n$ j" a) f; j R5 [ - if ($this->debug && function_exists($this->_logcallback)) {
( t$ ?. r: p& F- l1 c' W - if (is_array($log)) $log = print_r($log,true);
: Z8 m7 U. k) l$ F: m - return call_user_func($this->_logcallback,$log);
$ l& v$ O) a- P, j# U; Y3 X - }
% ~$ \ ~5 V% u5 K - }0 {1 U) s, s d
- 1 W" N; D0 F$ G; p. c; i; A) d
- /**/ q( ^* W5 t. G7 o1 l
- * 获取登陆二维码对应的授权码 j, }# N/ f5 o3 W% D+ G
- */
. M) e& p. J* _2 }4 s) Y7 M$ y - public function get_login_code(){) |, R1 `! r- `, m8 O" M, {2 y* V0 E" I
- if ($this->_logincode) return $this->_logincode;
9 h6 E& R: l8 T O - $t = time().strval(mt_rand(100,999));5 ?) K6 Y, ~* N
- $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;3 ?9 p( V! r9 d3 K
- $send_snoopy = new Snoopy;
2 \0 W1 p; b6 M) {3 ^ h - $send_snoopy->fetch($codeurl);( T/ O! m6 q3 k1 o! ~
- $result = $send_snoopy->results;
0 F V9 X2 u+ B - if ($result) {$ ]( N( P0 C$ I7 C4 S- R6 C2 j
- preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
2 I0 ]+ x2 n+ O) R9 O. k n - if(count($matches)>1) {
7 l6 B8 s- w' P- r4 d( n; {& V - $this->_logincode = $matches[1];! m2 V; e& ?) v w
- $_SESSION['login_step'] = 0;5 m2 s* r3 |, X6 w8 h: y
- return $this->_logincode;/ L# C. b' i% g8 Y
- }1 _! z) r" ]! V- Z
- }
# q7 ^9 Q- c$ A" i. @ - return $result;, D% V4 J1 R% Y) _9 V& p- s( Z
- }
2 Q- G8 K/ ~8 M7 a$ s# U- I! V - % I U1 F& t) K# V) h3 a
- /**- l$ S) t# ?2 ~
- * 通过授权码获取对应的二维码图片地址. k- s; Q8 m2 \; O% s8 L7 s
- * @param string $code& C" D+ ]! g# f9 i: q
- * @return string image url
! D* i4 m; i2 d& G3 A - */' p$ ~" V1 z; G$ ]; G
- public function get_code_image($code=''){
7 d8 j" u; I+ A& E9 e, {% e: P - if ($code=='') $code = $this->_logincode;
1 J! A) K5 X9 p+ V2 ` - if (!$code) return false;6 d! l( d7 l3 @" {, W
- return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
$ O9 z7 g( l) @$ K5 O! g5 l7 H3 b( U - }
8 b& D4 f) n* i9 s - 7 ~5 }+ s g. I% v4 Z
- /**0 L# Z- }7 ~# [5 n/ ^+ [$ S; s, t0 T6 g3 R
- * 设置二维码对应的授权码+ @$ P' ~4 k% r$ q( y6 T/ n
- * @param string $code% T5 C8 H6 z0 n4 I6 S5 Y, E
- * @return class $this% M2 r8 d; ?1 `
- */. t- u2 k ]$ K/ ~ Y% B) P
- public function set_login_code($code) {
6 v- Y% v& ^0 M: f. k+ {) k5 ^ - $this->_logincode = $code;
5 p. `5 j L( Z) Y, c7 o - return $this;* r- s6 g% D" \+ H
- }
2 g, F' [3 T# O3 q - 4 b4 y1 P. W! V0 J' S+ E. T
- /**
% B- X' P3 l1 F - * 二维码登陆验证, _# c1 T. X# `7 N
- *
3 W# e F! K) B, u1 t) _ - * @return status:
. B! `# i I3 C6 g* Z - * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired8 i' F+ |! W0 R, Y% M
- * 201: just scaned but not confirm
# G+ w3 _+ J; j5 J - * 200: confirm then you can get user info0 j) I0 c E+ d, E, @7 w8 [
- */$ D# h: C: _0 ?1 J* Q
- public function verify_code() {
) A8 Q; a& L- |" f: r1 U - if (!$this->_logincode) return false;
1 |+ Y/ H5 L0 y - $t = time().strval(mt_rand(100,999)); }+ f n+ A! d9 _" e& j5 x
- ! M8 \7 A( S8 `& E n9 T
- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;
/ a% ~+ @5 s T3 m" O/ N - $send_snoopy = new Snoopy;
: y) z: e5 D' }2 V9 S0 O+ Q1 s. v - $send_snoopy->referer = "https://wx.qq.com/";
+ G0 W5 \7 O3 E( u' `, V- ? U - $send_snoopy->fetch($url);
$ U* _$ D4 @: @$ q% T. @ - $result = $send_snoopy->results;
1 |' K" m( `. |( v& j" w1 h0 G) K - $this->log('step1:'.$result);
$ W/ W) b' L& F$ d* o - if ($result) {
, K% I+ W) l; k3 c# j/ ^ - preg_match("/window\.code=(\d+)/",$result,$matches);( }5 m8 p5 E, r/ \
- if(count($matches)>1) {- N$ x+ W0 h E
- $status = intval($matches[1]);
6 l5 D4 {! ^9 h - if ($status==201) $_SESSION['login_step'] = 1;
* f6 `! }0 `8 j$ u+ W6 m7 u; j - if ($status==200) {
) E0 f6 r. Z& n5 ^7 w4 k+ S; a7 S: z - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);/ o7 \( d0 X4 {) i+ C7 {9 q
- $this->log('step2:'.print_r($matches,true));; X. ?* u# t2 Y8 S* W; d/ \
- if (count($matches)>1) {2 G/ N, t& c5 M
- $ticket = $matches[1];
: y+ z: ~- J% `5 V* _ - $scan = $matches[2];
2 \$ @/ n$ O i4 S/ G+ e - $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';
2 k9 G% F# M9 W8 o - $send_snoopy = new Snoopy; . v9 z9 k) w9 J6 ~
- $send_snoopy->referer = "https://wx.qq.com/";" R3 K% m$ R. M7 |8 }8 R: j! n
- $send_snoopy->fetch($loginurl);* D6 ?3 w% @* A$ Q2 i
- $this->log('step3:'.print_r($send_snoopy->headers,true));% ~8 o5 U7 ~* H1 W+ x0 h
- foreach ($send_snoopy->headers as $key => $value) {2 s5 F! i" n$ T# a9 K( }' v
- $value = trim($value);7 }& N0 x" e. f! L/ c
- if(strpos($value,'Set-Cookie: ') !== false){
1 A2 c8 p6 _# u) b3 _4 |7 t# _* E9 ~ - $tmp = str_replace("Set-Cookie: ","",$value);
0 {+ y8 M% r- n% i - $tmp = str_replace("Path=/","",$tmp);
3 }$ N/ Z; d( |: Z5 M' D2 o - $tmp = str_replace("Domain=.qq.com; ","",$tmp);
! _4 g& P) q" t# s - $cookie.=$tmp;6 W! I2 S; n: K1 Q# s" a# [
- }
8 v1 d' O! d7 F# \ - }
4 \- d: D5 V' y - $cookie .="Domain=.qq.com;";8 S7 `7 o* C5 B1 O& k0 P
- $this->cookie = $cookie;4 }) ^ L# b d h6 g
- $this->saveCookie($this->_cookiename,$this->cookie);
9 ~2 F! Z0 j( y - }: m. c4 _9 e0 T9 @9 h9 t
- }/ a7 |8 b) L. N
- return $status;# |6 ^( d n9 Z. S3 {7 u, m4 q& Y
- }
5 [+ K# \& G- o - }
k- g/ D* f. J% M, e - return false; Q9 ~" |+ P, \4 Y% ]3 v
- }1 A/ h* p; _! r: J
- 2 B- W3 Z# o% N8 f( T3 }+ w
- /**
( T5 L/ ^6 X7 w - * 获取登陆的cookie
* @2 S/ X- V8 e: f% j; L$ f - *8 U. c) x; C. Z2 X+ v6 x( z
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
; ]- e+ s0 }6 Z - * @return string|array
7 q$ x+ s0 {8 W1 ]( A - */
+ u1 I3 |% p' Z9 q' U - public function get_login_cookie($is_array = false){
6 G- N1 h! K9 v7 E3 j/ X: n - if (!$is_array) return $this->cookie;
% l0 F7 p* }& H" d$ B' R - $c_arr = explode(';',$this->cookie);
" c8 l) \" @% L1 ^. h - $cookie = array();
& E& F9 @7 `; Y. ~1 A3 \' Q* n8 h - foreach($c_arr as $item) {
9 c% L0 C. V, g- [( c- Y - $kitem = explode('=',trim($item));* c9 U( ^' b1 T" e4 O4 V
- if (count($kitem)>1) {
& A' z" I1 S/ H: n - $key = trim($kitem[0]);
! F. t2 n3 B n7 F' F- U& t - $val = trim($kitem[1]);
; v& v1 `. Z [. z. L8 s4 g0 N - if (!empty($val)) $cookie[$key] = $val;
/ D1 S! D4 r. j4 E - }
% ~5 [* f2 u3 h! I - }
8 z0 v2 S, ` T - return $cookie;
, D9 x2 o& |$ g - } R! g! l2 U8 o: I: B! Y
- ; s$ x0 O1 o4 j1 L9 K
- /**; I# m) i7 @7 e1 e P4 S
- * 授权登陆后获取用户登陆信息
6 I) c M! N9 s - */
5 Y2 [" j2 R( M( A' | - public function get_login_info(){; y- N! _4 V" i, z# [- `2 v
- if (!$this->cookie) return false;
3 z0 O4 [3 W4 ^0 v- j# ~* D0 G0 P - $t = time().strval(mt_rand(100,999));
s) T8 \8 l3 M8 o( Q& Q - $send_snoopy = new Snoopy; 3 p& Q" i7 |' e8 W }9 {
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;8 ~1 |! m: g# ]% E( @0 Y* f# Y$ [- k
- $send_snoopy->rawheaders['Cookie']= $this->cookie;( t" j1 |/ J" o) P
- $send_snoopy->referer = "https://wx.qq.com/";
( Q V' J. j% e/ ]9 m$ t, k - $send_snoopy->submit($submit,array());
/ f. h& D+ m1 p! I - $this->log('login_info:'.$send_snoopy->results);
' x: P# V7 F/ f; w s6 R - $result = json_decode($send_snoopy->results,true);
# I2 Q7 J9 x, E' S2 a - if ($result['BaseResponse']['Ret']<0) return false;) D8 V' ~- C0 O, H% q
- $this->_login_user = $result['User'];
6 z, V j2 B' W& V) n C& G - return $result;8 m# E* W" Y. w7 E( h
- }
_7 n: i* q( m -
" c7 N, B, Q* g$ \ - /**
0 G5 F' a9 H- M# U# F - * 获取头像4 a4 A! ~( Y) j* o
- * @param string $url 传入从用户信息接口获取到的头像地址2 S- V0 s2 j( q2 Z8 F
- */
; i: F5 r$ P6 r& }7 g) T - public function get_avatar($url) {
4 k+ w0 w( ^& m( X - if (!$this->cookie) return false;
) W0 e, P8 Q/ H7 T2 Q - if (strpos($url, 'http')===false) {
- a) t H( @2 {" B3 ]8 y$ p( ~ - $url = 'http://wx.qq.com'.$url;
0 u8 f7 J/ A% }* J# T4 G1 C' L. l - }
4 W/ ^+ o6 \% a - $send_snoopy = new Snoopy;
K4 D# _% R( a0 S - $send_snoopy->rawheaders['Cookie']= $this->cookie;9 D8 u5 U- v x! q0 p
- $send_snoopy->referer = "https://wx.qq.com/";
7 Q5 H4 x M' Z, o8 S6 N! U - $send_snoopy->fetch($url);5 d2 Y2 M4 y2 L! W! f
- $result = $send_snoopy->results;( D+ U+ t/ u6 ]( Y! q
- if ($result)
$ t6 o% z6 ]. p6 M - return $result;
; a0 ? U+ E$ k, i% \/ i" l - else* }( U( f4 E% T! F- u
- return false;1 n9 B5 A/ _" O0 @: e4 C5 N: H+ Y
- }
' s8 a1 F. g1 S* o- v0 u( w - : v ]6 }: t n, [) W6 z
- /**9 G: J& X- X- g1 m$ ~
- * 登出当前登陆用户- T% {; X% W7 D- G/ @$ {" u1 z4 ?
- */
* G5 v9 z% u) \1 ~* l1 E! R - public function logout(){: s$ Q( n# t/ R4 P" a1 j2 ~. q0 I
- if (!$this->cookie) return false;
, a' v5 W5 l7 ?5 Z3 g5 L* J6 E% A7 v - preg_match("/wxuin=(\w+);/",$this->cookie,$matches);
9 v$ g. m* A4 R7 {8 { - if (count($matches)>1) $uid = $matches[1];1 L$ ^5 @( k: m" g
- preg_match("/wxsid=(\w+);/",$this->cookie,$matches);: P! J+ t) U/ s5 }" p
- if (count($matches)>1) $sid = $matches[1];
& v- @. W0 h: z5 F: { k3 H; I1 \! ^ - $this->log('logout: uid='.$uid.';sid='.$sid);) m8 p7 p6 u- d6 n5 U5 \
- $send_snoopy = new Snoopy; * u5 z+ p1 }4 d# w9 \- C9 l
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
1 g# }/ o' s- S+ Q - $send_snoopy->rawheaders['Cookie']= $this->cookie;2 D1 G+ {, O& i d! D
- $send_snoopy->referer = "https://wx.qq.com/";
7 o) P& g& @- r* G: L - $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
; M1 D- z( P% X2 l - $this->deleteCookie($this->_cookiename);( R3 c T- F/ R4 i( U
- return true;
) y' U) Q& ^* Q: P% y - }
/ t$ G2 k- Q5 y3 m+ [ - }
复制代码
1 ^& k* b- M: _+ h* j4 t7 e |