用户通过扫描网页提供的二维码实现登陆信息获取
0 c1 F. n) ~4 `# u) b! f- <?php
+ M) f/ @, n% n& @( J6 ~+ j: n - /**. }6 G( x% O: a8 r
- * 微信公众平台PHP-SDK
6 I; d. A5 {/ h( k - * Wechatauth为非官方微信登陆API
' M) u7 M2 v+ S$ `# s6 ]$ E - * 用户通过扫描网页提供的二维码实现登陆信息获取
; y4 H1 @4 W8 ?3 i9 j0 `) _ - * 主要实现如下功能:) q; E1 I! V% s
- * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
# E" P8 ]- W) L, W, J: s - * get_code_image($code='') 将上面获取的授权码转换为图片二维码0 v! t: ]5 v. P9 I0 J
- * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.* g% f/ \) ?* ^' X \
- * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息* J9 I% l. C; K1 ]% v- O
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
; j2 c% Y' L {" u! g+ Q - * get_avatar($url) 获取用户头像图片数据
+ D/ q: U* ^( t2 m8 h - * @author dodge <dodgepudding@gmail.com>
, K2 j9 _3 H6 D/ B - * @link https://github.com/dodgepudding/wechat-php-sdk f; B- Y5 b! ]" G$ e9 o: n/ M
- * @version 1.1
- D( n$ V, [& a. _, [5 u. N$ q! p* u5 V& i - * 5 V6 V( h: _6 V3 W$ r* _. y, k
- */6 [ P% v' n6 O
- include "snoopy.class.php";* U9 }+ |0 a& Z1 {- R8 e# G
- class Wechatauth
8 X, v) @5 a1 W! U; \/ d2 o* V - {
- s6 {7 P/ L' h9 c9 _3 o8 U' r - private $cookie;8 r5 T4 `3 K# n; H) P
- private $_cookiename;1 W& q0 }) f, T
- private $_cookieexpired = 3600;: t- J/ j2 C: P4 y+ O& a
- private $_account = 'test';. i/ M. V" u( W; K% g
- private $_datapath = './data/cookie_';) D2 U2 K2 Q6 d; Y' r
- private $debug;
; _% t6 R" n" f - private $_logcallback;
$ v0 |, L7 Y. m n. v - public $login_user; //当前登陆用户, 调用get_login_info后获取" ^: w& d2 _4 G ` C
-
1 v+ i! `- \/ J - public function __construct($options)/ }2 q- A) x' N9 U& R
- {- U3 S2 H% O1 G) k# ^
- $this->_account = isset($options['account'])?$options['account']:'';
4 c0 \& j B5 W3 o - $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
) {6 ?1 b0 X$ I$ r! Q$ |- R - $this->debug = isset($options['debug'])?$options['debug']:false;2 U3 v8 V# L% A2 ]. s" Q1 u% x
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;- D$ S+ r/ ?& L
- $this->_cookiename = $this->_datapath.$this->_account;% v0 n3 B- C( c' [% M
- $this->getCookie($this->_cookiename);
+ G P ]+ ?% t/ x1 B& ] - }
$ I6 D! v: J' r' D+ C- E) z' C - /*** |' q5 ]% n! Z# F4 D
- * 把cookie写入缓存& `5 j5 e! H* h
- * @param string $filename 缓存文件名& j" [0 I2 t$ f. X: q
- * @param string $content 文件内容
' m% v, I4 }% P: ?7 N - * @return bool; y: w# \. n# l, X1 a
- */
! w9 m& h! C1 G1 V* l - public function saveCookie($filename,$content){
7 E" A0 X6 c m% i8 ^- Y7 W# |7 D - return file_put_contents($filename,$content);
/ F, @9 ], d* v$ X. f4 M! W. E6 V2 h - }& N( ^+ j4 i, _
- ! c7 @4 ^9 x! `, A
- /**3 r' L4 \1 J2 T, v* X
- * 读取cookie缓存内容
' f1 f1 O0 h! r7 a) T- ~# \& j: Y; `% m - * @param string $filename 缓存文件名
+ U4 g }7 _/ F7 L! S( O! N" T1 } - * @return string cookie" n2 i. q# p" b% [, i1 p& Q
- */* d( I* j; l; x$ I) o, n) s
- public function getCookie($filename){
?" w* r+ R& N7 o4 A3 g - if (file_exists($filename)) {
! H1 k+ q9 g6 H3 L - $mtime = filemtime($filename);
, m B2 T; }1 [' `% t. k' q" G3 k - if ($mtime<time()-$this->_cookieexpired) return false;
9 C8 `5 E9 p5 a9 B% A - $data = file_get_contents($filename);
; h9 m- y0 K/ }! U. i& h - if ($data) $this->cookie = $data;& q+ G' \; W" r% h+ e
- } 1 F& T& v( Q }0 W
- return $this->cookie;' B. Z6 N( Q$ H2 ?7 R9 g( q
- }% e. y: T! V4 O8 M: D: L) e, _
- 9 e; j2 @9 L T, m+ _
- /*5 b4 }, L* S Q( C8 Q( `8 j! P3 R
- * 删除cookie
* q# T/ N8 W, \) o' _# S/ r - */) a ^( H/ u, \
- public function deleteCookie($filename) {) X j' Z4 }# D
- $this->cookie = '';9 o6 S% |4 c& O. y: g- t! V
- @unlink($filename);' [$ p0 J" t5 W9 N7 X
- return true;
; f7 h o9 w- w! a% i - }" j- G+ X% n! @8 r" C3 ~6 l
-
! O3 G" F4 K5 T - private function log($log){
7 C }& g' T ^! X) w - if ($this->debug && function_exists($this->_logcallback)) {
M, y, l: b: n6 t7 L4 h5 s& K - if (is_array($log)) $log = print_r($log,true);
1 l6 H" O5 r4 J$ w - return call_user_func($this->_logcallback,$log);! }7 a# l! W6 W5 g! K
- }3 O) P5 N' l. z
- }) F- @% u! n: W
- 6 l/ N9 [6 r4 V& ~" h" _ J$ W
- /**6 u4 R" `* m* x9 |3 \
- * 获取登陆二维码对应的授权码
- {/ {# |7 h; k, \ - */
4 k- r3 y- x6 J7 o, m! u# Z1 p, I - public function get_login_code(){: Q" B4 g+ Z' s7 n1 B. C1 W
- if ($this->_logincode) return $this->_logincode;3 _; s! w; X* `8 J; O
- $t = time().strval(mt_rand(100,999));
% |* B* V- \+ s - $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;
* E/ S! x4 g0 R" W6 r - $send_snoopy = new Snoopy;
' U( E- d, M# B - $send_snoopy->fetch($codeurl);
" X3 w; h3 t, J4 |4 h0 Z: K W3 ] - $result = $send_snoopy->results;
0 w7 a- m+ Z: L9 x0 d" O - if ($result) {
! ^: Q9 h: G5 T% D; i - preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
- v* s& f+ @# t5 {* F - if(count($matches)>1) {$ C4 w* s4 [" K r$ s- O$ z5 V
- $this->_logincode = $matches[1];
2 {+ D% F4 ?7 k; f$ S - $_SESSION['login_step'] = 0;
3 v/ V4 z' }2 s0 }) D& V' q - return $this->_logincode;
1 f) q& y5 J+ G- ]% ~2 K3 S - }! x" i& g4 j% F3 @6 g
- }
C' u$ T9 l* R7 T - return $result;
# D5 K3 }- \, \$ Z5 Y( }; F$ B( f - }
6 B, k+ e: a/ a0 s" k - ' d* s5 V/ Q. Z3 M0 L
- /**; r) ~9 ~5 e/ c* U: Z! r' H8 A2 N4 J4 u
- * 通过授权码获取对应的二维码图片地址' w: b7 k+ X! Y
- * @param string $code) i2 l& ]7 [" U
- * @return string image url
7 X$ R1 a3 Z4 z - */
( r, @) |1 i3 {/ q - public function get_code_image($code=''){
( j2 L1 m8 g7 M, Y# P1 b4 h" `8 Y - if ($code=='') $code = $this->_logincode;, j5 ]0 o. ~: K
- if (!$code) return false;: O7 m* m0 F5 m- d" M
- return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
: @6 n& N* @/ v s1 m - }
$ B9 R) S3 X' Y( U1 m& ~, i9 | - ( s) R3 |! h# y0 S/ \ z; {
- /**& e: A) ^ K# M1 ^! Z
- * 设置二维码对应的授权码
: b$ i4 z: P/ e" \ - * @param string $code
3 E* S0 d/ i# t, T/ t - * @return class $this
( D7 ^2 r, f+ l4 |5 s" ]4 P - *// P$ a5 ~* q4 U. T+ H
- public function set_login_code($code) {( [& |8 Y$ S% `3 g7 ~- m( J1 Q
- $this->_logincode = $code;3 m8 o& g3 x# H1 i. _2 f0 O
- return $this;
$ K7 {/ J2 R- ]. y6 M: l2 a - }
$ \8 l# K$ D2 ^1 e -
# q* v7 J7 Z& \# G - /**
: x, J0 O% S, T, S0 V: \ - * 二维码登陆验证% y# J- {, o, N8 l- f R
- *5 S* p, D) n' s% W2 q( B
- * @return status:- u! k1 M) ]/ Y6 g
- * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired# q/ |4 p) R j) H5 W3 o% U# g2 `) z+ n
- * 201: just scaned but not confirm. B1 |' j1 Z. Q# z& ~5 k7 J
- * 200: confirm then you can get user info" ^; | f3 }1 D# g- r/ T
- */* Z9 I+ ?6 k2 G! i+ z* W
- public function verify_code() {
1 [! O! [3 L: N' \7 z - if (!$this->_logincode) return false;
@2 E5 ?9 O. {0 e& k - $t = time().strval(mt_rand(100,999));
2 t% T! o6 ?% @; J7 v, j
3 L% L) h" n2 Z0 j c/ _" K2 I- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;- C7 K: k+ ^2 x6 u. J5 ] O
- $send_snoopy = new Snoopy; / e1 }4 K3 w* Z5 j4 D$ `; Y" w
- $send_snoopy->referer = "https://wx.qq.com/";9 U& N) S/ e9 w
- $send_snoopy->fetch($url);
, i3 n! k2 M9 t6 ^4 ] - $result = $send_snoopy->results;
7 a# C, x7 u: L3 F g - $this->log('step1:'.$result);# `; O* L0 q* I |
- if ($result) {' |, n- B3 [, o5 Z% w4 A
- preg_match("/window\.code=(\d+)/",$result,$matches);6 Q4 p0 e7 u6 f m! z
- if(count($matches)>1) {4 Q5 ?1 a' f( q
- $status = intval($matches[1]);9 r, @$ c2 r. G3 q$ C& }( K) V# L6 M
- if ($status==201) $_SESSION['login_step'] = 1;2 j" ~/ g: J7 m4 u+ {
- if ($status==200) {
: J+ p# v6 O$ Z2 a2 ^ c - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
8 E! P. H3 `. ] - $this->log('step2:'.print_r($matches,true));% O: s; W1 U. q* G7 b/ Z8 z
- if (count($matches)>1) {0 ]6 e0 ?" Y$ U3 x( G
- $ticket = $matches[1];2 c3 V& V' I6 s% ?, P; ]* p6 J2 P
- $scan = $matches[2];! ~' H2 O5 D" u5 [& V/ f- Z& V6 j
- $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';/ H6 A. }4 e8 q7 q4 i' i7 i2 i \
- $send_snoopy = new Snoopy;
" I' E+ Y) k$ U3 g2 J* H - $send_snoopy->referer = "https://wx.qq.com/";
& ~: C$ w+ }8 A! N - $send_snoopy->fetch($loginurl);4 i( w& Z1 O* V; y/ f x1 R1 E) I
- $this->log('step3:'.print_r($send_snoopy->headers,true));" c& C, C N3 A: y
- foreach ($send_snoopy->headers as $key => $value) {* k4 z0 i7 D0 H1 e
- $value = trim($value);7 g' b* Q) H' z2 G- P! r+ ?1 g0 u
- if(strpos($value,'Set-Cookie: ') !== false){. m7 y2 c/ b: M O0 z
- $tmp = str_replace("Set-Cookie: ","",$value);
6 _. {( x" N2 q- m/ w! R% y - $tmp = str_replace("Path=/","",$tmp);
- I" ~) q, ]' o* z+ z$ `" B - $tmp = str_replace("Domain=.qq.com; ","",$tmp);
$ L4 i( ^- ?2 M2 V% V# T - $cookie.=$tmp;
* j! S# Z+ G* B4 h l - }# Q! d% D# Z1 t" j
- }2 h* J7 c4 J1 ^' {& ^
- $cookie .="Domain=.qq.com;";
( G& Z6 D: O% ^: D - $this->cookie = $cookie;
; x8 }; d3 D6 T' Z, _ - $this->saveCookie($this->_cookiename,$this->cookie);) M3 E1 k; b; T8 c6 \
- }( Z L% n- ]+ m+ A3 Y0 G: M
- }
; P* I+ E6 b- K7 l" q - return $status;
! |! j' B5 j% h" m1 m) ]# `! f - }
% T$ e- A5 N W! J - }+ {3 N, s E5 G8 P- V
- return false;- R9 P6 `0 V& R4 G3 f/ A
- }
! A# h: p) |* e+ R+ Z8 c( R -
- C w" U J! }* K0 ]0 S$ {- f - /**
, R* T8 ~3 Y2 F! ^ - * 获取登陆的cookie( }1 N( a* N' S T, k; E$ U( h2 Q$ C
- *
y& D# X! p4 p5 U5 ~" d - * @param bool $is_array 是否以数值方式返回,默认否,返回字符串% ~+ h }. o2 u# h
- * @return string|array
5 G3 F. b& E6 \; ^* [) Q - */6 Y: u8 X& D7 }7 L a% C e `, f
- public function get_login_cookie($is_array = false){
! e7 j6 a) r) F - if (!$is_array) return $this->cookie;9 ~7 k Z% l: n+ y: L6 ?" J: ]$ p8 x
- $c_arr = explode(';',$this->cookie);
7 r i9 V8 |# W/ l, G - $cookie = array();
& K2 ~! R: i5 m- j - foreach($c_arr as $item) {
7 ~0 B3 q0 C3 N9 X - $kitem = explode('=',trim($item));( E! Z8 y7 x: z3 U x- U
- if (count($kitem)>1) {
4 |2 N. d' ?# X$ L - $key = trim($kitem[0]);
. j- g2 M+ h5 d) }7 n4 {0 t - $val = trim($kitem[1]);
) M* u0 I$ [5 O0 }* R. e - if (!empty($val)) $cookie[$key] = $val;
" Z S* o- `8 a9 Y- Q6 u - }
`! W0 \0 c' E. t1 K( B* L - }
! k2 G, y4 @% a# `4 e0 f5 H4 j - return $cookie;0 `: d2 z6 \9 s. \/ j; w, w
- } d: ?* A9 {0 O; f7 k
- ! Z$ G8 v# Z. }6 \+ [
- /**
- P! P+ t; f+ l2 k - * 授权登陆后获取用户登陆信息) z! o! G a5 W9 h [
- */$ \: F) }8 S6 ?, p# {
- public function get_login_info(){
- `5 z7 x) e3 X3 o - if (!$this->cookie) return false;6 a. H- j6 `- ^! U
- $t = time().strval(mt_rand(100,999));
% X* J" I( h' S* N; m. |) i4 @ - $send_snoopy = new Snoopy; - E+ S* D3 V, v% u$ r w$ L
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
E5 F/ u5 | v3 K9 Q' N - $send_snoopy->rawheaders['Cookie']= $this->cookie;+ j; i% c6 ~4 j: U
- $send_snoopy->referer = "https://wx.qq.com/";9 j: ^: A* z8 H7 z! [2 T7 k- ?
- $send_snoopy->submit($submit,array());9 f' H1 i8 _9 v. w. Q8 y0 m. N Y
- $this->log('login_info:'.$send_snoopy->results);2 T4 h9 k- H% i: R% B) v* r% J
- $result = json_decode($send_snoopy->results,true);
, v1 B4 P4 M, t' K# q: m - if ($result['BaseResponse']['Ret']<0) return false;7 a& ~" ~& q7 @) I2 }8 I
- $this->_login_user = $result['User'];
3 y1 [3 K8 C9 A8 J$ Y - return $result;
- z( X n, l8 c5 V0 ] - }$ L3 e2 |. m" I# m
-
$ L' } p3 N7 j8 e7 i& v( I* z - /**- F, U! a7 N( T# ]! K
- * 获取头像4 F0 W+ ~# K. u$ }& U# x
- * @param string $url 传入从用户信息接口获取到的头像地址) g+ x* `' U/ l8 P$ U6 i
- */
' @% b, O; `% x/ P8 ~ K - public function get_avatar($url) {( _3 q+ O1 r7 Z% }/ k) n/ A5 J( E
- if (!$this->cookie) return false;
. M( }4 H/ Z% r3 L - if (strpos($url, 'http')===false) {6 X. W# E; B# M; m8 x8 ^
- $url = 'http://wx.qq.com'.$url;) }* h2 L" U) P9 @4 \
- }# W: }; g9 b5 a S/ y
- $send_snoopy = new Snoopy;
" J3 e* b" P: L( N0 d2 ? - $send_snoopy->rawheaders['Cookie']= $this->cookie;. }* F1 P& J3 ]
- $send_snoopy->referer = "https://wx.qq.com/";& @ f& v0 o$ B6 g0 c
- $send_snoopy->fetch($url);
$ [! I( d; I0 ^5 P; [ - $result = $send_snoopy->results;$ q& ~3 J0 N6 t3 d' z
- if ($result)
: D6 @) n6 u) r5 z# s - return $result;
; F; ~7 D- p* T1 Z- o( r - else
) V/ f9 M% d ^2 ?5 H. ] - return false;! v* {- t+ P) W. _& V3 w
- }
0 [7 d4 R# j1 x! t! P: l - % S1 G3 z, {% l4 @* p* {
- /**, p3 K- ]" e1 u/ G
- * 登出当前登陆用户 m9 }4 I& \" N7 z
- *// R6 u: \8 a6 a4 D2 W, {% Z. ]
- public function logout(){
6 W7 D0 p+ }/ x; c o5 p" T - if (!$this->cookie) return false;
% Z+ g: A, ~& p0 C7 ]6 u - preg_match("/wxuin=(\w+);/",$this->cookie,$matches);9 G1 C3 l* ^& [" P w1 M
- if (count($matches)>1) $uid = $matches[1];: E' h( ~, ?, f; d2 Q( x' d2 @3 A
- preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
8 `6 |1 w$ s. l7 i) q( ` - if (count($matches)>1) $sid = $matches[1];+ d% O1 n( h# f! C- \7 a1 g
- $this->log('logout: uid='.$uid.';sid='.$sid);
$ T: L( s6 H2 C0 j+ e - $send_snoopy = new Snoopy; , K l9 ~" B) y$ t! J3 z! j* P
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
' y" y9 x) Y9 s! v4 z0 N - $send_snoopy->rawheaders['Cookie']= $this->cookie;2 t; d8 g( D1 W4 K, t
- $send_snoopy->referer = "https://wx.qq.com/";
! o1 Y* L& I3 G9 i" y' W - $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));5 D9 u' o6 t3 g# K; }
- $this->deleteCookie($this->_cookiename);
9 n" u& ^+ s: B# B: W$ K - return true;) E) e( x* ^, H, `+ [
- }" d3 E& ^5 M0 g2 _6 i- c6 d
- }
复制代码 % W( ]7 X/ f0 U) Z
|