用户通过扫描网页提供的二维码实现登陆信息获取
- H0 [: L7 q- Y- <?php
7 h' v& T4 r+ C% t8 ?1 U( c6 T, D - /**
8 W+ \7 r; M& s( H4 Z& E - * 微信公众平台PHP-SDK
! \+ G- P$ K9 ^, k6 W: Q8 m - * Wechatauth为非官方微信登陆API
: o/ l) M e" J0 e1 E* h - * 用户通过扫描网页提供的二维码实现登陆信息获取, o1 J$ O+ A7 w: m4 |( u9 b
- * 主要实现如下功能:
5 u: x9 y9 M& _! z - * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
* G3 Y7 r% u) W/ T# Y6 r" d - * get_code_image($code='') 将上面获取的授权码转换为图片二维码
7 w" t: K+ p9 m) q4 z# }# ^ - * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.4 k- ]4 N% s8 i, d% C1 q' e
- * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息
# f. S( ] z" A - * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息) O# p4 f, s } i$ Y' E
- * get_avatar($url) 获取用户头像图片数据9 k& V2 o6 K; u/ I1 D; J
- * @author dodge <dodgepudding@gmail.com>
+ K) e9 j+ Z6 @* N, u6 I9 f! a - * @link https://github.com/dodgepudding/wechat-php-sdk
$ a1 a4 m5 e- \; b d& o2 r* ` - * @version 1.12 Y9 u# {8 h3 a/ c) u& h
- *
: l% A8 D- U; r - */
. f; H. g* o* J7 f k) j' w, i - include "snoopy.class.php"; X, s6 E! b* Z; q; K' l
- class Wechatauth$ z. @4 |" e% f" ^) q }
- {' B. _) q5 Q% @' {
- private $cookie;' |6 D6 o1 r* E5 J
- private $_cookiename;0 k$ }7 t5 e1 A+ c
- private $_cookieexpired = 3600;
# c$ \# Q9 r* v - private $_account = 'test';) r! z! A* L% a& N
- private $_datapath = './data/cookie_';0 y9 d, U4 U( j! J! o
- private $debug;
( f4 i0 [- F0 I( A, }+ e, x - private $_logcallback;
5 \4 N: S: A1 N( b" d5 s3 e E9 W - public $login_user; //当前登陆用户, 调用get_login_info后获取3 l3 e- K# F- G: W% F8 ~8 i
-
" o; _* _, x0 G- }/ |. l" Y - public function __construct($options)& p) m1 c6 @9 r# ~: D& L
- {
" b) ~0 h5 D8 ]6 H ?2 B( s - $this->_account = isset($options['account'])?$options['account']:'';
/ F8 s; V3 y R4 |2 B* k - $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
$ {- S' r M" D4 g; |. [ - $this->debug = isset($options['debug'])?$options['debug']:false;0 Q+ }1 M+ E5 C0 G+ y$ {6 }
- $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
* W* R) J: E* V9 J& R+ a, A9 F/ h - $this->_cookiename = $this->_datapath.$this->_account;
, P. ^9 I0 {: U( U - $this->getCookie($this->_cookiename);
! R3 s* d/ H9 K2 p5 w - }% M: a$ I# S; V0 C/ O7 s! ~
- /**
F0 @2 s( k& h9 Y9 k - * 把cookie写入缓存* R% ~$ f+ u. G9 ] H
- * @param string $filename 缓存文件名: {0 s' v X4 a4 ~' J" {" u! R. o J
- * @param string $content 文件内容" ^; s0 L! \: `/ Y) a2 p0 g
- * @return bool
% v7 j2 n1 N0 P5 p0 J A. \5 A - */! P; [7 P7 w6 g+ M9 K
- public function saveCookie($filename,$content){
* u/ w; O: K+ G# k' V - return file_put_contents($filename,$content);
" ~9 H% n6 X8 Q1 \5 l3 Y6 O) D - }
6 V9 M e5 I7 U! `" [3 r - / ]5 U, F0 y- T# [6 L
- /**/ g* J$ R: y, } s% ?( s. J3 X' V
- * 读取cookie缓存内容% ?+ W8 _: r+ F) A; G) ~& R
- * @param string $filename 缓存文件名) n9 H1 j' ~: |4 H4 _/ S6 f
- * @return string cookie
" t5 r z$ I) v) ] - */9 h/ f4 q% p" {$ E( B
- public function getCookie($filename){
+ A n1 ?+ G1 U - if (file_exists($filename)) {
4 {- n) @7 q8 z+ t: k! F - $mtime = filemtime($filename);
2 q$ m: k& q8 `8 e% M$ Z" S3 q4 x - if ($mtime<time()-$this->_cookieexpired) return false;8 M( R( [$ ~5 ?+ A0 P) J- P, S
- $data = file_get_contents($filename);
4 ?, G2 T) Z2 p( E4 X$ Y - if ($data) $this->cookie = $data;
9 m) r( k) t1 d% C) A, G+ s/ ] - }
6 f" P Q6 N8 }% o4 b+ S - return $this->cookie;7 D2 H) Z" S o# Z
- }
) c- H: Q" l4 \+ } - 9 t" g y9 }6 }5 a7 J
- /*
7 w. K$ R! i5 Z - * 删除cookie
. p$ C, w! h; L& [5 j5 G' X - *// {7 C! b" ]! C% s
- public function deleteCookie($filename) {
/ T' e! ~5 a9 O1 ^: I3 k, p - $this->cookie = '';0 E {7 F. m* H7 L) `1 ?$ t# T3 a
- @unlink($filename);
6 v0 _7 u( |$ C# w8 H6 f - return true; A9 @. d+ e5 |
- }
( V) b" d+ h0 ~/ y+ U -
2 B1 H% B' h& v) T - private function log($log){
2 {) a# k0 V: H1 `+ Z5 x! m8 D$ ^7 b - if ($this->debug && function_exists($this->_logcallback)) {
* Y8 O/ W2 @5 [; k) m! E( k - if (is_array($log)) $log = print_r($log,true);
7 B! N; {3 h7 ? - return call_user_func($this->_logcallback,$log);
5 B( J( l, h \8 I - }7 U: u1 a- e0 B; \
- }
/ `! k# I, E) E# r- D - 6 ?2 m4 b3 S; a
- /**
6 r( ~* w9 m8 x3 z5 r0 H6 C! {6 R - * 获取登陆二维码对应的授权码
, ]7 M' t: ?- v5 ` - */6 p/ F d" {( W+ A( p, S
- public function get_login_code(){" Q/ C$ ]2 _- E! x$ _
- if ($this->_logincode) return $this->_logincode;, k# f8 y: Y+ o; ~/ q
- $t = time().strval(mt_rand(100,999));( U* C& d9 A: ]% \* | `* y0 X( h
- $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;
0 f7 v6 g' T |+ ?6 O - $send_snoopy = new Snoopy;
1 U6 k$ L0 b, N0 h# ^1 h - $send_snoopy->fetch($codeurl);
8 `: {& Z- P. u6 B. p0 Z0 D# U4 r - $result = $send_snoopy->results;0 w" C# l5 h n; t+ b! M
- if ($result) {/ d, A P! {( i. i
- preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
9 F! Q1 @* b+ D, g9 W D - if(count($matches)>1) {
, U0 h }& h" A' \' x - $this->_logincode = $matches[1];
+ z8 Z8 p. O6 |' y. ^ c - $_SESSION['login_step'] = 0;3 V y3 Q7 M" j5 N, c' ?8 c& G
- return $this->_logincode;
: D& T, o7 A3 V - }) j* }5 x$ q2 Q8 J6 X
- }) W8 ~# @% {0 u1 D. |6 S9 b
- return $result;7 F" k8 \# n9 x1 }' U% t* Q
- }
5 U) k+ w$ f' C `
0 G M& S/ m' f2 Q9 c- n- /**
( V# D4 l4 ~+ Q$ }; R - * 通过授权码获取对应的二维码图片地址, q4 D3 ?$ M/ m' R
- * @param string $code
$ R$ V0 P, I" R - * @return string image url) ]% j$ M8 B* H) O
- */7 o1 X* o* S3 `9 ^
- public function get_code_image($code=''){
S1 h8 o* o1 Y |" @ - if ($code=='') $code = $this->_logincode;
) b$ e3 u& j- h1 O) Q6 p6 q- J - if (!$code) return false;
# b; |0 `& l' z) U& t - return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';& D: ]3 k; T- R5 h5 Q
- }
3 x$ x+ Y* n9 ^: e) H - 0 R2 J* c. L$ v3 j+ ^6 Y6 b
- /**
/ n* C: p) A" {( j$ M6 p2 B - * 设置二维码对应的授权码
' o# }2 c# D- _; }" f+ }6 S - * @param string $code
! J" ~$ E" @3 Y$ t - * @return class $this
* M' ]- V/ \7 ?* i/ q1 L. s% X$ ~ - */; u& F- b& g* A) n7 x; J8 F: L
- public function set_login_code($code) {
4 |* B' \* `" K4 J$ w - $this->_logincode = $code;
+ O {. k8 g2 g1 u - return $this;* t, M4 T6 t( b8 H" L* c! _, A
- }
7 V1 c6 I3 n/ c+ B0 g/ W. ? -
2 ?7 c" }. O2 m: ?' c. h9 k G - /**/ v4 f8 A- _2 ?( U0 D
- * 二维码登陆验证# w3 ~4 l1 \" F( Q! ^5 Q$ Z
- *
5 A4 m( {6 a0 Y8 L7 {7 F - * @return status:
7 z8 v2 a e6 y) ?5 w - * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired5 c1 M+ {# }; \0 S/ S
- * 201: just scaned but not confirm6 x! Q8 ~* x0 J" }- g7 q' c
- * 200: confirm then you can get user info
Y& H! q7 h* M; l - */" c7 \9 H: D. I# Y" w
- public function verify_code() {9 `5 k J, i7 B7 t2 U! i7 c
- if (!$this->_logincode) return false;
& a3 O& p1 k; ]: Z8 P1 t - $t = time().strval(mt_rand(100,999));5 w% M7 [! p g. w6 @) u
- 3 T% Q/ y! ^ q7 |2 G! x
- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;% p7 l- g+ i5 \6 G/ T- G
- $send_snoopy = new Snoopy;
/ d$ F7 m5 o1 n9 s* B5 z - $send_snoopy->referer = "https://wx.qq.com/";1 Z. @- I' M: K3 Q: t; D
- $send_snoopy->fetch($url);/ B+ c6 x r5 s; d
- $result = $send_snoopy->results;& S4 _# t l" ^: a. X1 l2 }* t
- $this->log('step1:'.$result);, }6 B5 g" D, f
- if ($result) {8 o ^% r( v) g: b: S9 c% ~
- preg_match("/window\.code=(\d+)/",$result,$matches);3 l! [8 ^4 S! b+ {! Q
- if(count($matches)>1) {
$ ?6 m1 u1 Z6 e! `! g - $status = intval($matches[1]);( O. E# K# r4 V) C8 Q7 t8 O
- if ($status==201) $_SESSION['login_step'] = 1;
7 C7 G# [1 a& J0 h: m B A P - if ($status==200) { l( i' T* d7 m& j) ?" o3 o" ~
- preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);. W# I% N I8 Z4 B) t" J8 b
- $this->log('step2:'.print_r($matches,true));
) ~0 k1 n4 K0 a0 q - if (count($matches)>1) {
1 J/ B9 C `! {- C8 o - $ticket = $matches[1];
' F# N6 k8 ?, I - $scan = $matches[2];" @) y+ g, ^4 q9 i6 m
- $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';' K. Y5 f+ s: R3 U
- $send_snoopy = new Snoopy;
" T. ?* q G7 A1 p1 N: W - $send_snoopy->referer = "https://wx.qq.com/";
% X$ s: e* n" o0 @ - $send_snoopy->fetch($loginurl);2 q' `6 T2 e% o/ y
- $this->log('step3:'.print_r($send_snoopy->headers,true));% h. X7 A& U- W2 o$ K
- foreach ($send_snoopy->headers as $key => $value) {
6 `! d( a* T' H* V* } - $value = trim($value);& {# j) j1 u3 m" I
- if(strpos($value,'Set-Cookie: ') !== false){
& \- M) t$ h, H! {! |: V+ o/ { - $tmp = str_replace("Set-Cookie: ","",$value);
- L# D$ a1 Q: B$ c - $tmp = str_replace("Path=/","",$tmp);1 X, F2 a' P1 {* r4 [ P
- $tmp = str_replace("Domain=.qq.com; ","",$tmp);# F; I1 i" W+ V$ q r, W
- $cookie.=$tmp;' R4 \$ f: i* a- n" R6 Z- k
- }
$ v) n7 z$ M9 c9 K+ Y - }
3 Y$ A4 r; X& @ z. c1 o. Q - $cookie .="Domain=.qq.com;";5 f( l5 g6 R* x2 d2 a' K0 b! N6 f
- $this->cookie = $cookie;
/ X* Q: j; f0 ~! i( S' e - $this->saveCookie($this->_cookiename,$this->cookie);
* n4 p2 a6 Q( T7 s5 b `( y c& U - }* g, u+ Y* J# `6 R& j
- }
1 G7 U$ Y7 |/ J6 S - return $status;
4 H9 {6 Y1 `5 t. H - }4 _' L$ N# a4 ~' K
- }$ O- |5 J, Z. C9 |) [+ L
- return false;" i& k( Y8 J$ v# h. F
- }
9 f! X8 Y/ b/ e0 _# \* c -
& K {" {& L. B4 i+ N - /**
+ U1 l$ r3 ^) J, D0 _ - * 获取登陆的cookie
L) I( \# T0 g5 z+ U- J" N" r - *6 M" r& D7 O" J0 i* p+ L" O/ L/ o1 |
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串 s: `) q; T% N q6 ]# Z
- * @return string|array3 @( q, R1 \ c- N9 y4 M
- */; [ z1 x) \, C& l
- public function get_login_cookie($is_array = false){, f1 P( G! P5 F% Q
- if (!$is_array) return $this->cookie;
& Z% z$ j8 g1 W$ G! m - $c_arr = explode(';',$this->cookie);/ C( F0 C4 j: H1 i0 o
- $cookie = array();
4 L* Q9 m6 V+ r& A2 z$ y2 V - foreach($c_arr as $item) {
1 u" |, o0 q6 c5 |* _ - $kitem = explode('=',trim($item));
. I! d, P1 M1 m" u% V6 r/ A" b7 {9 @ - if (count($kitem)>1) {) k: M Z! Q5 \& g% O+ f
- $key = trim($kitem[0]);
# m' q; D6 }2 v0 i - $val = trim($kitem[1]);
/ y8 y5 T1 C- u - if (!empty($val)) $cookie[$key] = $val;
4 w+ F5 A2 w [% e0 m" J" C( _ - }' Q" Z% z% f D7 u. _$ w' n2 m
- }, x# V% I+ c/ v2 x) R& G
- return $cookie;
+ V. A0 b* Q, U! U# G# _ - }8 N+ I5 m; @$ B) ?
- + M5 Z) c- [; z- h
- /**9 R6 B# c' W! ]# Y( |: N
- * 授权登陆后获取用户登陆信息
8 s4 D3 ^' m+ Y/ W9 |9 | - */
q( ~) R: R i% M- Q - public function get_login_info(){, \, M+ e0 f7 S. K% y& }
- if (!$this->cookie) return false;
7 z. _- ^) L4 O! v+ z - $t = time().strval(mt_rand(100,999));
, m% n: ]3 D* ]' A& K1 v% a0 l - $send_snoopy = new Snoopy; 2 t6 Y# @$ X' S( L
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;
) G5 g! ?' _ W R7 e; h6 x - $send_snoopy->rawheaders['Cookie']= $this->cookie;
+ S" T7 A$ t% f/ A- s* Q4 V5 j - $send_snoopy->referer = "https://wx.qq.com/";9 y9 ~' Y0 I% Z5 {) z
- $send_snoopy->submit($submit,array());
J' N3 J2 U4 V) ? - $this->log('login_info:'.$send_snoopy->results);* X) t1 v( A" d4 h/ v+ [! q
- $result = json_decode($send_snoopy->results,true);1 i6 x) A6 B: m& [- w
- if ($result['BaseResponse']['Ret']<0) return false;
8 U/ M1 q' g$ m. v7 [ S! ?4 a4 k - $this->_login_user = $result['User'];
, |3 u9 w+ R3 Q4 n4 Y1 ? - return $result;
1 K6 i( f% c* Q6 q3 `: ?, q8 x9 T - }
$ y u4 x+ {; K6 R. `, } - 4 [& B) v6 o }, i/ P, s! \, d
- /**! A' y- z$ L6 j7 t, Z6 Y
- * 获取头像. ?' U9 @- S m- U
- * @param string $url 传入从用户信息接口获取到的头像地址; ]5 q+ X* ^% \- b7 V& e* e
- */
, H' j# H: I) W( i8 B - public function get_avatar($url) {
/ q! C4 I7 }9 j1 h9 y3 A$ q6 r! G - if (!$this->cookie) return false;: Q0 I1 b3 A6 j# P2 _+ y
- if (strpos($url, 'http')===false) {
9 T; |# s$ D0 M/ s" V* Z - $url = 'http://wx.qq.com'.$url;9 {" [& I" p, `" H, n" G
- }
) G! X, b6 V) p% I# P( ^ - $send_snoopy = new Snoopy;
j, u4 L! D- k3 b% H L- ? - $send_snoopy->rawheaders['Cookie']= $this->cookie;
- r* j2 ~! [1 j3 o+ p1 b O+ ?% d - $send_snoopy->referer = "https://wx.qq.com/";
! J7 S9 P* X# B$ w- s; _8 d - $send_snoopy->fetch($url); J/ Y/ |& ~9 L: J p! ?2 r
- $result = $send_snoopy->results;
# x, S2 {% M e. t" M( X7 e6 p- N - if ($result) 9 O w$ d8 M8 a4 r5 b
- return $result;. G( I( m( \6 a7 e
- else
6 u; ?6 v$ \% ^" h# E - return false;& r, @- l# K5 p, m9 ~
- }
]- {; y _$ @ - 3 s" H5 J# j+ y7 P! p; a
- /**
/ ~$ R& q6 u* s - * 登出当前登陆用户2 c* q1 [' G* M% I/ e, }
- */6 D" i7 {9 l! I. ^
- public function logout(){
& F h2 U9 i3 ]1 I- V - if (!$this->cookie) return false;
+ m& e$ ]* h, C0 ] - preg_match("/wxuin=(\w+);/",$this->cookie,$matches);6 q& D3 R9 I4 C: F/ c/ D
- if (count($matches)>1) $uid = $matches[1];; o G3 V6 ~1 S# v8 M+ [" t$ R
- preg_match("/wxsid=(\w+);/",$this->cookie,$matches);8 M/ _; w) a' s! a. e! P6 r8 p
- if (count($matches)>1) $sid = $matches[1];
. S! W. w& Q' |0 Y: s! n - $this->log('logout: uid='.$uid.';sid='.$sid);
$ z( r* p0 s% g/ g$ Z - $send_snoopy = new Snoopy; 2 u( h: S7 W0 U
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
/ m& C: I0 Y6 @ - $send_snoopy->rawheaders['Cookie']= $this->cookie;
9 O, k8 l! k" S6 N' x: W9 f& H9 q - $send_snoopy->referer = "https://wx.qq.com/"; _. O! b) l" \' U
- $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));' s# e% W4 _$ a6 \1 e
- $this->deleteCookie($this->_cookiename);
- D$ s. d" ?2 w4 p* Y* | U' Z - return true;
0 r0 L; ?+ v( q2 T - }$ p7 J, |+ m# h( v5 _1 M
- }
复制代码 - y/ Y) @. m, d/ D, [8 n
|