用户通过扫描网页提供的二维码实现登陆信息获取 0 m+ n' r. _$ ]$ F2 F4 v# e# b
- <?php& q' z" G7 Y, {5 q- w, l N# {9 v
- /**' |% x4 z7 `% U& f1 s- F
- * 微信公众平台PHP-SDK
2 t; n( V* x) _+ |4 |* W; { - * Wechatauth为非官方微信登陆API1 [4 Z5 H8 q2 G3 N( j* ]
- * 用户通过扫描网页提供的二维码实现登陆信息获取
8 U0 p. Z" Y- r. ^1 g7 Y - * 主要实现如下功能:$ j G9 p$ ^5 D4 T! c
- * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码) I5 w6 f% O! q7 U
- * get_code_image($code='') 将上面获取的授权码转换为图片二维码, e% @: N+ {2 S+ O# N/ }
- * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.% q1 T+ }7 K7 \
- * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息/ E% T! T! ?7 l4 a5 \- u
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
7 w' X, b0 M3 A% L$ }+ ]! c - * get_avatar($url) 获取用户头像图片数据' q( R+ o# `* C5 Q/ \8 ^/ d
- * @author dodge <dodgepudding@gmail.com>
3 X% v) q3 V# X - * @link https://github.com/dodgepudding/wechat-php-sdk
- P- N E# R' i" t - * @version 1.1% G4 H* W3 U# f& [ Q
- * + z/ C& K; A5 Z
- */5 ^3 r, k& {' ]4 |+ @ X
- include "snoopy.class.php";1 z7 U! p. P( |1 E4 Y
- class Wechatauth
7 I9 q$ y, `& ]8 ~0 W. |+ h- H+ x - {* y9 _+ u& @1 h, `: l: ?6 {" h' N
- private $cookie;3 S# t; R6 O. r0 `# z- ^1 I( R
- private $_cookiename;, c; \6 ?" O9 y$ q
- private $_cookieexpired = 3600;* _. M4 W0 I2 ^+ ^, m- ~
- private $_account = 'test';& y! t/ g7 c& h, J; y
- private $_datapath = './data/cookie_';; b) s$ O( C. \- ]
- private $debug;
8 |" V1 R; n9 Z - private $_logcallback;
* ~8 x! T* C9 l& A$ `0 v' z - public $login_user; //当前登陆用户, 调用get_login_info后获取
( _! d7 j: s) `0 I0 J -
9 [- e* B1 X5 v - public function __construct($options)* G" K% X. c, t, H( I
- {
6 ?4 Y. O, r9 c( U6 K8 B - $this->_account = isset($options['account'])?$options['account']:'';& I4 b% ], S2 y$ _' g1 x- q6 ^# Y4 a
- $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;. Z. \) r. t( H2 ]( |1 Q4 G% A0 ]* p
- $this->debug = isset($options['debug'])?$options['debug']:false;/ P: Y1 i4 v4 ?4 E7 F3 ?" z
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
" U& T2 P) a) q - $this->_cookiename = $this->_datapath.$this->_account;
, X* v. b1 c8 q% d1 A - $this->getCookie($this->_cookiename);: G# ?: j8 e7 g3 J, K1 |0 V8 u5 }7 U
- }
" B f) _1 h2 `, T# o' `5 A: { - /**
2 c, \$ v! b# o/ O: n* P S5 z - * 把cookie写入缓存
* k$ M: V3 S1 W9 q/ Y# V* G+ {& }/ | - * @param string $filename 缓存文件名
( |% N; |* i. G" r' ? - * @param string $content 文件内容+ p7 O0 P, S$ {! }8 q
- * @return bool: b% X% o p( I! T% U
- */! a8 s" B" @, h. y; i
- public function saveCookie($filename,$content){
1 N! E7 O' R% u& n& V. [" K) o - return file_put_contents($filename,$content);3 u( Y( {9 V$ v) K* p
- }% S. P, N! R# b* `" [* J
- 9 P, \# _1 ~( I! [! B, G. x& z
- /**% L! T# C$ Z4 `! c
- * 读取cookie缓存内容( }2 d1 O2 u& }: L0 c
- * @param string $filename 缓存文件名
) }( J# H9 }. F! _1 g - * @return string cookie3 J" ]: i# B7 N9 [8 s' X" V% f
- */
9 q2 T# R% X4 _) M. w3 R - public function getCookie($filename){
! P5 O \* v' Z) h$ p1 Y - if (file_exists($filename)) {
( Q! \; v+ P9 z& T/ C - $mtime = filemtime($filename);
9 J& |! t) f$ E$ j5 C! _ - if ($mtime<time()-$this->_cookieexpired) return false;* C1 d" z0 U! H& Y) G
- $data = file_get_contents($filename);2 T/ r) `- R7 e: D( U
- if ($data) $this->cookie = $data;5 E! e( N3 K2 H% ^8 D+ {
- } , M& O; {# Z2 Z3 d2 W' L% f, I1 x
- return $this->cookie;
8 c% f6 g: x$ ~7 w2 P; [ - }3 k/ L) }9 H- F$ t h/ }
- 8 W6 M0 I+ {' S) ?' O8 K9 m4 ~
- /*/ C9 g$ }: Y' H4 `* @
- * 删除cookie
" j! |8 D2 L" W! ~( N/ i+ ^+ `% o - */
. W) y f2 E8 |1 I - public function deleteCookie($filename) {
9 p% B& j1 {, }7 I/ ` - $this->cookie = '';
& T3 n$ R X- g- e& U, s4 d - @unlink($filename);( P! r. ?9 B) y& W" ^
- return true;; k. T; T. d! ?" V- B4 P3 d4 m$ x) H
- }
9 s: W& v( U- l4 p, T* Z -
$ a+ U4 e* l2 V - private function log($log){
/ V: b/ v% q2 q - if ($this->debug && function_exists($this->_logcallback)) {+ j" }7 g/ U& b+ Q
- if (is_array($log)) $log = print_r($log,true);6 p- [2 b. s" L3 e1 P* p J$ O
- return call_user_func($this->_logcallback,$log);
/ s4 w L- `; Y9 z& m8 c: O& p9 w+ b6 { - }& G3 ~2 q' A& I) ?
- }
u/ a9 K9 C& q9 Z" [; k/ H -
# \* s, Y4 n0 ?& }! N" s/ Z& P) d5 H - /**
6 v) ~/ L: S( t5 H4 e8 T. w" H - * 获取登陆二维码对应的授权码) N3 @9 ~3 N4 X
- */
5 ^7 q2 s* d* [5 q* { - public function get_login_code(){
$ b: m4 s7 u' U7 w: P' ] - if ($this->_logincode) return $this->_logincode;
7 W' ` A. x' _/ r7 `& w& ~ - $t = time().strval(mt_rand(100,999));
, O# ^6 Y3 l% T5 L5 x - $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+ p, l, f# Z: e - $send_snoopy = new Snoopy; ' Y: R- E- [. a" H; x" X
- $send_snoopy->fetch($codeurl);9 Y9 c7 W: `! T+ f6 E8 U
- $result = $send_snoopy->results;
7 u+ D4 V8 V- {$ X - if ($result) {
( w/ a. h6 c6 |6 O - preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
, |& p) Q6 a a' F - if(count($matches)>1) {6 A7 H' ^3 x; _' O: K, N
- $this->_logincode = $matches[1];7 q0 `+ Z6 |( i7 N' s3 J6 ~! Q
- $_SESSION['login_step'] = 0;: B: k& @. Z. T2 P3 J
- return $this->_logincode;" t2 C+ D0 ~7 o
- }& B& C4 Z2 Q3 H+ O0 D
- }- f: R2 ]4 D& m) e6 _- X7 V. C0 O
- return $result;
" ^9 Q: ?4 B6 _( ^- a/ U% y - }0 b4 U+ s2 p- _# ~4 R" o
- & ` E9 S/ b4 b' @2 V y* n7 ~
- /**
: T |5 B* @ b - * 通过授权码获取对应的二维码图片地址) B' A& H; N* J4 y& [. v7 g
- * @param string $code0 J0 S7 `2 u5 u" \1 H
- * @return string image url
) U( O/ U7 T, d) o3 Q j4 t) } - */
' c8 c* b2 u* F; ?0 c - public function get_code_image($code=''){
* D0 ^! Q5 z7 { r1 [+ _ - if ($code=='') $code = $this->_logincode;
0 c& o! ]0 j& ~0 k* R8 k8 B) n - if (!$code) return false;
( y6 Z C. M* K( w/ X9 @ - return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';) N2 D9 W" \* m7 D; d* S+ g
- }
- L2 x- A ~/ L% p - . c j, L. y. N& o
- /**
5 Z8 w5 C/ X1 N- V1 Z - * 设置二维码对应的授权码, J% T! S* I+ A3 g. _$ T) Y
- * @param string $code4 _3 A' p2 P2 B- E
- * @return class $this1 @- ~; L% N1 X
- */! w; \7 q6 z: x$ L" ^- Y9 \
- public function set_login_code($code) {
7 W; g" S3 q( w - $this->_logincode = $code;
; Q) @- \/ D# B) n+ r5 ] - return $this;& R4 B w& _& [. U2 _2 F$ X; m
- }
' T0 I( G! E2 l. M9 k -
* O7 k. R& S/ N - /**# X1 ^: p; P' q2 h' r
- * 二维码登陆验证0 a2 b# G* W- [! _; T/ S
- *$ M9 A3 m+ Q) [, d) I3 U
- * @return status:8 s U# _( L3 d. m3 n
- * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired( \) [0 w4 j" w9 \
- * 201: just scaned but not confirm
9 C, T" S) e: u0 x; k3 } - * 200: confirm then you can get user info; Z, i& _0 m/ {- Z. e% h. f6 o4 ]
- */
% c- M* W+ k% u5 W" P" x1 X - public function verify_code() {1 Y# I; `! t! l7 ?" _, h" {, ?
- if (!$this->_logincode) return false;
' y, g# Y) A5 F, t! q( H. W; M* a - $t = time().strval(mt_rand(100,999));' t- v U: Q3 M4 P, L
- 6 d3 I$ w! A s0 g2 O2 w! q
- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;
: K/ F8 ^0 |) H0 I# \. B) E - $send_snoopy = new Snoopy; " ^7 z" g- d7 u+ {8 ?! y. v& C4 |2 R) a
- $send_snoopy->referer = "https://wx.qq.com/";: _9 a9 h% W4 u; X# k/ G
- $send_snoopy->fetch($url);6 m& R: Q% y9 m2 c
- $result = $send_snoopy->results;
@4 B! J& P p$ x - $this->log('step1:'.$result);
/ X( x5 v, b! d |4 w- s8 x6 T4 m - if ($result) {! C0 j0 j5 ~* _' g, s' e1 I8 C
- preg_match("/window\.code=(\d+)/",$result,$matches);$ }& U3 ?3 Q! [7 i5 E. }# I
- if(count($matches)>1) {
0 U0 c0 p" d. n+ h3 O - $status = intval($matches[1]);2 f2 G) i) l( }
- if ($status==201) $_SESSION['login_step'] = 1;
: k1 Z1 z3 U7 A2 } - if ($status==200) {
3 {- {) L1 W- U9 a% Q4 q$ w - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);9 p' R/ E; V2 \2 p* K- X
- $this->log('step2:'.print_r($matches,true));0 _, g% u5 \# L1 Y6 ?8 u
- if (count($matches)>1) {" }' z1 y/ J( N& ^
- $ticket = $matches[1];& O9 W2 l* m' | X. I' J: v" J& ^
- $scan = $matches[2];0 T) Y& [* P& X6 o" Z0 }
- $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';
9 D( n ?+ I. |% N P - $send_snoopy = new Snoopy;
8 N7 R8 i D; ?1 V: q6 w0 P - $send_snoopy->referer = "https://wx.qq.com/";5 b. [; a ~: S8 {/ K5 K q7 x5 E0 G% z+ v
- $send_snoopy->fetch($loginurl);
3 O: m4 H: u2 r7 A. Z* l - $this->log('step3:'.print_r($send_snoopy->headers,true));
- }% L2 x8 t$ Z2 h) W( u( I - foreach ($send_snoopy->headers as $key => $value) {( m. k( e6 X) B, A6 `
- $value = trim($value);
, M4 B& g% [8 o9 K2 S. V ?$ G! p - if(strpos($value,'Set-Cookie: ') !== false){
9 o4 l4 L; R4 f) p: W - $tmp = str_replace("Set-Cookie: ","",$value);* o' n2 r* y+ |1 s! R9 W6 p
- $tmp = str_replace("Path=/","",$tmp);
+ U( v& ~9 p' C M @ - $tmp = str_replace("Domain=.qq.com; ","",$tmp);
1 ]3 K0 W. V/ w, \2 N- m - $cookie.=$tmp;: i+ ^+ d, X& k0 X2 U9 `
- }2 N+ f1 [) [. ], q( ~, \
- }
; a l! J1 v8 `4 F' a - $cookie .="Domain=.qq.com;";8 }$ o0 m4 r$ ~# ~) R9 L
- $this->cookie = $cookie;% K% G: y- w6 c ~0 y
- $this->saveCookie($this->_cookiename,$this->cookie);' `1 a { O4 l* ?/ t3 j
- }
2 L0 v9 W: M# L - }
: u* I# y/ ~8 b& r# b4 B8 A - return $status;
5 v9 b% K- ~4 S! l' k - }
4 l! s$ d" G: v+ p% t( S - }' d3 @5 D4 J. I2 W; s: h
- return false;+ S0 N* \ ]3 s! b; ~6 l5 |
- }
- E. C0 C& _% G. Q - 8 a4 V {6 K9 p8 a
- /**/ F) @( _. v; A; e( ~4 M3 p
- * 获取登陆的cookie% n: [" t0 J( ^$ r
- *3 ?8 S# a9 V" l3 U
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
4 f5 b2 u4 ?7 g! s: k: X - * @return string|array4 y: V7 d' T8 M/ P
- */8 [& j2 ]9 M8 C5 l. r* O+ A" w
- public function get_login_cookie($is_array = false){
# \8 l; U& [) @9 M" |. x9 ? - if (!$is_array) return $this->cookie;
/ `+ U+ m6 F3 g+ ~7 Z. s( D - $c_arr = explode(';',$this->cookie);
: B( P* ]" s! g1 X - $cookie = array();
a5 J. L1 ~" W7 f2 N& k - foreach($c_arr as $item) {
1 [, ~' M/ n% [: r, d% l5 B/ } - $kitem = explode('=',trim($item));
. S5 }2 \$ ~! V$ q* t5 D5 g8 i - if (count($kitem)>1) {& f0 T. V+ { H8 `% \3 N6 L' e
- $key = trim($kitem[0]);
4 B# C2 U( d/ } - $val = trim($kitem[1]);
( }$ b+ r6 Q4 T1 V - if (!empty($val)) $cookie[$key] = $val;
1 U) _: f% ^' t6 Q; j/ @ - }
5 {- \( G8 e3 q8 E* J5 c+ j# k - }
2 `5 W4 d4 Q& ?' z - return $cookie;
$ T; A; d F2 |, N0 D! y; k - }8 b2 O/ ~8 G( S% z. }$ n
- $ }) |9 F- s# }% i9 H
- /**
, |* i& }5 ~& m- C- W0 c, w - * 授权登陆后获取用户登陆信息
" J e% k: K! x) B$ z+ y - */+ C: k; @7 x+ w) i
- public function get_login_info(){; U; P' z& C; p) ]; c5 Q
- if (!$this->cookie) return false;
: w3 q0 L- M) S - $t = time().strval(mt_rand(100,999));' L: G! U3 W( r u
- $send_snoopy = new Snoopy; - C7 X$ I# s* V* T
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
, h3 H- V) y; G' C - $send_snoopy->rawheaders['Cookie']= $this->cookie;) g# Z' T" |# a/ X' L& C
- $send_snoopy->referer = "https://wx.qq.com/";
* l' B9 F/ s9 P+ m' H" h - $send_snoopy->submit($submit,array());+ u( R- H7 M+ a( U3 ?& c! A2 O
- $this->log('login_info:'.$send_snoopy->results);# y0 j, Y' k- C# q$ Q
- $result = json_decode($send_snoopy->results,true);
9 U0 Z. N; r' k# j - if ($result['BaseResponse']['Ret']<0) return false;
7 M% o, ?: U: f: l! f* @7 B - $this->_login_user = $result['User'];
+ J+ j% y) {( q; N5 q& F - return $result;
# T2 N$ J0 b$ O! X2 B) a - }
/ a( i+ k8 _; O; y - # Y7 B! T% D+ X
- /**
) b- ]% W$ |. a6 x - * 获取头像
3 }. q [' u D) U - * @param string $url 传入从用户信息接口获取到的头像地址
7 o8 z4 H3 O- S! Q. T! S) ~" m: g, Z b - */
" {, W/ V# q* M4 F - public function get_avatar($url) {
. S/ W5 M! j/ r7 \, w0 P3 j! { - if (!$this->cookie) return false;5 P2 ]) o3 Y+ R" H4 j+ i
- if (strpos($url, 'http')===false) {
; P3 _3 U! G* J3 K, L/ Y - $url = 'http://wx.qq.com'.$url;6 l7 S- v. V& [6 t9 C" ~% d
- }+ k' V/ c5 R; b' s
- $send_snoopy = new Snoopy;
+ j: D$ C4 ^. R+ |( r% n& V - $send_snoopy->rawheaders['Cookie']= $this->cookie;
( w$ v5 r' i* ^% b4 R - $send_snoopy->referer = "https://wx.qq.com/";- z* l+ |+ U. N& p
- $send_snoopy->fetch($url);
5 H& x) w, y" d3 ]' e - $result = $send_snoopy->results;
% R) m5 ?: z9 ?7 ]6 _2 k+ { - if ($result)
2 A; n! @7 L7 L# K5 H: {1 V) Z - return $result;
% f! U' }) t. l# N7 h* i* G4 S - else
! r8 V3 [# g0 @4 h - return false;% o9 a8 m" Y' Z+ r0 f. p: P
- }: e0 m Q& G) N1 H6 g3 J
- , c( G u; z1 b5 t8 b7 Y! ?" J
- /**
( v3 V( u, d1 B - * 登出当前登陆用户' P7 v4 [- ?4 B, n0 w% L c3 _! ^6 |8 q
- */
& J' w, K; s& k8 N7 [ - public function logout(){+ n; d! P% Z+ Z, _1 m* Y- M
- if (!$this->cookie) return false;* @! }" L: c: ? B; h+ j4 F! H; t
- preg_match("/wxuin=(\w+);/",$this->cookie,$matches);" o6 ?/ ^5 y# D0 S; t& i" ~
- if (count($matches)>1) $uid = $matches[1];2 A: i; A3 ?9 p
- preg_match("/wxsid=(\w+);/",$this->cookie,$matches);! c1 f( J. ]2 `8 c* E
- if (count($matches)>1) $sid = $matches[1];
& V! Q7 L: \% [1 d4 _ - $this->log('logout: uid='.$uid.';sid='.$sid);9 T! r0 d+ f# N6 _
- $send_snoopy = new Snoopy;
5 U# I9 p- R3 z8 k% `8 p - $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1'; V, U$ a8 A6 F# e
- $send_snoopy->rawheaders['Cookie']= $this->cookie;
8 v5 ]6 \9 N: e8 x/ }9 a3 L - $send_snoopy->referer = "https://wx.qq.com/";& e4 z4 q& m4 S/ M) E- C
- $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
& F7 h% O4 h2 x* n: Z1 L3 x" U" H1 ] - $this->deleteCookie($this->_cookiename);
5 M5 h( o( ?/ \/ o - return true;4 [) J+ U* Y: x+ ^
- }1 ]" T9 |/ n/ W$ Y2 Y; y- g
- }
复制代码 % X2 Y2 S9 ]! `" x0 ?$ |2 s7 b5 X
|