用户通过扫描网页提供的二维码实现登陆信息获取 ; [; \' Y! q0 z) E. s
- <?php
/ B5 H9 s3 Q* \7 \+ D+ Z0 s: T - /**
2 v7 J+ G6 u& }/ x - * 微信公众平台PHP-SDK6 K* J/ h6 z: ~4 W. j# V: ^0 I
- * Wechatauth为非官方微信登陆API( S9 c+ D0 P' ], U
- * 用户通过扫描网页提供的二维码实现登陆信息获取8 H, P& s$ g6 y
- * 主要实现如下功能:0 Z9 I" `4 E& t h
- * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
% `& g/ b. z# J3 I# ]# H" w. C - * get_code_image($code='') 将上面获取的授权码转换为图片二维码
7 i- D- D" B2 J2 \ - * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.# v5 K+ B7 D6 w
- * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息
3 c3 x. m, s/ J2 M1 z- w - * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息
; o. r( t$ M+ q$ z/ M" Y - * get_avatar($url) 获取用户头像图片数据
6 W7 g3 h, T+ p3 e - * @author dodge <dodgepudding@gmail.com>" _4 W3 P" }0 M* t: z! S% k0 k
- * @link https://github.com/dodgepudding/wechat-php-sdk
9 g, j P, O+ X1 |) l2 N - * @version 1.1
! j+ }" ?+ |, j' q2 }# R+ e; i - *
/ I: d; X. X( Z5 a7 h - */( Y2 Q" x3 r0 w/ V, @2 m+ U
- include "snoopy.class.php";
4 X0 }0 L4 m Q" F* [4 X. Q- i - class Wechatauth
; b, }+ Z4 S: g! V/ P - {) d2 r) R/ R$ O9 L" k6 {
- private $cookie; P3 D3 J: r& M4 g
- private $_cookiename; ~% e- a: {2 b- {2 H1 h' a
- private $_cookieexpired = 3600;! S8 _( C3 U: S
- private $_account = 'test';( Z- `: A# `4 A1 o L7 k
- private $_datapath = './data/cookie_';
# \8 B6 s& \ C2 M; y7 O - private $debug;
3 B: k5 s Q$ K, c - private $_logcallback;
+ w5 j! L# l; Y3 W! ?- M I - public $login_user; //当前登陆用户, 调用get_login_info后获取
( Y+ ?- `; v( T! n1 F) } -
7 B, F7 {. U4 d - public function __construct($options)
2 Y. n k" a0 X% } Z - {" x3 G M3 W7 ^# x' {: }. H$ b
- $this->_account = isset($options['account'])?$options['account']:'';; m$ @- M; \3 w4 h8 [
- $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
8 ^% W1 d+ L8 T' y! M - $this->debug = isset($options['debug'])?$options['debug']:false;& _8 v% E2 i7 h% E& j( ?! O
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
\0 W1 g% i, @# i - $this->_cookiename = $this->_datapath.$this->_account;
1 u+ [; w- a- B) b { - $this->getCookie($this->_cookiename);
; D* Y9 @2 q3 w( D8 O/ _ - }
. k. z$ f& l9 D& K% u. m - /**4 C/ p* h# B8 ]+ y" A
- * 把cookie写入缓存$ \: v" O; l2 F2 P/ Z6 f
- * @param string $filename 缓存文件名
. O! a3 L: {9 q! W/ ~8 Z6 ? - * @param string $content 文件内容
- Z" B0 X) I: x! q* W2 q. O9 J - * @return bool( ~5 m1 T/ M0 X7 ^8 f
- */& I8 k$ F2 J+ O, b' k+ Y2 a
- public function saveCookie($filename,$content){* [! ^6 T9 ^4 n7 A
- return file_put_contents($filename,$content);) D$ X6 `( P5 ?6 i1 y( |
- }
K$ B9 q/ V' d. [2 ] - % L% z1 Z' `' k& V
- /**
6 V, N* ^* R `' A - * 读取cookie缓存内容; ^' P$ k4 p4 u) L* N9 ~" L
- * @param string $filename 缓存文件名
# D/ ~" h# O7 |' B - * @return string cookie
: B# _+ \- B2 @+ L# m/ r - */
+ ]$ ]/ z6 L+ m: Y. O - public function getCookie($filename){
$ h' b9 J5 G, {* e7 J, ?) D, g$ J v - if (file_exists($filename)) {) w& P- [% |: o2 d2 L0 Z. X
- $mtime = filemtime($filename);- r# @) f+ Z( M9 n
- if ($mtime<time()-$this->_cookieexpired) return false;% Z; K) }3 h2 @% y/ A3 k
- $data = file_get_contents($filename);7 A Z& W/ f7 O; U9 z
- if ($data) $this->cookie = $data;
+ C( m' b; W! p* K - } ^" U0 J3 l& D
- return $this->cookie;
; U7 [) V4 A+ E - }
% i9 r. t: [7 Y# w/ M -
, u) Z" P0 ^% z5 R3 [ - /*
1 r4 `+ q. Q9 B$ H5 h! x* H6 Q - * 删除cookie
4 m- F2 d6 D7 G9 Z# c3 v - */
7 C+ L7 \1 U. D+ D/ j) B0 G - public function deleteCookie($filename) {
0 f7 t7 z& B% L$ }9 Y - $this->cookie = '';
7 ?3 S# z4 H2 Z# T: E4 k) ] - @unlink($filename);
: k: V% C) ^% w, B c! \$ { - return true;
+ C# f& y* n$ @( y, t - }
! z, D8 s' U) M* {$ i -
& `! M% o# l3 P) d, d% t - private function log($log){
* x# J& h' F3 p - if ($this->debug && function_exists($this->_logcallback)) {. T) g, n9 A B
- if (is_array($log)) $log = print_r($log,true);- p1 L! G( g2 E6 K. e1 c E
- return call_user_func($this->_logcallback,$log);
1 G% b0 G% k- k5 W- l - }$ T) K) D. K3 S, K" ?. b I
- }
7 x* `; g' U# K& m: m5 |! D! n7 N - 8 u7 S% @; r- L
- /**; S. b. @$ l+ X) o9 x+ I# J
- * 获取登陆二维码对应的授权码% d: g& l ?, n) O( h/ J
- */4 f) b* [0 F+ m. S) L
- public function get_login_code(){
) Z/ j8 ^2 w {& ? T - if ($this->_logincode) return $this->_logincode; {/ R$ m1 F6 j5 {5 ~$ ]# k" b7 v7 j
- $t = time().strval(mt_rand(100,999));
1 @9 Q6 A& j/ Z& T# d - $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;
1 B* I, c; S0 b g) U% ^0 X - $send_snoopy = new Snoopy;
: Y7 K, O! g* j! N - $send_snoopy->fetch($codeurl);- c2 j* T& ~1 z: W) t+ v: c
- $result = $send_snoopy->results;
( z2 l( V* D7 S: ~- c - if ($result) {
6 j% L Q# U x0 W; `+ a - preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
' [. @' a, P* Y5 n1 l; ?) u - if(count($matches)>1) {
; Q! j7 A, h% ` F: V - $this->_logincode = $matches[1];3 w5 y! |9 v9 E4 j7 P* L
- $_SESSION['login_step'] = 0;# J0 x; q8 H4 X
- return $this->_logincode;9 X% `( b# F- O9 M" w, \1 g
- }% W$ |! p, ^* x P9 s
- }
2 R* e6 m) W7 s" P7 ~ - return $result;- u, ?) H2 g: k4 j. E
- }
. T. G" ~1 J- Y. Q8 S# B2 I! S' P - # K% A" d* k6 y! V7 Q* l( ~
- /*** ~2 m7 u/ q2 _
- * 通过授权码获取对应的二维码图片地址/ B4 M+ e6 }* R6 N
- * @param string $code
- V6 r! D1 k* F- }- z: W& w4 v - * @return string image url7 k9 i9 c& A! Z# @
- */
6 V8 A( e0 l2 Q - public function get_code_image($code=''){
& T# p, ]4 S; ]8 ]# r3 A1 a* s - if ($code=='') $code = $this->_logincode;, h7 {0 N' r, W. U
- if (!$code) return false;. J; b8 D' V3 C" d. G* S
- return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';( `$ ?4 S% c+ c; Q" `( K
- }
# W( B' Y1 s% K: f" j -
( I: e, J' \$ l - /**& g5 L* i) F% H( M- z1 d) L
- * 设置二维码对应的授权码
2 E( B2 \: X2 h3 N( M/ T - * @param string $code, S' {! L0 x: ` G; V1 Y) ^8 H
- * @return class $this
9 X( Z" r$ R8 o& x/ m. O6 | - */
% w! j) h1 g- Z - public function set_login_code($code) {! {1 y/ r& v2 i. q
- $this->_logincode = $code;
/ m2 s5 F' j2 V8 M; E9 ~ - return $this;. g* p Y0 F/ ^5 X
- }
/ V6 x8 l1 T( g! C& ] - . F/ }$ k: ~" u
- /**9 Y8 [0 a+ O4 X6 f9 j
- * 二维码登陆验证
0 h+ S# w- m2 Q% d7 r - *$ x6 ^9 o$ T% S! j/ z( Z
- * @return status:( H& o+ ~2 f: G
- * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired# _( [: v" P/ p( U) F
- * 201: just scaned but not confirm8 q! a9 j; r% T% K) ]: n) Y2 Y
- * 200: confirm then you can get user info5 _: |( Z% a# `+ S1 h
- */4 T* s2 ?# u5 X( \6 S) m$ D7 W8 G
- public function verify_code() {
( o8 K. q' W' Q - if (!$this->_logincode) return false;
9 @ P& ?( F( @* t, s v - $t = time().strval(mt_rand(100,999));
' ]: L ] ^4 T% \) k- o - & G y: a7 M, A7 N2 M9 Y* ]
- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;+ C, z. z; \& `% _) d% |) v) V# i# m
- $send_snoopy = new Snoopy;
$ h! |* y+ |* h+ ] z& F$ J9 w2 v - $send_snoopy->referer = "https://wx.qq.com/";8 j/ [( S% z4 ~2 t1 ~9 u E
- $send_snoopy->fetch($url);1 D% W- C; O( e4 b/ C; N
- $result = $send_snoopy->results;/ h+ p7 y, X) |8 Q; O, M
- $this->log('step1:'.$result);! ]! S8 x$ R# G/ q+ ^% N, _
- if ($result) {- o v9 } t& ~ D3 ^8 G$ f
- preg_match("/window\.code=(\d+)/",$result,$matches);3 o! o7 i) c4 L k# e
- if(count($matches)>1) {
D! f7 r; ^+ ^4 P) }- M - $status = intval($matches[1]);
- X; @$ o+ H, z% S5 h - if ($status==201) $_SESSION['login_step'] = 1;$ E- c0 Z6 C; E6 \. M; B
- if ($status==200) {( m6 [( ~7 W- Z* U2 _# ?# E* a; m
- preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
+ B( o: R) p$ t! f) e - $this->log('step2:'.print_r($matches,true));
* {6 m N1 K* q/ U1 T/ I - if (count($matches)>1) {
8 W3 R" l9 `% c& d+ U1 n1 Y8 b - $ticket = $matches[1];
4 |8 Q& g4 n8 T: m - $scan = $matches[2];$ t% \+ f Z: z' R) p9 d. Q
- $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';9 g" {: X8 l' X8 l
- $send_snoopy = new Snoopy; : e7 P- j4 g- B9 [
- $send_snoopy->referer = "https://wx.qq.com/";. Q" s% z5 b$ a, {3 E8 Z' l
- $send_snoopy->fetch($loginurl);' n7 d5 H/ H3 z
- $this->log('step3:'.print_r($send_snoopy->headers,true));; h3 v1 d9 I- p
- foreach ($send_snoopy->headers as $key => $value) {
; |3 w: W0 Q4 ]' `/ m - $value = trim($value);! f" t6 `, c1 D* g
- if(strpos($value,'Set-Cookie: ') !== false){' {, F6 ^; j# c& X: |
- $tmp = str_replace("Set-Cookie: ","",$value);5 A3 a" o- W$ D1 C
- $tmp = str_replace("Path=/","",$tmp);
+ @) q* a8 @/ m. J: P( K: \ - $tmp = str_replace("Domain=.qq.com; ","",$tmp);8 R# d& f1 @( g3 ~1 G I
- $cookie.=$tmp;$ g/ g/ G( v$ Q0 }* N+ o6 ]. ?
- }: Z$ n! p! W: S8 K U* k g; t* Z
- }1 q# |6 I0 P3 T0 H( z# B m
- $cookie .="Domain=.qq.com;";
9 s2 a, Y& T2 q - $this->cookie = $cookie;
# R0 c8 y" g$ e5 o S - $this->saveCookie($this->_cookiename,$this->cookie);5 \5 B! |7 _3 Z% n; t
- }
" y! s5 V/ z; M. ?' b$ y1 k - }1 O$ U! O- w. `8 g$ O0 k8 \
- return $status;* f6 }( o! c& A: K0 R# z' ?
- }: R; C5 e) p, n; a7 v1 q1 z
- } t% Y* i5 `) {/ `$ G
- return false;( y3 ^" v, U, _$ J
- }# r# t1 C' P, ~4 ]
- % v# s5 w4 t3 U- a/ P9 a: Z4 y, N
- /**
, j3 J. Y+ W. a9 g) @0 l j - * 获取登陆的cookie( \" x- D2 ^+ U. {! P3 d
- *& _, M4 V5 q1 o; G& u& a
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串* [ p. @: \8 @" _0 n, m: j
- * @return string|array) [+ q6 p4 w6 n. t7 f( f
- */4 @9 p2 c% n2 F% r A& }2 O
- public function get_login_cookie($is_array = false){
: p7 J5 Z+ C' M! H% k" E# T - if (!$is_array) return $this->cookie;
4 J( A R$ b# e5 x - $c_arr = explode(';',$this->cookie);: Y2 q" T1 s: W3 j/ J3 k& a% \
- $cookie = array();- S6 E! S" r- \) A
- foreach($c_arr as $item) {1 J! P* C2 D- _6 ~# z! r
- $kitem = explode('=',trim($item));
! h, {- V5 r6 w6 o- M! N2 @ - if (count($kitem)>1) {4 A( S" h- P: F% `9 L; L, S$ C
- $key = trim($kitem[0]);' C/ H9 [& B) z) U& I
- $val = trim($kitem[1]);
9 ~ q( c. G! Q0 `$ Z - if (!empty($val)) $cookie[$key] = $val;
! W% G2 z; S3 N - }
3 c U; g( g' u) z$ O* V& B( @: n - } I8 J5 M2 _, ?* x
- return $cookie;
* _1 i( `! u$ p - }" a3 O( Z9 {0 g! j
- ) F5 N4 n8 D6 k& i2 N
- /**
3 y. s% ]/ _% \5 u, i4 `0 @$ N0 X - * 授权登陆后获取用户登陆信息5 v4 d$ w7 A) Z$ W3 M! x
- */8 b. z% I; z# |" X* M
- public function get_login_info(){# l1 u/ t; X( K" J& a4 ?
- if (!$this->cookie) return false;( u: w) U5 Y: o4 W
- $t = time().strval(mt_rand(100,999));
# L( H. a; N! ]; v2 n, B) z - $send_snoopy = new Snoopy; + ]1 W6 n% X. D0 u: {- {
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
* ~7 r. v! }# w, ~/ }% B7 E0 O - $send_snoopy->rawheaders['Cookie']= $this->cookie;
/ X. s1 B) b! f. I' _% D! x - $send_snoopy->referer = "https://wx.qq.com/";
7 y! `( |" m5 Y8 O - $send_snoopy->submit($submit,array());% b6 k" e7 y0 u, B3 ~
- $this->log('login_info:'.$send_snoopy->results);4 V( @+ s1 G5 V p d1 m
- $result = json_decode($send_snoopy->results,true);
' p/ N* o' E$ G4 |: s - if ($result['BaseResponse']['Ret']<0) return false;+ i& j$ s: o8 O9 ~
- $this->_login_user = $result['User'];
* n1 M l9 u+ N: |* s1 V# ]9 Y - return $result;8 b2 R1 G4 ?+ G) ?& k1 ?3 g" x
- }) l9 w$ d- L/ u$ p3 Q
- 8 N% J- b& O! p
- /**
) F' A( m( t8 V5 m+ k - * 获取头像0 B( X: G; d% E
- * @param string $url 传入从用户信息接口获取到的头像地址! O7 T1 l) ]' Q7 K4 l
- */
$ {0 Z; n0 T1 l9 N* c - public function get_avatar($url) {
/ v; Q! M# u. }" \* ^" {/ e - if (!$this->cookie) return false;, C1 ?2 ^9 I6 l9 p( e" @/ V
- if (strpos($url, 'http')===false) {2 I8 I' v2 S; J( H4 z a
- $url = 'http://wx.qq.com'.$url;
/ u: i( J! g/ T3 Y - }" B# A# O! {! F$ I0 B9 ?
- $send_snoopy = new Snoopy;
8 H- ~ ~$ g0 c9 _/ g; ~" y - $send_snoopy->rawheaders['Cookie']= $this->cookie;3 {, K- ?* a( d- C' @
- $send_snoopy->referer = "https://wx.qq.com/"; ?$ T" Y, d" U9 e/ R
- $send_snoopy->fetch($url);0 u# U ], m% m
- $result = $send_snoopy->results;
# ^1 h) ~7 `' z& \" [& i! a - if ($result)
: l) }0 I4 |2 I. @ - return $result;
* q! `* l0 w: c$ ^ - else
7 @# y% S/ [3 H# m* W$ i - return false;
% M7 v$ K& V% x1 ^6 k. B6 K, a* Y - }! F8 b) I( ~8 q j+ e
- $ |: L/ F9 N* T' i" `4 S) @
- /**
9 W( M n9 V7 m+ D) y) N - * 登出当前登陆用户4 p, ^" i. P' A% I( @' B- D
- */" b% _- S8 }1 h% d2 f
- public function logout(){: n% I0 J/ e3 p/ D$ f n- A
- if (!$this->cookie) return false;
7 N' B& b; F4 c; X - preg_match("/wxuin=(\w+);/",$this->cookie,$matches);) L0 W+ w* u* |' Z. K/ t/ N9 ~
- if (count($matches)>1) $uid = $matches[1];
6 e7 s* j# Q* R q& k: }- A( ~6 } - preg_match("/wxsid=(\w+);/",$this->cookie,$matches);
. U7 w* I. k% l4 J* U* A4 Z - if (count($matches)>1) $sid = $matches[1];; k9 x5 b* q1 P# K. d
- $this->log('logout: uid='.$uid.';sid='.$sid);
; }6 r4 o- N( A" v/ J* Z4 y+ z - $send_snoopy = new Snoopy; 2 t/ V9 B! g3 ] w* L9 O1 u# `
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
1 h2 C" b8 k4 Y) H/ L& T& g - $send_snoopy->rawheaders['Cookie']= $this->cookie;
! O" s8 C) E. V8 u& L2 v - $send_snoopy->referer = "https://wx.qq.com/";
4 D5 ?. g# L% y' Y2 A: j X) K. E - $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));6 M) M e6 W3 l
- $this->deleteCookie($this->_cookiename);& N" x0 l3 Q) z+ e" v# ~. Z: C5 l9 E
- return true;2 ^! r' x, G# _8 i' m5 H# B0 C
- }+ `: p) c3 g3 e7 V' G3 U2 J
- }
复制代码
, p" g$ G1 Y- {6 i8 ~5 u" z- q |