用户通过扫描网页提供的二维码实现登陆信息获取
+ a% I9 |. U, p% C- <?php. R, r6 G+ r7 `
- /**; L& N5 V6 S" ~+ T N! L
- * 微信公众平台PHP-SDK
. n" P' |9 C% e4 g5 K# ^, v' a( s0 _ - * Wechatauth为非官方微信登陆API: ]. s. F5 L$ T; [$ b
- * 用户通过扫描网页提供的二维码实现登陆信息获取7 c1 e% v( v0 M. m( i; f
- * 主要实现如下功能:
8 O2 p5 o3 D. W% [7 e' A- r4 p - * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码7 [4 H2 i [ b; o& x# q T( T e
- * get_code_image($code='') 将上面获取的授权码转换为图片二维码! m* r$ F7 R* s8 |* C
- * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.( r5 l, W; i& h0 Y; a% C( b7 B; ?
- * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息" m7 ]+ u- x! S3 X- z) P- n" f: P0 v. S
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息; H2 v; u. q# e$ `
- * get_avatar($url) 获取用户头像图片数据& `' n1 @+ m8 {: F4 s( ~
- * @author dodge <dodgepudding@gmail.com>- U3 |4 g" Q2 [* I
- * @link https://github.com/dodgepudding/wechat-php-sdk/ d; E, y6 n/ T: @3 ~$ h
- * @version 1.15 ?* G& F( h% H- p( o7 `4 H
- *
& ~/ G7 R6 z Q0 _& G0 x. ~ - */
9 T8 \4 j% }) s2 }# i4 ? - include "snoopy.class.php";
6 u/ U& z2 c, a) s0 [" N2 W - class Wechatauth% e7 s C' G0 n+ r2 w
- {, P# U0 E3 T; h/ |0 y
- private $cookie;
8 C5 _7 u; ]+ @/ a; D; M8 s! ^; K$ Z - private $_cookiename;
6 h- a9 b; J5 C3 _5 T8 u - private $_cookieexpired = 3600;3 z9 Y1 _/ Q! K$ Z8 g/ m, K1 s
- private $_account = 'test';3 e0 E( j0 E, D( q- l
- private $_datapath = './data/cookie_';/ [( p& w( z4 C5 v
- private $debug;" g1 F- b3 Q! h
- private $_logcallback;) F8 @& z, F8 l/ W) l
- public $login_user; //当前登陆用户, 调用get_login_info后获取
* a" [, F; N A1 m7 M$ l* \5 p -
, E9 ~1 t8 @7 ? - public function __construct($options)' m0 G( x* Y, n3 H( }9 r
- {. A! g/ r0 i6 i( `% r! F. X
- $this->_account = isset($options['account'])?$options['account']:'';
" q2 t! v- m+ H# N2 n - $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;& ]; c' o' d* u' A. E1 ]6 c9 M+ l
- $this->debug = isset($options['debug'])?$options['debug']:false;6 A0 \) V+ y2 K
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;- B2 G$ I, t# E. e/ |1 q( I
- $this->_cookiename = $this->_datapath.$this->_account;
% L' z& K# ^ b; Q - $this->getCookie($this->_cookiename);
* n' ^( Z" `; P- p$ K# ^$ E, a s% _ - }8 \7 ~& l& o' ^1 `3 z
- /**
. X6 s) x& c; r/ |( R - * 把cookie写入缓存* i+ A# B* y9 G ^2 g
- * @param string $filename 缓存文件名9 e8 \) B$ i! v6 c* K* W
- * @param string $content 文件内容3 M4 n- Z) j1 d* u5 c4 W1 U6 W
- * @return bool! w6 |6 \8 d. b2 Z" ]
- */8 k7 ~% j. H5 w" i; N7 c. q: ?8 h
- public function saveCookie($filename,$content){7 ~8 w- E; V1 ?9 T) | _
- return file_put_contents($filename,$content);
3 S$ I4 V' }, ^8 Z8 d" B - }# d% L/ b: A+ C$ e" U
# H$ R: T" \& U6 e# \/ {- /**! T. b4 z# v2 q3 s: ?% o3 m+ E
- * 读取cookie缓存内容) @. [* M! I; g& j% k& Z5 u
- * @param string $filename 缓存文件名; _- p4 E- t1 F6 X! `5 |
- * @return string cookie
5 s" ?. H9 _8 {7 u - */* ^& Z( e W! e2 Q$ V8 g
- public function getCookie($filename){
$ L0 N# A2 o8 u3 P3 K* d - if (file_exists($filename)) {9 p& d6 C* A: m8 `# V' }! W* N6 e
- $mtime = filemtime($filename);
# V5 K- Y' ~/ [6 q% F# V( B7 | - if ($mtime<time()-$this->_cookieexpired) return false;
/ a ^$ @7 w: g. `+ D - $data = file_get_contents($filename);: u5 K! ^) K D3 r0 N: v
- if ($data) $this->cookie = $data;
, |+ N# x1 B5 O. X+ m$ z - }
; B9 K5 p+ |8 m+ U% J* ` - return $this->cookie;/ F. z" [7 B4 h* A7 k2 A7 f! O
- }
1 e6 U4 {/ R5 C0 i& H7 G -
& z- _* f; s+ x D( z0 O* n; k - /*7 [7 i% ^# P8 z v, v; o
- * 删除cookie
5 w& m2 M; A) K - */: j, R2 y1 [1 A# p5 b; p# {' k. @
- public function deleteCookie($filename) {+ @2 H7 d, [, K6 u" o
- $this->cookie = '';6 X" `, ?# M- u+ w8 c. Z9 a: a
- @unlink($filename);
2 \5 A* \) ^% p - return true;9 y8 G5 A0 X& o/ }2 i9 ]" j; d
- }# A0 B( {/ B/ F' W: O
-
, A9 Y9 T% L- F D/ } - private function log($log){
9 A; J/ x v/ }0 P: x% ~ - if ($this->debug && function_exists($this->_logcallback)) {. R2 g5 l7 F3 g7 J6 D9 A, e5 F
- if (is_array($log)) $log = print_r($log,true);
2 z: y% E8 x! |+ n q; @ - return call_user_func($this->_logcallback,$log);
~5 P' V0 c0 r, f! t - }
, t6 @7 D+ o) \ - }2 U4 L( F8 g9 } o4 ]# ^ c2 y
-
% H* ~3 n! v4 @) w - /**2 Y- U1 Z# P( A! E7 ]
- * 获取登陆二维码对应的授权码
$ g( k/ g+ r4 F7 P# t - */
, }9 E4 T& A) o& R! ? - public function get_login_code(){
! M1 x! e1 H @! x - if ($this->_logincode) return $this->_logincode;$ A" q- V9 j1 ]0 S! N1 ]
- $t = time().strval(mt_rand(100,999));
5 V( m2 l2 h; O& e$ 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;
/ E, f T) V1 g# X' C5 A4 h" j - $send_snoopy = new Snoopy; " Z5 ?( S: ?- q: O+ t
- $send_snoopy->fetch($codeurl);, ]' I; Q' S* e3 G2 P
- $result = $send_snoopy->results;
" m% h" ?: p+ q0 A - if ($result) {7 B$ p- d; z1 a" _( G$ U5 r9 C
- preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
: d8 y& r2 b9 v( M+ e; U - if(count($matches)>1) {& D. l* H6 L+ N, c5 H. r
- $this->_logincode = $matches[1];5 ]+ ~, }1 C% f/ u% M
- $_SESSION['login_step'] = 0;5 G( X& D) K: t8 u
- return $this->_logincode;
2 _$ w1 s" W$ @+ x6 D - }4 X7 V) U. X( \2 y% o
- }& k8 ~& M! J, J$ q4 H% _
- return $result;* f8 X8 X7 z' ?* Z
- }
G+ L2 {7 r$ b$ I% m
" Z4 k( ~, t' y( O& d( J- /**# r' y4 H9 m# B# m- } d
- * 通过授权码获取对应的二维码图片地址2 t6 y' a" F' _
- * @param string $code$ U& ]& X9 p" r$ V
- * @return string image url
6 F4 { _$ E6 ]/ Y1 k0 d! e4 _ - */
' g$ G& T/ Q/ f B' A0 `& s - public function get_code_image($code=''){( ]$ X: X. i! k8 G/ G' M1 C" o
- if ($code=='') $code = $this->_logincode; k( x# ^: j# B) Q4 _5 }) K+ k
- if (!$code) return false;
) G+ _0 U- Q0 ] J. L1 D - return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
# u/ V$ @5 j3 a: w+ @ - }
& n3 i" W) m- t' q" `4 p/ d+ M -
1 |: i V. `1 o; }9 ~ - /**
T# u T8 ]& m t/ X, Z u* z9 z0 ^! [ - * 设置二维码对应的授权码2 U+ E; x, a* J1 _9 C# F
- * @param string $code: \/ s( g5 y% n2 n2 C: l; ?
- * @return class $this
& q5 V8 I+ i) V. j4 C# s6 ? - */" F" c$ M7 \+ F7 M
- public function set_login_code($code) {1 P7 ^1 M( m5 u- D# F8 Z
- $this->_logincode = $code;( ]% N; S- ]! Z4 s5 y9 _
- return $this;
+ G& N7 T* ~8 ?) ?& A/ Q- D! f' { - }
' Y1 o2 N3 r! c/ ?) c - 2 t! e1 w( S! C) R9 u
- /**
+ }1 `# Z' M- l' i0 W, h7 y( Y - * 二维码登陆验证
. @( e4 x. v9 e8 ?5 M - *# ?# Q5 e' C. X: T; K
- * @return status:
" T7 Q6 Z) }+ X' P# i& t - * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired! C2 v; Q+ S: a
- * 201: just scaned but not confirm& W: {0 @6 @- r e5 h
- * 200: confirm then you can get user info" @* L& Q! R, i* a4 ?
- */
/ U% w) u) B5 _8 ` - public function verify_code() {
( [( J, a0 N6 {; u2 v - if (!$this->_logincode) return false;
# @2 S6 Z. D' _, U& s - $t = time().strval(mt_rand(100,999));
2 b U) Z8 ^4 e; `, x: ~ - 9 S( H$ S5 I" l- N4 M& Y
- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;3 w F8 E; M/ n. I# T
- $send_snoopy = new Snoopy; $ d, V5 y- A8 a, u8 S6 i- o
- $send_snoopy->referer = "https://wx.qq.com/";6 {5 f U, H7 H3 _' y. r
- $send_snoopy->fetch($url);
4 @1 q5 d: |! M; W- F1 \3 C - $result = $send_snoopy->results;" w+ A3 V3 f$ f U* d3 Q
- $this->log('step1:'.$result);0 j7 {5 C' ^: J. J' W
- if ($result) {- o- H) }) e1 `5 n0 }
- preg_match("/window\.code=(\d+)/",$result,$matches);
- n! F6 K* g1 ?, h9 i) U - if(count($matches)>1) {! J& n$ c2 H% f: u8 J
- $status = intval($matches[1]);3 u7 p* e+ h" u) J
- if ($status==201) $_SESSION['login_step'] = 1;
2 E9 n- Z8 Q) b - if ($status==200) {
% _% e2 K! E: o1 a1 y - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
+ X$ I5 p- \& g4 j9 Q- ~9 { - $this->log('step2:'.print_r($matches,true));
/ O b2 x# Q! R% t1 G9 Q4 D - if (count($matches)>1) {
! J& L4 @8 N7 C# x - $ticket = $matches[1];
' B, f1 G. U' Q/ ?8 m - $scan = $matches[2];
1 C4 E$ a6 G, T3 ?6 G9 t* \8 I - $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';- @& T- v. M, m3 R
- $send_snoopy = new Snoopy;
$ h9 C( t7 b. f0 q% ^ - $send_snoopy->referer = "https://wx.qq.com/";+ {0 \" ~- q: Y( Q" N9 s( S
- $send_snoopy->fetch($loginurl);! n% I! i- S8 ~2 [/ g
- $this->log('step3:'.print_r($send_snoopy->headers,true));2 z, [6 |0 g0 G8 I0 m% a
- foreach ($send_snoopy->headers as $key => $value) {
8 T$ ^7 L. o; w5 v# ? - $value = trim($value);) c& M. ]3 V+ l
- if(strpos($value,'Set-Cookie: ') !== false){. z2 [* r3 `+ ^5 M& r
- $tmp = str_replace("Set-Cookie: ","",$value);
e5 z' T9 f6 j/ ?, f6 g8 P - $tmp = str_replace("Path=/","",$tmp);
[+ L. Y2 A6 P6 A3 C5 y A. ` - $tmp = str_replace("Domain=.qq.com; ","",$tmp);+ W# H% Q, P ^. \
- $cookie.=$tmp;# J& u, d) p: x9 c* W. y
- }
% x0 @. l) \7 _) a) s, n - }
' K, }& n& k7 L+ x* ` - $cookie .="Domain=.qq.com;";0 ^4 z( m' B7 ]0 H" v4 I9 O( T
- $this->cookie = $cookie;9 f+ D; i- Z' M, J/ ]% t& \
- $this->saveCookie($this->_cookiename,$this->cookie);& z9 R* d% {: w/ n3 _
- }
, X& l1 W1 a8 \+ K# B/ e - }& `7 t- u8 s: x3 m- A* y
- return $status;
% C% E) q$ H, f, X - }$ l9 I* ]* S7 J A4 C: Z
- }* [% I% ^" W7 c$ [8 A+ P" l0 b2 ]2 k3 H4 C
- return false;' j' \, Q1 ?# T- b
- }
3 w3 }! `5 C# {* L7 n -
4 u; _$ q8 t$ H' n- l - /**
0 f2 t. ?7 e: B+ }6 q; J - * 获取登陆的cookie
6 G/ z3 h- s' P( ]# Y - *- } Q2 K* v; b4 N6 J
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串0 @! o3 F1 Z# Q8 o8 e8 [5 ^
- * @return string|array3 F" f( D' g. f( C% ~" A
- */ H, I8 {3 U% x9 C8 s* U1 U+ @
- public function get_login_cookie($is_array = false){5 }0 a0 }) M2 e+ d, P- O: `
- if (!$is_array) return $this->cookie;7 a4 z2 ^8 z& |! q% f3 D
- $c_arr = explode(';',$this->cookie);
) k1 O* v! x0 T0 ] - $cookie = array();3 k) z, @7 _2 q) Q& V) h- k
- foreach($c_arr as $item) {
. N3 u) s: w, K% Z3 f - $kitem = explode('=',trim($item));9 h' ^- z+ j6 N, r, T' B5 W
- if (count($kitem)>1) {
; D" u7 t* {' h7 t5 z y - $key = trim($kitem[0]);5 G7 {' U3 m: o+ z3 l* P
- $val = trim($kitem[1]);
( P8 k6 i+ `) t - if (!empty($val)) $cookie[$key] = $val;
! F( b% f, |+ E: [" A9 U - }
# [8 T& q. O2 P ?/ N* N - }
6 ]# ^- ~% {2 N: V- z - return $cookie;
+ Z v! U, _7 w1 E `) q. B/ C - }+ T9 g1 i+ E" J+ ?6 }9 l
-
; E" o% ]0 H# @ e - /**: {; b+ W) y) C+ s
- * 授权登陆后获取用户登陆信息% m( H" N3 B" P0 ~" t, ^/ _
- */
3 ?/ ]$ i; f- y: A9 m$ p5 S8 G, t - public function get_login_info(){
) s7 n' i) G: P! L - if (!$this->cookie) return false;" s/ y* Y# Q& G
- $t = time().strval(mt_rand(100,999));6 h. m' l. q& `, [- ]: N/ ^
- $send_snoopy = new Snoopy; : W: u. i* \1 ~
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;: ~$ W8 S9 L. k# \' X4 Y
- $send_snoopy->rawheaders['Cookie']= $this->cookie;8 j* C! N0 x: R; e0 U. d
- $send_snoopy->referer = "https://wx.qq.com/";' {' S/ Q; D. O0 g L7 k
- $send_snoopy->submit($submit,array());
4 _* I2 C2 {3 `6 [8 ^; m - $this->log('login_info:'.$send_snoopy->results);
. e. |5 S7 |3 o( w5 ^ - $result = json_decode($send_snoopy->results,true);
* h, j/ k7 {2 @ - if ($result['BaseResponse']['Ret']<0) return false;
- u$ k" ?, z4 y% r0 o - $this->_login_user = $result['User'];
7 X1 O* _% k4 t6 J) L, u - return $result;
& U% z" Z C; H* ]( k' W9 c - }
; }- r/ B0 K$ Q -
' z$ s9 o: w. M2 W K - /**3 p" ~1 L( m5 [ l+ q9 \, Q: k" S2 k4 |
- * 获取头像4 d6 [/ @. a$ d& w3 Y
- * @param string $url 传入从用户信息接口获取到的头像地址) A% Q6 l9 W$ E# I* @. i h4 y
- */
! i5 h" q* s; Q# f+ A1 Y - public function get_avatar($url) {
# Q" K0 T* j9 G6 g - if (!$this->cookie) return false;
z( _, b9 _+ G - if (strpos($url, 'http')===false) {2 h8 {' E- r& V
- $url = 'http://wx.qq.com'.$url;2 P0 L) G& \. d/ ?0 y# P! ?
- }" B- f9 r4 W9 {$ z) s- r2 e4 Y
- $send_snoopy = new Snoopy; & u8 H5 }! v" B' c
- $send_snoopy->rawheaders['Cookie']= $this->cookie;7 |; ^; |" ~# s- [6 G. S
- $send_snoopy->referer = "https://wx.qq.com/";
6 [8 d) R/ O& Z8 z: s- a, E - $send_snoopy->fetch($url);+ i$ \9 t. C5 }' z2 r$ U3 _
- $result = $send_snoopy->results;
$ Q" ^5 M4 Z: S. [2 e - if ($result) : f+ N$ C/ H8 a
- return $result;" L( z) g% F, a% [
- else
1 e# @4 Q0 e* x1 ?; {, c; k - return false;6 A. y W) q) I6 O) D8 t
- }1 S- ^7 V( Y6 u6 c7 O" g& J
- 5 b8 p9 `7 l+ S0 l/ J& {
- /**
% E; V3 u' n) p- S* @2 K - * 登出当前登陆用户1 ~9 }5 S2 B/ E2 y
- */5 Z0 {: W4 E& n! l3 N; d% y
- public function logout(){; v# H! H9 K0 o1 N/ c9 D C
- if (!$this->cookie) return false;8 d9 Y9 X4 t2 _# o+ n
- preg_match("/wxuin=(\w+);/",$this->cookie,$matches);
6 d2 I+ a; Z- Y Q+ V! T( m - if (count($matches)>1) $uid = $matches[1];
! s z, g6 W7 e7 I - preg_match("/wxsid=(\w+);/",$this->cookie,$matches);0 r2 B% a5 I! V U3 ~8 A+ m
- if (count($matches)>1) $sid = $matches[1];8 E' ~- ^1 L2 [6 \
- $this->log('logout: uid='.$uid.';sid='.$sid);4 E& x. @: n5 k5 Y6 B5 n
- $send_snoopy = new Snoopy;
2 x4 {+ {; L+ T7 @) v" E, p( D - $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
3 f% T2 P- A7 i+ Q/ f! q - $send_snoopy->rawheaders['Cookie']= $this->cookie;
( K; e, E$ b9 z+ b( C" }: g - $send_snoopy->referer = "https://wx.qq.com/";. y9 m5 h' W; P1 A
- $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
- X, c& P* K: P2 P, ? - $this->deleteCookie($this->_cookiename); E- H0 E7 w" z
- return true;
) H0 d( i& r' S! n - }
. \; g. Y6 B L/ f3 t8 l - }
复制代码
8 k/ O Q: s, ?9 Y/ K9 q |