用户通过扫描网页提供的二维码实现登陆信息获取 + F6 t, ~! J5 H7 q* M( Q4 [, v' q
- <?php
4 K" t& o! o' c w/ n - /**3 u2 |/ {. S% n+ j# g$ b0 E& s
- * 微信公众平台PHP-SDK p( ^1 F. C8 q8 L5 a& U
- * Wechatauth为非官方微信登陆API0 }' b1 x" f! H( [$ e5 [4 @
- * 用户通过扫描网页提供的二维码实现登陆信息获取
" |" T/ T# \! R/ y/ q - * 主要实现如下功能:( k% b* _" E; H- i6 v
- * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
$ A% V$ N% p- S d8 m - * get_code_image($code='') 将上面获取的授权码转换为图片二维码
- y- ~+ f% W8 t) I - * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.( {4 O5 K) Q( a$ ?" Q
- * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息9 e# h1 s- l+ R
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
+ G/ F* O( K) a( D+ r% Q, G6 e, _4 g# Q - * get_avatar($url) 获取用户头像图片数据, }/ |- h! H* L
- * @author dodge <dodgepudding@gmail.com>
; f- j) _" n8 E4 F- ~0 x - * @link https://github.com/dodgepudding/wechat-php-sdk
, \. r1 Y T, B - * @version 1.1
+ v; p0 ~* W5 b2 B! ] - *
2 M) b& d/ Y1 l1 Y) \8 `- H - *// u7 m5 U4 K6 f/ E
- include "snoopy.class.php";; Y- |1 l) I0 ]/ G( \: ]
- class Wechatauth" _" p5 z1 n8 e0 a
- {
+ C2 |( t; W/ E7 l" d& ?9 ^* V; u/ X - private $cookie;
3 N( {9 H: A+ ~7 d) Y! u: {9 S; a - private $_cookiename;
$ u% L; \6 s; [$ e9 s( J0 b - private $_cookieexpired = 3600;
) C) L& k F# R6 E( J - private $_account = 'test';3 Y2 c% k: {: x
- private $_datapath = './data/cookie_';
6 a# \1 K" `) }% i. y8 v - private $debug;
# I4 {/ Y) b$ k" c1 h# U( t% f - private $_logcallback;
1 m3 B& y# C* ]4 X - public $login_user; //当前登陆用户, 调用get_login_info后获取
2 _: {9 U0 X. M8 o$ X$ y% W1 W -
; a7 l- j, j4 { - public function __construct($options)/ a4 M" m, V8 M: X; |- W; N
- {
; ?4 b/ W( ?) p+ p - $this->_account = isset($options['account'])?$options['account']:'';. j/ k- _1 M; ^) Y) Z. |
- $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;5 z* r; k( j6 R# |
- $this->debug = isset($options['debug'])?$options['debug']:false;# B% @( ~4 S) W2 Q
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;" D* _ J- H) S7 h) G
- $this->_cookiename = $this->_datapath.$this->_account;8 c+ D: j9 a; N: O; R2 Q8 d
- $this->getCookie($this->_cookiename);8 E/ d2 R, L6 V1 Y! _. m# [7 a
- }
5 I1 ?5 t' F9 K$ `0 z& O& |/ ? - /**+ l( w& Q6 P' V# S/ t- `3 w( X5 | G
- * 把cookie写入缓存5 c( p4 p e/ D: F9 i$ Z6 J9 j* H
- * @param string $filename 缓存文件名
7 I6 H, ]- q9 q7 `- Z# x- L+ U+ l, i - * @param string $content 文件内容+ ~' r0 i6 N) b7 e
- * @return bool: Z+ v1 V, R" Z. W, u0 n
- */. [( k& l2 X; Y2 f3 k2 R
- public function saveCookie($filename,$content){8 K3 Z- ?, I7 M7 a; M B# Q
- return file_put_contents($filename,$content);2 o$ f- ?" |3 y% H
- }( V/ G8 N) n$ ~2 i: \2 l+ {
- - ]. o( F8 ~% }" V/ q6 F( A6 x
- /*** F8 S) i# t2 @7 R) i
- * 读取cookie缓存内容" X" p+ ~$ R) I4 c8 v. P
- * @param string $filename 缓存文件名
' {$ p/ ~5 ?4 N2 x; a2 p - * @return string cookie
0 u) F( |6 w! ~, Y3 `, L - */ U6 t% h8 L3 A, Q a3 ~
- public function getCookie($filename){* L5 L3 o% m+ \1 K
- if (file_exists($filename)) {
, C4 {# s3 x3 [* x - $mtime = filemtime($filename);
5 t" V# }- I' _ - if ($mtime<time()-$this->_cookieexpired) return false;9 a/ g4 ]- f7 g( u1 V
- $data = file_get_contents($filename);
* p# ~$ S' s0 v& o; N# a - if ($data) $this->cookie = $data;
2 M( k3 t& z$ U, C' I3 y - } 6 E# f) n, \$ ?
- return $this->cookie;
% ^- w- a" w( L* t - }
5 O; c7 f1 m6 `/ S' f - ! r' q. c u* J& c, C0 F1 r
- /*3 O& [" B- [7 h! n- H/ Q
- * 删除cookie8 B0 x% b7 [: I5 D8 j/ H
- */. Z+ o" {4 {% J
- public function deleteCookie($filename) {% z2 q5 a8 @6 @* P0 w- M$ t/ `
- $this->cookie = '';
+ w9 ]- [; k7 Z% _4 X# D; g - @unlink($filename);( P& V3 r) }; j
- return true;& `* ?8 b+ `- _
- }1 K K+ Y: V4 B; T% ^5 }
- " Z# w% q6 f& r+ i) c" ^1 J
- private function log($log){- b$ O5 E% `9 A/ p2 r/ m
- if ($this->debug && function_exists($this->_logcallback)) {. D1 F* s! |) j0 n2 v$ @: A" G) n6 [
- if (is_array($log)) $log = print_r($log,true);
- ^ ^# ?, Z& i - return call_user_func($this->_logcallback,$log);! t# V: `" Z7 Y' @6 U7 ~: T
- }
5 O; I" }3 s& F9 o/ x0 V - }
}8 Q4 p. R& Y8 B1 h -
% k+ k# f' k3 G - /**
; ? r, u3 o! N - * 获取登陆二维码对应的授权码/ Z1 W/ b6 c: e4 j" y3 I! m
- */
0 i- \# p' E1 U- [ - public function get_login_code(){/ ?1 ~ B" Q4 C( b- s3 ]9 I
- if ($this->_logincode) return $this->_logincode;1 s" s1 E4 _+ \+ U
- $t = time().strval(mt_rand(100,999));' B) Y0 g) H3 {$ [9 ]. 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;+ G6 T) a3 p* ?7 o. v
- $send_snoopy = new Snoopy; + |6 a; ?7 z& D! E* ], ?- u* S& `
- $send_snoopy->fetch($codeurl);9 \1 d$ X- A1 R' D4 l
- $result = $send_snoopy->results;
- m3 O4 _3 g* [" Z b - if ($result) {
$ V3 s& @: |, c; ^9 A1 U' ^/ @4 a) T - preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);& V* v4 F6 ] e; I/ B/ ~
- if(count($matches)>1) {
+ G" |: b' I, |# I - $this->_logincode = $matches[1];" A3 X' f5 h$ E0 \; \( D0 d
- $_SESSION['login_step'] = 0;5 p9 w# h* [- T5 P+ e6 F
- return $this->_logincode;
, ?& q; {8 q% j; Q; `1 h - }
& Y) E2 {6 h5 M. I0 \ - }( z, i7 L* E' O5 u s6 @5 h: [8 n
- return $result;
. W/ b# T# J% k* K9 X3 j - }, {/ z8 T( i7 Q9 S* h* _4 i
, e: g# A2 @2 p! H- /**5 N- i& W! d( F! k2 S$ D" b( ^
- * 通过授权码获取对应的二维码图片地址
; B5 ~- X" D$ q F+ b0 X$ F# D; } - * @param string $code
* `% y: U% s2 ]; S. P - * @return string image url
5 Z2 L3 J" T8 c. O - */" m1 E$ G9 M0 w/ K
- public function get_code_image($code=''){
+ G- d# [' b# p7 y6 u1 o& R1 c - if ($code=='') $code = $this->_logincode;% q4 ^; D8 w4 X: ?: }. ^5 m
- if (!$code) return false;+ l s6 b) \4 k2 ^4 y: ]% T# A/ o& I
- return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';, ^/ Y8 R3 M" q* Q7 {7 B; ~
- }
3 ~9 c$ h" n2 z: v* n/ ^) [ -
$ o( h' k% t& w/ F# c" z: { - /**: n( q0 [9 _% a f2 z, h
- * 设置二维码对应的授权码+ r3 O: D# W# L: s$ c% n
- * @param string $code) i- `9 v" s8 q4 [. j
- * @return class $this
% j8 L. _) ~7 v3 | }. [7 g - */% V' F. m- ?$ B1 @) l0 B; T
- public function set_login_code($code) {
7 j6 `$ p2 z8 J! x: |, | - $this->_logincode = $code;
" y2 Y n$ t C# k - return $this;) S& P1 f& ~* c" ?/ |
- }: ^" }- k/ @9 F* C, ]0 u
-
0 ]6 t- H; d- j5 N) J! |" T& ] j - /**8 l' \7 W* p& w" s
- * 二维码登陆验证1 A/ g2 C; A2 \& D9 Z6 L8 x8 z
- *
8 s2 d- C% T+ U+ g0 n" x3 b# F - * @return status:; y& \& Q( A; b: U4 \, d8 q6 q3 n/ p
- * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired# m4 [+ q/ }$ A) @; p; p
- * 201: just scaned but not confirm0 Z. ~. B. _, f4 {3 R
- * 200: confirm then you can get user info6 b( P( M' t$ [8 |- f$ ^# M
- */! P+ S' j1 D. O' I
- public function verify_code() {
3 m% ]3 t! D5 A5 {/ D) P: [ - if (!$this->_logincode) return false;* l5 A, w" @( C K" c r
- $t = time().strval(mt_rand(100,999));0 I1 X9 m5 C, \( H5 B, Y L
- 6 }! \4 s: W1 m: u, a
- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;
, Z4 s, b6 O3 N/ X' N2 I# e, L0 k - $send_snoopy = new Snoopy; : O' N" s; [! r/ [1 L- M1 v
- $send_snoopy->referer = "https://wx.qq.com/";0 d8 f9 K' ^4 D) B, ` f( X1 t
- $send_snoopy->fetch($url);
( B& I4 j% {+ M7 |- S8 A - $result = $send_snoopy->results;
, c2 }+ U/ m* W1 X - $this->log('step1:'.$result);
1 h/ e/ [9 T+ H/ ]: D - if ($result) {
2 V* M: N- A4 G n. ^ - preg_match("/window\.code=(\d+)/",$result,$matches);& d( U9 {% s/ b( h/ A" q3 L+ n
- if(count($matches)>1) {
, Q& p- k7 ]0 E6 F1 v - $status = intval($matches[1]);# m, i/ k4 b& J% y$ t% x. ^; N
- if ($status==201) $_SESSION['login_step'] = 1;
1 C* X3 r, f4 q+ U; w( N - if ($status==200) {
. @. T' j' k% }& _ - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
+ n, w, h4 ~* ] - $this->log('step2:'.print_r($matches,true));
! x, D; I# j, t7 i& n7 a - if (count($matches)>1) {0 s1 f) |% ^7 j) U/ ?
- $ticket = $matches[1];2 y2 p4 o2 X, S1 b$ ~- `; N
- $scan = $matches[2];4 [$ D7 U! {- Y% X
- $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';8 @" j( m# ]6 W/ F/ O
- $send_snoopy = new Snoopy; 2 h" I% b0 W9 b0 l/ T) I- ~- P
- $send_snoopy->referer = "https://wx.qq.com/";" H! A; Y- A+ e& s) n0 T
- $send_snoopy->fetch($loginurl);
5 d- I0 z* o e3 [+ T. A4 U - $this->log('step3:'.print_r($send_snoopy->headers,true));( G7 g: H* i7 Q6 K: ?/ s+ h
- foreach ($send_snoopy->headers as $key => $value) {
) l0 U1 D0 @% N) ~$ ^ - $value = trim($value);
& w* H! W6 G% E8 g& P, _/ g - if(strpos($value,'Set-Cookie: ') !== false){
0 n! E6 E6 u; L2 |( Y% | - $tmp = str_replace("Set-Cookie: ","",$value);5 K( b0 y& ~: i3 V4 u
- $tmp = str_replace("Path=/","",$tmp);
( l+ M: H }4 X& W- s - $tmp = str_replace("Domain=.qq.com; ","",$tmp);% [- B+ D% Z) n2 ~; e) a: K
- $cookie.=$tmp;2 x8 U, Z0 N% W% p; w
- }! j+ x+ _6 O8 M7 N
- }
# v$ H/ T/ ~* s9 l - $cookie .="Domain=.qq.com;";
: ?, Q, u# }1 Q C" Q - $this->cookie = $cookie;
1 c" u5 @- }3 a: d# j+ Y - $this->saveCookie($this->_cookiename,$this->cookie);
- u& Z( L& |7 B# }( C - }
. v& j9 o( d% n' O+ H, n2 c; U+ f! ` - }! J' ?2 v4 A4 e3 g, G/ W
- return $status;
* G: z- H7 y! l2 |. d( M+ q; C0 Z - }. }6 w. r9 [7 f! o+ s
- }. m' u2 D2 x# E* E0 ?' Y
- return false;/ c X: U' G! ?- A9 b% ~8 R
- }
& x8 ?, X# ?9 H7 Z -
% n4 r' g. U" e" `6 c* D - /**
2 v c6 x* q k+ s, b - * 获取登陆的cookie$ W" E8 d' b! _) E
- *) ]5 e( e! Q! H$ T
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
# P% y3 _7 t9 G# r/ ^* g. O - * @return string|array
; y1 _& a' R8 n8 M& ~ - */3 d( c. h4 u, P; d3 l7 L
- public function get_login_cookie($is_array = false){
3 d8 W& p% k6 d$ N" ^/ Y' t0 \# C - if (!$is_array) return $this->cookie;, X7 T6 I9 b, Z5 @( f# x) }8 `
- $c_arr = explode(';',$this->cookie);, q, S; `. }$ K" \. Q: c
- $cookie = array();
/ f, c- e* Y" n D. L - foreach($c_arr as $item) {
f4 U* `- R9 B& g8 _. x - $kitem = explode('=',trim($item));6 q9 F9 X3 d6 O o/ T# l0 v
- if (count($kitem)>1) {6 c9 B; P7 X% r: ]6 x+ Q: V! D
- $key = trim($kitem[0]);$ c s0 {2 {0 l/ J7 z$ ?/ e4 v
- $val = trim($kitem[1]);& P$ c+ q0 V! l. U- @ v1 z
- if (!empty($val)) $cookie[$key] = $val;
; Z8 `/ U7 K1 b# s% Y; j - }
1 v# `( o& W, c6 J' e - }
1 {0 M2 P$ h% ]) i5 F0 g3 d - return $cookie;
, M9 @5 C& i4 d: _8 C. W2 h$ W - }
M" X. X6 U# Q) a - & S% S" b/ _' D, y( @
- /** j) _* A, c2 d1 v3 w
- * 授权登陆后获取用户登陆信息
5 j; j! E4 S6 O1 Z) _0 D - */
2 Z, k# A0 ?/ ]. H! m; p; T - public function get_login_info(){0 }2 E; E2 R5 {% h
- if (!$this->cookie) return false; I; ?0 K+ z# W9 n, x
- $t = time().strval(mt_rand(100,999));
: k: l/ x5 G1 Y+ r/ U4 e& }: Z - $send_snoopy = new Snoopy; " s8 N9 b1 J& I( Q0 F
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;* H' R% q* ]. C+ Q. x- f; |- b
- $send_snoopy->rawheaders['Cookie']= $this->cookie;
# [: s8 k( i0 `+ { - $send_snoopy->referer = "https://wx.qq.com/";
( V3 b) |" R5 G6 ^ - $send_snoopy->submit($submit,array());/ e4 s+ R) y( W6 F+ m
- $this->log('login_info:'.$send_snoopy->results);1 u: I$ C3 d0 P( @, S% n8 y
- $result = json_decode($send_snoopy->results,true);% L$ L1 s L* U4 B7 x# [; h
- if ($result['BaseResponse']['Ret']<0) return false;
, x* N, E1 \' K3 i k - $this->_login_user = $result['User'];
' l" t: w# t) l5 u: t D) i, @0 s - return $result;
& G% E: q. U9 g+ c4 ? - }
/ M. T# G6 R7 P! N -
2 K/ j! Q( n9 O7 W9 l' _2 h - /**
" x! K4 a# X1 F, | - * 获取头像( j) n1 @1 g( L& z2 n! g8 G
- * @param string $url 传入从用户信息接口获取到的头像地址/ p: [, m0 D; x3 ^
- */
) @% g* ~+ A+ d+ P- [! o - public function get_avatar($url) {
! j4 m' J6 m, q! h - if (!$this->cookie) return false;3 D5 o c8 r1 x7 W
- if (strpos($url, 'http')===false) {
2 G( n( v( P! ~! R% R - $url = 'http://wx.qq.com'.$url;
9 ]" Q/ L6 L S# V- S! s) _3 ` - }0 w* }& `8 P& U7 I4 N) l4 R
- $send_snoopy = new Snoopy; % u1 P8 A) x( i r! i. O! C
- $send_snoopy->rawheaders['Cookie']= $this->cookie;7 d2 B4 H$ F# f; i
- $send_snoopy->referer = "https://wx.qq.com/";( A' y2 C! T0 e) O# R3 l) Z7 ~
- $send_snoopy->fetch($url);& g" ] V; e; @- f; {
- $result = $send_snoopy->results;
3 g: t# A1 l) h - if ($result) ; Q" E% U5 G) d
- return $result;
! g. p0 D5 X% A7 J; t& M, f - else
1 f, n6 M, q8 ], M - return false;
% M& \5 g6 T6 ~! v3 C8 P - }- {: U. n0 l2 U8 f3 b( d) _
- , \7 x% T5 o7 ^1 q% J* I7 m
- /**2 _9 _; i+ e" x6 Y8 a8 H( E: D) J
- * 登出当前登陆用户
0 F6 r2 k6 j- `; L! U! t - */
: F4 t4 t8 I0 c3 L8 O - public function logout(){
' H3 j: w9 B; M) V7 u- u - if (!$this->cookie) return false;% I, {, O6 z, Q
- preg_match("/wxuin=(\w+);/",$this->cookie,$matches);
H; I9 R$ n) q k7 Y% v# s - if (count($matches)>1) $uid = $matches[1];# d/ @4 \: H. ]( G$ z. M; W
- preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
$ B( a6 e+ z1 a# {- K5 x - if (count($matches)>1) $sid = $matches[1];& P& P6 e0 `- Z8 b$ Q" g+ D: B
- $this->log('logout: uid='.$uid.';sid='.$sid);" ]! g; |5 F- M2 h8 b
- $send_snoopy = new Snoopy; ) m/ B/ x, y4 I7 {8 i; d
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
/ o2 \6 M' [9 O+ @! Q& F9 | - $send_snoopy->rawheaders['Cookie']= $this->cookie;% x) l5 j% E- d+ }% d5 M4 t
- $send_snoopy->referer = "https://wx.qq.com/";
! x2 q4 k" Y% O, R$ K% h T - $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
/ `" z; l, a7 k+ g$ Y - $this->deleteCookie($this->_cookiename);% }& g0 w" h5 D5 E/ f
- return true;7 ?4 Q' G" W. e
- }3 r& S, n+ P8 W3 [
- }
复制代码
! w* ?- w/ w K; d |