用户通过扫描网页提供的二维码实现登陆信息获取 4 X1 \7 Q; }3 L; w& Q3 `% p0 P8 A
- <?php! O* A% V$ j. n6 G( M% z# `
- /**
; \0 E# o6 g) h- D0 ~ - * 微信公众平台PHP-SDK$ ~( [$ f& _% S
- * Wechatauth为非官方微信登陆API0 a: Z7 y- |9 y' V9 \: `
- * 用户通过扫描网页提供的二维码实现登陆信息获取
0 o2 j3 a. S& q# u! H - * 主要实现如下功能:/ _. y1 B8 c/ G9 ^! \/ U2 I8 f
- * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码+ @% e% [+ m( D6 E8 m% k
- * get_code_image($code='') 将上面获取的授权码转换为图片二维码
; M4 Z2 `: ~; O2 _) J/ N - * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
5 A+ l4 ~+ Z8 j O& P6 D- m7 w" z - * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息
* O' ]1 d( \8 h* y - * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息! Q+ O' i* P I7 i' _
- * get_avatar($url) 获取用户头像图片数据
; O# f4 ~+ a2 \, y& Y0 ]9 w4 [ x - * @author dodge <dodgepudding@gmail.com>
t; m0 {7 M5 u1 r, j" c( ? - * @link https://github.com/dodgepudding/wechat-php-sdk
& ~& ]: O5 l8 d0 h( c/ g2 X: ]. f2 l - * @version 1.1
6 m7 S1 Z: a$ T) |' g) \9 n - * 8 W' B; h8 U. r/ k
- */
k, g' C. S2 u8 d2 f2 v+ g0 j - include "snoopy.class.php";
, \9 u N7 }# C1 D& \6 g - class Wechatauth- I0 W' [4 R) H5 o4 K6 N$ e
- {
/ M N( M9 o5 { - private $cookie;: {( T( ]6 T+ h5 Q4 p8 f( B
- private $_cookiename;$ N* k8 j0 X9 _ \5 w7 Q5 L
- private $_cookieexpired = 3600;& ~; @2 a# {3 v* A8 c2 I1 N
- private $_account = 'test';
% ?$ l! n1 b4 u8 l8 f8 i - private $_datapath = './data/cookie_';
- x0 e. l$ Y! ^8 P7 K7 @& r - private $debug;
! X# q! n2 ~3 L& w; S/ z) c - private $_logcallback;
4 Z# t! Q8 h$ e8 }' F, q7 F2 X - public $login_user; //当前登陆用户, 调用get_login_info后获取% i- t; ?* R8 R
- & [/ B! C' e9 {) A3 m: F* m
- public function __construct($options)
k5 R* ^2 Y/ J1 k - {# Q: b0 R' u) d2 r, ~
- $this->_account = isset($options['account'])?$options['account']:'';7 N! c3 ^$ X+ G8 g6 O" T& h
- $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
. T$ i) v$ s! I- r5 } - $this->debug = isset($options['debug'])?$options['debug']:false;
' Z; P; Q) L! D4 D* O2 `" H4 z - $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
^& B- U1 V9 ?3 a" `! l - $this->_cookiename = $this->_datapath.$this->_account;
# l# D" u3 p# G3 B' r# q - $this->getCookie($this->_cookiename);
2 {& J u7 u# J5 u' p - }! {% {0 Z# \! p6 P2 W
- /**6 K6 Z. c: U1 X/ Y
- * 把cookie写入缓存; c0 N+ L) \9 ?; S( ^# m1 p
- * @param string $filename 缓存文件名4 a2 |1 z2 E- y7 E# a9 B4 v
- * @param string $content 文件内容
! i! G8 [& Y' @& w3 X5 f. r1 F8 J- ^3 @ - * @return bool
# \! w( f! _' A3 ? - */, v, q3 W; k, g4 v8 n
- public function saveCookie($filename,$content){
# [( k ]$ V) t+ @ - return file_put_contents($filename,$content);
% Z' g+ R" M0 K% p% d5 L u& i: e - }
S& J" q: H# N
8 d1 J; l# `, h5 c' p; y: @- /**' h8 d( h$ n6 E$ M; O/ k
- * 读取cookie缓存内容
+ N$ Z; |# n- ?) j1 J. x {0 V - * @param string $filename 缓存文件名
! D% r7 `& W- }2 ^6 T0 f - * @return string cookie7 ]: V* M) |/ ~$ a9 e- A
- */
! S K. F3 b9 x. _) G o - public function getCookie($filename){+ _6 ~/ W7 s: x$ j1 k3 C
- if (file_exists($filename)) {
% q( [* R% A8 g) d. L - $mtime = filemtime($filename);
, m" W. M1 U$ B2 y- t; B% {& e - if ($mtime<time()-$this->_cookieexpired) return false;# @. {7 o5 K I, g, B: I
- $data = file_get_contents($filename);
8 [, i9 ?6 i( A" [& J0 F - if ($data) $this->cookie = $data;
) G1 Y. J9 h. O7 V5 p) G/ M - }
) @) h4 O7 B! W' I8 ?) i - return $this->cookie;, [. M4 Q7 ^$ L7 e5 z
- }- X: A- M% l4 N6 K$ S
-
' |* r( v0 q3 V$ y6 ` - /*
- z- L" ~1 A" h" f - * 删除cookie
) X. g6 q) B6 A; D - */
% L/ o7 m" Z# n6 ^. l7 {0 e - public function deleteCookie($filename) {
8 M F8 ?, @, }3 v - $this->cookie = '';
7 v' l" R* \1 y) k, v - @unlink($filename);7 g& K7 K; S. t/ E; n
- return true;
. @7 [: h$ I7 k6 r [5 m; e8 _5 d/ j5 a - }
+ L) M4 d! b+ p9 W - ; P) V1 k4 [# t
- private function log($log){
) s1 n* d! b/ O1 s; \+ e" { - if ($this->debug && function_exists($this->_logcallback)) {4 N& z, ], Z' f% j% _) Z+ j
- if (is_array($log)) $log = print_r($log,true);
, m# J/ K& ^1 ~$ @6 K - return call_user_func($this->_logcallback,$log);- G2 d' e1 p7 \7 U/ {1 |: X% _
- }' x% N( c* f$ O9 `8 p* m5 T4 Y7 b
- }* i$ \2 O3 u, s
-
6 F: T3 m7 D5 z+ F ^7 F! s5 k; }6 s - /**
% }0 K: T* A+ y/ c5 o" Q1 ~0 ` - * 获取登陆二维码对应的授权码& s5 ?' J' L7 z. s+ m" H8 D
- */
; @8 F+ u U+ f. g - public function get_login_code(){
2 |/ L4 D6 F$ Q6 O. m - if ($this->_logincode) return $this->_logincode;
( q, `- i2 k. C6 i5 }) G - $t = time().strval(mt_rand(100,999));5 ?$ J# e. W2 O/ {1 r
- $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 |% R2 y! q2 G; p2 l$ ~ - $send_snoopy = new Snoopy;
) k' ^4 d: I% u% Z) V - $send_snoopy->fetch($codeurl);
% N8 V5 @2 J8 J7 L% X$ n - $result = $send_snoopy->results;7 ~7 V' b# Y3 x1 ]/ r5 B0 h, e$ |
- if ($result) {3 M, }, X4 G$ F, a+ _3 M2 n$ o
- preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
3 r7 ^; }+ U2 t0 p - if(count($matches)>1) {
) e" G& z1 }4 P4 D+ _- B% S - $this->_logincode = $matches[1];; O3 I9 ^7 O0 C& T$ b* N
- $_SESSION['login_step'] = 0;- {. i) ^! }* R* @- S1 ]
- return $this->_logincode;% w) C2 d3 t- B8 z% ^4 ?
- }
- s8 U2 h* {# M" B - }
1 R' M4 V: D" C+ A. @* R - return $result;. B" Q3 Y4 V; M& Q( e! h
- }: t1 ~% ^+ m( b- i" m
( ?/ U6 T& p, g- /**; S# ~9 p/ L, x( e7 P* n6 S
- * 通过授权码获取对应的二维码图片地址
: a; ~/ Z' l P - * @param string $code
6 F u& {* E8 J7 |1 s - * @return string image url( }( M: u5 ]- L1 H
- */! h5 E1 v, h- L- O
- public function get_code_image($code=''){
- Z' K, |8 T3 B4 n* } - if ($code=='') $code = $this->_logincode;( }3 `* ]4 {9 r: C9 e! j1 q
- if (!$code) return false;
F$ Y4 o9 X! g4 e C - return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';& M4 v9 x- ^# x, Z4 h g0 [% N
- }
: D% M9 W* f8 S4 X* ?; I - 3 ~3 g% l7 I' T/ l
- /**5 J8 q& _$ G6 T9 ?4 w% c
- * 设置二维码对应的授权码
5 c6 ^) Y/ @7 l& G7 q% B8 d - * @param string $code% F7 `, V# w( j, _8 l
- * @return class $this
: X0 Y0 ]( u+ L* \7 E v - */1 _7 i. J/ E' F7 @
- public function set_login_code($code) {6 m O% H( w* ?5 @* h
- $this->_logincode = $code;: h4 H( _ q w1 E
- return $this;/ |: M( |4 @" s' j' d
- }4 N* D) `5 Q. _! S
-
( ?9 o" |& v2 u# r1 O8 v - /**
, _4 A! G" o e - * 二维码登陆验证
' T( P0 D( }* {( T8 o - *9 s# Q7 Q, B* V' }$ C
- * @return status:3 Z) a, M" K4 h+ t g, i. k; K
- * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired
0 q4 G0 \' z7 d. R" a - * 201: just scaned but not confirm% l9 H- h7 a# @0 m0 s: g
- * 200: confirm then you can get user info
: E' E1 l# l* x9 ?) C - */# [' @& @' f; @$ C: H
- public function verify_code() {
! R, ~7 u) [1 B) p" h- S0 { - if (!$this->_logincode) return false;6 W: O4 v+ i3 }
- $t = time().strval(mt_rand(100,999));$ Y& j- D& a7 K7 S0 x+ y
% @! ]) Q; I+ m1 [9 N1 `- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;
: W- u: `) v m: I - $send_snoopy = new Snoopy;
& R7 u$ x, v3 [7 ?8 b. w5 _1 Y - $send_snoopy->referer = "https://wx.qq.com/";
6 H6 a: [ K$ j3 k e7 h - $send_snoopy->fetch($url);. x$ H9 P8 k; w- j7 B0 ]
- $result = $send_snoopy->results;
$ v- u+ w, h2 v' u - $this->log('step1:'.$result);6 H8 w7 Z+ x: z9 `# Q* _4 }
- if ($result) {
5 z$ K5 O, G/ \+ y( z6 a; ^1 } - preg_match("/window\.code=(\d+)/",$result,$matches);
& N2 {# f% a q7 w3 y+ j$ f - if(count($matches)>1) {
% s( N/ g0 d7 b3 F0 J! d) u - $status = intval($matches[1]);7 h7 |9 f3 w1 `# {
- if ($status==201) $_SESSION['login_step'] = 1;7 G% r3 y2 l! B* Q; m e1 Z/ w
- if ($status==200) {4 V- Y1 T" n. _$ S/ {% k" Y; h3 u
- preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
; T0 w/ Q$ X3 I! @$ I, }: @ - $this->log('step2:'.print_r($matches,true));. ?5 R' `1 z: {. ^' e0 f
- if (count($matches)>1) {
' `( z0 n9 G+ J3 [" D - $ticket = $matches[1];/ I# B6 T5 b4 x% z6 B+ G
- $scan = $matches[2];
2 c$ J1 d6 X1 z6 d - $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';7 q& [* m- G7 {; g
- $send_snoopy = new Snoopy; . ^3 ~; q1 N* f% f
- $send_snoopy->referer = "https://wx.qq.com/";
% k( H( {" L: G' z3 b - $send_snoopy->fetch($loginurl);
3 q q N4 F' ?! e8 `8 C/ h - $this->log('step3:'.print_r($send_snoopy->headers,true));
9 N0 g4 K$ o3 X; m - foreach ($send_snoopy->headers as $key => $value) {: S8 g/ h1 S- `7 m2 k
- $value = trim($value);( i# [9 C6 `, }: W9 k: A) H9 l
- if(strpos($value,'Set-Cookie: ') !== false){
0 j6 n+ [- k" v: z - $tmp = str_replace("Set-Cookie: ","",$value);% a# V" Z2 Y9 R. _) u
- $tmp = str_replace("Path=/","",$tmp);" w2 ~' b x P% [4 W
- $tmp = str_replace("Domain=.qq.com; ","",$tmp);9 [' q% z! z" [
- $cookie.=$tmp;+ }7 u6 C7 R+ m
- }; f/ d" T0 K( l! f( P
- }2 C0 W7 q+ c8 j8 a& Q+ w$ S3 h
- $cookie .="Domain=.qq.com;";
, I9 I; w+ l6 [7 f- Q+ { f - $this->cookie = $cookie;# w7 [- R$ e [5 @
- $this->saveCookie($this->_cookiename,$this->cookie);3 B+ K6 a4 c' P6 n+ c7 W0 W4 C
- }
* Q4 M% d( s; C! a* ] - }
8 a9 P; c1 \" d0 U1 y - return $status;
7 k5 l+ w& ]0 U3 M- {+ l3 \ - }7 R: ?9 D: K5 b: {" i0 h# W, `* y
- } O: H% A. [/ h5 t/ k# w
- return false;
: `0 [+ P( Q( m2 t) V - }
+ E* u+ k2 u2 | -
* _: N8 F7 g1 B3 s, t0 f2 N - /**
4 _( p) M$ v: m' F! q - * 获取登陆的cookie1 }( Q0 c/ u( K3 Q5 }, z( Y) d
- *
7 o1 ~$ F% w5 I! Q8 N- [ - * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
5 M/ i: I/ i( g6 n0 G: U - * @return string|array8 o$ c0 E2 i( n# i8 W% A
- */ ^0 a' {& W9 w7 ?
- public function get_login_cookie($is_array = false){
% d0 h8 ]. p4 g0 k - if (!$is_array) return $this->cookie;5 h7 v j! y* J0 @; e5 O. Z* E
- $c_arr = explode(';',$this->cookie);
; G+ |& M( k6 v4 }& B( c - $cookie = array();
. G u# o% b3 h, B4 _ - foreach($c_arr as $item) {
% I3 u1 H0 F; F/ a$ X - $kitem = explode('=',trim($item));
0 G& `$ _9 C* M" d/ E" t$ Z. a; X* R3 J - if (count($kitem)>1) {
! V! o+ A2 Z8 F8 O - $key = trim($kitem[0]);9 ^# u1 w$ K5 W3 r- b
- $val = trim($kitem[1]);& m- b0 C6 @. U$ e1 ]
- if (!empty($val)) $cookie[$key] = $val;. p: \) ~- t% R9 t5 U: o3 C
- }
) o4 A$ z( e1 {6 W8 }0 v, | - }
" J+ y( `, p0 \5 R. Y, } - return $cookie;& y4 T, e9 f, @% D: @
- }
8 i. t0 l9 C( C5 @) q& R - 3 H9 I% p' ?% A' B/ N0 F8 R c
- /**3 f" m3 k1 v' r$ U7 D' Q4 j; H6 I
- * 授权登陆后获取用户登陆信息
5 k, C6 g z% f; V- o+ A/ y; o - */; B& x& b- Y8 I2 L' }- \
- public function get_login_info(){$ g+ I- x$ Y k4 f X/ v, R W
- if (!$this->cookie) return false;1 y* s0 b( ]: A ^& u! e+ x6 Y
- $t = time().strval(mt_rand(100,999));* E8 r4 j7 m$ i3 q; B
- $send_snoopy = new Snoopy; ) j! t; r5 W: F' V+ Y, J
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
5 N& J1 e- `8 h& w+ b - $send_snoopy->rawheaders['Cookie']= $this->cookie;& k4 K* u5 }* |& P1 W- x1 F: y; k8 Y
- $send_snoopy->referer = "https://wx.qq.com/";& w7 T' z9 y' r0 }. H
- $send_snoopy->submit($submit,array());
% b& h' F6 W( g, q+ c# D - $this->log('login_info:'.$send_snoopy->results);, l1 E1 c9 V: g; U/ p
- $result = json_decode($send_snoopy->results,true);' N, ~; x8 l. m$ J: F# i
- if ($result['BaseResponse']['Ret']<0) return false;
' G& H+ v0 k+ t9 a4 a" ~ - $this->_login_user = $result['User'];; D% M' E# w. `9 I6 k
- return $result;
( j; D6 y8 p+ r* W7 ^7 o - }
# L7 v. t' u9 N - - Q- @/ Z# B- t
- /**
5 H6 y# h( i. J& T q7 i7 C+ s" K - * 获取头像& K! _0 @. D' y0 {. K4 w
- * @param string $url 传入从用户信息接口获取到的头像地址6 m4 u2 X; K7 a5 i: |9 m ?
- */9 ]4 T4 w9 _; r" Z
- public function get_avatar($url) {* j/ T9 Q5 z) @0 B/ ?( [) o9 o
- if (!$this->cookie) return false;
$ Q; v* i! X% W6 t: v0 h$ H3 ?- ] - if (strpos($url, 'http')===false) {# z/ S5 n0 V/ O }8 q4 t+ W
- $url = 'http://wx.qq.com'.$url;
4 E+ e1 w f% ^! `, Q2 G - }
% w4 t% c: s3 G% H. R4 I/ s - $send_snoopy = new Snoopy; % x+ N* c0 q7 s4 ^3 C8 h) r
- $send_snoopy->rawheaders['Cookie']= $this->cookie;
. _6 s) |( y4 r4 G+ m4 Y- C1 V& [ - $send_snoopy->referer = "https://wx.qq.com/";6 B! p( s# X: v) ^/ _8 o
- $send_snoopy->fetch($url);1 f0 L3 y3 q: s% v6 {2 d- t7 {
- $result = $send_snoopy->results;9 t3 s% l7 w. L5 U( }" z4 {) H
- if ($result) 1 p; e l- J# n/ J( Q
- return $result;
7 t5 O1 A. J! i! Q o( p+ L8 A9 M - else
9 T7 s# Y" Y5 I/ v- o' E - return false;
6 l; w, D6 H: T2 X4 ]5 u# m/ z1 Q$ B - }
- c, ^! ?% \3 {* n3 G* r: V3 a - . |* i: b9 Q4 G( {3 V z% R
- /**
- h: f0 C8 U2 T* g! j2 x - * 登出当前登陆用户4 z: j) t) N a, C m
- */
. b/ J- g5 Y8 e9 ^4 b- l - public function logout(){4 a( q# a" M+ M5 g
- if (!$this->cookie) return false;
5 ?+ d& u! ]) x5 r* f; \, H$ A! V - preg_match("/wxuin=(\w+);/",$this->cookie,$matches);4 s2 K4 M6 C r) o
- if (count($matches)>1) $uid = $matches[1];
% ]4 E2 z& F9 p* Q' m- x - preg_match("/wxsid=(\w+);/",$this->cookie,$matches);! o4 t( T5 _# L$ a1 Z
- if (count($matches)>1) $sid = $matches[1];
, d9 I6 B/ {9 K8 ~' d - $this->log('logout: uid='.$uid.';sid='.$sid);7 F, o) v& U9 u2 v2 m
- $send_snoopy = new Snoopy; ' Z8 d5 l! T' Z) [, n% n9 r6 N
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
" g6 E* Y: d. B - $send_snoopy->rawheaders['Cookie']= $this->cookie;: {9 w% _* E+ M+ b: z( Y
- $send_snoopy->referer = "https://wx.qq.com/";) _. |- |; Q( @4 s) y0 L
- $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
; e0 L' h; J' V5 d" K: d - $this->deleteCookie($this->_cookiename);; H w7 g$ K) ~4 v6 ^, z
- return true;
2 ~6 ?+ g0 |$ D) e6 c: A - }
, V0 h# v+ E5 z) \ - }
复制代码
7 z( |3 v, T5 o |