用户通过扫描网页提供的二维码实现登陆信息获取
% j" H+ b2 [1 }& ?" l. _; W) E" m, @- <?php
1 F ], A( R$ h3 T# \6 @" o, ^ - /**1 w* u* b H6 J* z+ `; {0 E8 A
- * 微信公众平台PHP-SDK7 u# y$ t3 `+ y: [4 {( s
- * Wechatauth为非官方微信登陆API" |" b& Q" e. R' m9 j5 G- I- M" U
- * 用户通过扫描网页提供的二维码实现登陆信息获取* A! V/ V# f7 V$ c9 n0 q
- * 主要实现如下功能:
$ X Y" z; \2 L% r# J9 J5 k8 ~& P9 | - * get_login_code() 获取登陆授权码, 通过授权码才能获取二维码
" a+ t! h1 `% f8 ]! ~- D. _& e - * get_code_image($code='') 将上面获取的授权码转换为图片二维码$ A: Q o+ `! n0 K) p+ Z
- * verify_code() 鉴定是否登陆成功,返回200为最终授权成功.
) Z, \- I2 S! H. F - * get_login_cookie() 鉴定成功后调用此方法即可获取用户基本信息4 v8 c: G1 h* l7 Z5 y
- * sendNews($account,$title,$summary,$content,$pic,$srcurl='') 向一个微信账户发送图文信息& @/ f( B r- @. c
- * get_avatar($url) 获取用户头像图片数据7 q1 S l* Y( r* M7 r" J$ ?! e
- * @author dodge <dodgepudding@gmail.com>. b' D/ d' c! G& P
- * @link https://github.com/dodgepudding/wechat-php-sdk: {. _1 N; W6 s& O
- * @version 1.1
3 ]' E8 `: z( b% P( q - *
3 f9 B4 }# k! ?3 m) S - */
3 P" }5 @/ z% S2 F- C - include "snoopy.class.php";
% ~, t! p6 c% I- r" d - class Wechatauth3 S, P2 x( ^$ Z
- {3 c2 Q* ]% x6 |- l! U
- private $cookie;
" R! @5 h& O& O" u - private $_cookiename;
" P0 V& G! S! r - private $_cookieexpired = 3600;- K7 o! L# W4 Q W Y
- private $_account = 'test';5 p+ [* R9 ? r
- private $_datapath = './data/cookie_';
. B# x6 C4 w) a! V; B6 r7 u+ ? - private $debug;1 ~9 d2 K: h% N1 F" W
- private $_logcallback;& Q& ]; s- P# Q* I# }0 y
- public $login_user; //当前登陆用户, 调用get_login_info后获取3 o9 v1 D, G5 w; j" U) b
-
5 P# K+ @. n0 G. e7 O - public function __construct($options)
+ [3 a! r: [7 r1 X - {) c$ Z- X+ X b6 q% g! ?. \/ |) n
- $this->_account = isset($options['account'])?$options['account']:'';, R7 x' b, M1 B9 G, k
- $this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;
$ X7 g% V+ o* F8 G+ ` - $this->debug = isset($options['debug'])?$options['debug']:false;
8 d; q0 Y7 q5 m I, z - $this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;
: n% t: g" }7 O b* t - $this->_cookiename = $this->_datapath.$this->_account;
* x1 t$ ]+ g0 F3 f - $this->getCookie($this->_cookiename);. z# @) E0 s- ~' D3 j
- }4 I0 i" {7 Q9 m" o' E
- /**4 {! l2 p) _. |/ U3 X2 B; S
- * 把cookie写入缓存/ ?' O( A1 C9 i; D- d7 X7 M9 Q
- * @param string $filename 缓存文件名* D5 r- A9 F# X: r. F
- * @param string $content 文件内容3 m7 C/ ?. S1 O5 ]% e9 \. r
- * @return bool0 H) w2 G, G2 o) d4 ^
- */# c0 p! D. `0 D
- public function saveCookie($filename,$content){8 B0 o: ?( D' V. O7 l( n
- return file_put_contents($filename,$content); U7 M, t- \" L9 A
- }5 L) M7 S u/ p& D% Q' v8 P
- 4 I4 S6 C% T2 {1 |
- /**
3 {4 x1 T s: V - * 读取cookie缓存内容
8 Q/ c4 i3 H6 H+ E3 Z; h - * @param string $filename 缓存文件名: M3 f# t9 U" m- ^
- * @return string cookie
4 b3 d2 R D# m/ { - */
6 O L' j0 y. @# p1 I1 Z, [% G8 M - public function getCookie($filename){
" [& r1 _# R5 j" ^* z - if (file_exists($filename)) {0 v8 R. v0 d. H
- $mtime = filemtime($filename);3 p5 ], S: ^, }0 X- }( x
- if ($mtime<time()-$this->_cookieexpired) return false;# o. N, r, S- r! d/ d4 W( H2 ~
- $data = file_get_contents($filename);
$ N, {6 B8 K8 m- s% _% ?) w% K - if ($data) $this->cookie = $data;* n7 M/ X3 ]0 v5 c0 s* C/ H
- }
! H' i8 Y* L9 M e5 H, n) }# b+ b/ z - return $this->cookie;' N* b4 K; X' [: W0 ]9 p) I2 B
- }. O3 l9 l: o4 l& v- V" b
-
+ S7 {7 P; }' H2 n! J4 A8 l1 l - /* [8 _. _% N2 V+ y8 g( _
- * 删除cookie; e; D, O R! e
- */7 o1 n7 B* l. d
- public function deleteCookie($filename) {
# X7 c6 _" j Q* s3 N - $this->cookie = '';
2 K: g( s- D7 m; n+ C - @unlink($filename);
# x! F; k4 j- S - return true;
G5 i9 M: v+ j. D+ |% a7 v - }
3 s- U/ V* D- A, n - % d$ C' c! L: r3 z1 O6 |
- private function log($log){3 k5 i! W1 L! J$ E
- if ($this->debug && function_exists($this->_logcallback)) {9 m5 z: d0 G) r: l1 f3 I7 {
- if (is_array($log)) $log = print_r($log,true);
! j$ b! G l% a% ~/ G8 W# h+ ` - return call_user_func($this->_logcallback,$log);
n) ?( j0 m( ^0 h q! { - }
3 Z9 r6 c9 Y3 u7 \4 G2 z - }
+ n) N$ e. ~. |4 G" N -
6 `* H" T4 \, i: U. W - /**
/ y0 {, I, K, y4 X! o* N - * 获取登陆二维码对应的授权码7 ^' E: O! S {# n5 l& @
- */+ j' b. D3 O! Q( g' p; `
- public function get_login_code(){4 P0 R- r! x; Y* U
- if ($this->_logincode) return $this->_logincode;
% z" T+ j$ ?2 X4 b - $t = time().strval(mt_rand(100,999));
' \) ^/ y* }6 H! X7 ~3 l: v/ o2 J - $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 i$ q3 P. K1 c$ K: d
- $send_snoopy = new Snoopy; ( N/ a; y$ _0 c# o9 E
- $send_snoopy->fetch($codeurl);
2 P1 [: m+ x4 C) R - $result = $send_snoopy->results;4 g* f: s! K5 V7 v9 T; U6 g1 ?
- if ($result) {% V3 Z- O$ |2 D6 z* { D" K& o+ H
- preg_match("/window.QRLogin.uuid\s+=\s+"([^"]+)"/",$result,$matches);
. ~8 J5 Y, I4 D - if(count($matches)>1) {3 }* q" n# q, |" j( u
- $this->_logincode = $matches[1];
% ~; p) d* N8 r( E - $_SESSION['login_step'] = 0;
0 t7 i& P9 r2 d; }2 B% n - return $this->_logincode;. p7 W& R8 h! a* o
- }( C% s# a- c6 E/ z. y. N
- }
6 I; f, ~# a& m# r/ r0 m - return $result;
+ u# `% m0 Y; I& Q - }
" [& b E [% d; l1 o; e - 2 Y$ |7 ~* E3 d$ Z1 i
- /**
1 M H+ @5 Y" p& C1 z) t. _ - * 通过授权码获取对应的二维码图片地址
, }& z1 w$ E0 k T1 j - * @param string $code5 j* b1 P" \5 k4 t' ]
- * @return string image url
7 o z; s3 f7 b, c+ K: O; \/ e - */
' Y F( w* K1 _ - public function get_code_image($code=''){1 @+ w5 x/ }% g6 |. [
- if ($code=='') $code = $this->_logincode;
9 {/ l+ X- t, B4 ~ - if (!$code) return false;( b) F5 J+ ~* W- o1 l m
- return 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';
1 ]7 z/ d A/ A: L! |: i( N - }
! X% Q9 Y. }. ^) N5 {7 ]8 D8 C5 j -
, t/ k# n x& Y, r% e9 c" L h - /**( u+ `* j+ w5 g$ y# B
- * 设置二维码对应的授权码6 w- \. D$ h e! ^) n) K& B
- * @param string $code
. l( r+ D: ^/ O- }- Z0 b - * @return class $this
6 G" R, b' p6 S2 O$ ^ - */
: X% l# l5 H1 U5 s; V - public function set_login_code($code) {% n( s4 h# G' y0 m/ r! o5 m# n0 Q
- $this->_logincode = $code;4 x$ ~! k, i) x1 H+ ^4 q
- return $this;& e3 [2 X7 T- Z# h- z5 l
- }
! @2 O- B2 a) Q& I, F5 P - - O. I5 o2 R) P; V. `" H0 L* d/ v
- /**
, s7 Z& X/ {/ Q5 n% S - * 二维码登陆验证
$ W$ S$ {4 X: x6 w; } - *: p6 G& x1 V7 @: Y
- * @return status:
5 @* E+ X2 Q2 S% i - * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired' B& ?2 m2 z7 p7 R, y- b: Z8 ^% l
- * 201: just scaned but not confirm
& E5 _4 I [: f8 w - * 200: confirm then you can get user info* k* m2 s& k5 S- i
- */5 f/ l3 t ^! K( o9 v9 G1 g6 n
- public function verify_code() {) ]; W2 |6 H9 R; C( q. u7 G
- if (!$this->_logincode) return false;
: E' R& {( K' D2 w+ d" A4 x4 y - $t = time().strval(mt_rand(100,999));6 t6 s6 {& T4 ~8 @+ P
: U: [% Y' i/ X7 n9 I' O- $url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=1&_='.$t;' h9 h3 C: Q( F( K, p( b* B
- $send_snoopy = new Snoopy;
9 N6 K, m9 r3 q" B8 ? | - $send_snoopy->referer = "https://wx.qq.com/";+ N" L: u9 H0 z, u
- $send_snoopy->fetch($url);
0 Q( w: L* B! f9 y7 i" |+ }" x - $result = $send_snoopy->results;9 U- X6 [1 P O
- $this->log('step1:'.$result);0 f# ^" Z5 L7 z. `; n
- if ($result) {' n. X3 G+ N0 o' | Z5 x
- preg_match("/window\.code=(\d+)/",$result,$matches);& A1 k2 p k% Q2 \3 @+ c: N6 t0 k
- if(count($matches)>1) {+ w, {( \; |* `" e+ G1 }
- $status = intval($matches[1]);' p0 |& X: N% S$ n* R0 S$ j
- if ($status==201) $_SESSION['login_step'] = 1;! E7 M$ u, U6 S. E8 h
- if ($status==200) {
5 V8 ?: ^ s8 H! J: y; }( g6 w - preg_match("/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\d+)/",$result,$matches);
: }: o0 r' [' S: w - $this->log('step2:'.print_r($matches,true));
: a# \# G4 S7 e" Z4 c - if (count($matches)>1) {. C! K& y7 _, b6 O
- $ticket = $matches[1];
+ A" [. D. C/ |' w9 g* g - $scan = $matches[2];
) o l* W6 E( e; q" R - $loginurl = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';* S1 w. \( @4 L, `
- $send_snoopy = new Snoopy; : u! ?' C! Z: Y& u* g/ r
- $send_snoopy->referer = "https://wx.qq.com/";) t0 P4 F; y" T* @+ {! V1 J) `3 w* O
- $send_snoopy->fetch($loginurl);
6 G, R3 [& m6 H- a+ D/ w4 x - $this->log('step3:'.print_r($send_snoopy->headers,true));
: y% @) R$ k* g1 k W) i" g8 U - foreach ($send_snoopy->headers as $key => $value) {* ]- [+ O5 H& W: D0 s0 R
- $value = trim($value);
1 f1 C* J) z6 {( T' f - if(strpos($value,'Set-Cookie: ') !== false){5 x' D/ p) c+ r$ h8 z1 J. q% U
- $tmp = str_replace("Set-Cookie: ","",$value);
- B- L0 J+ z* ? - $tmp = str_replace("Path=/","",$tmp);2 z2 I( l5 `: C; Y) J
- $tmp = str_replace("Domain=.qq.com; ","",$tmp);( _: b2 K8 g$ @! d. s3 k$ ]
- $cookie.=$tmp;
/ \0 d7 n8 c& X' v o - }( j+ ~3 x1 v. k ]- }3 j! S$ S2 J% |* z
- }
+ k# A- ~' R1 `! _7 x8 f - $cookie .="Domain=.qq.com;";
4 B8 a, {* |9 \) ?( A4 U7 w - $this->cookie = $cookie;
- d- S9 D7 y8 j* b - $this->saveCookie($this->_cookiename,$this->cookie);
) z# q7 n7 y- E, a+ T - }; ~/ q- C! z) |$ v
- }* e! v- ^4 q* \5 A0 `
- return $status;, V( e4 ]" ~1 F2 J5 T: V( d
- }
R4 C0 s; K2 E - }: g p+ g$ S3 i6 W5 S; H# l
- return false;
f' y) h8 i2 q8 d - }
( V0 J) x I' _1 w - ' |- a) V: B- |$ c2 _; @
- /**. L! @: J! P! I* {
- * 获取登陆的cookie
' C& H3 U+ s; ^3 ]& i3 L - *2 [. N' u0 a; z& a$ O6 }6 F1 @0 \
- * @param bool $is_array 是否以数值方式返回,默认否,返回字符串
4 n$ C$ k' R4 Z+ k: Z+ o - * @return string|array7 d* @8 o, `% ]: ]
- */
+ \! \; c5 {3 B2 s& k8 h g - public function get_login_cookie($is_array = false){
8 J; D4 t# \3 z) m - if (!$is_array) return $this->cookie;8 _, o: I8 ]- n( f* c9 k0 ~+ c
- $c_arr = explode(';',$this->cookie);9 d; L6 \* |* k: z& E# k! z- ]
- $cookie = array();
8 x3 ?& m: G3 s8 b$ `- Z - foreach($c_arr as $item) {
, u- k/ Z/ b+ F" s& D. a0 P& U4 z - $kitem = explode('=',trim($item));
) z' c3 L0 U& M - if (count($kitem)>1) {$ Q9 r6 P% {6 e- S5 {" Z& M
- $key = trim($kitem[0]);8 {; |, g; w! K$ Z
- $val = trim($kitem[1]);4 q& f; S$ n4 L$ ~& S
- if (!empty($val)) $cookie[$key] = $val; P I8 Q4 [( x- D
- }
) p6 G: _5 w2 p - }2 }7 d- A g% W0 {) c3 l9 {" H
- return $cookie;
* a" v( x* Q* T2 G - }
( R. ^) z0 F- {! w5 Y -
4 y2 v0 a" r, I) w+ v/ s D - /**: B7 n( q- \5 b, z" V. r; w
- * 授权登陆后获取用户登陆信息9 i! J/ L9 i- M+ a$ {- g
- */
* N, G( Z3 j8 [8 }- d. G# }9 {* l4 s - public function get_login_info(){) o2 D" V- R. H$ h
- if (!$this->cookie) return false;
8 E7 x/ a* p' x3 U. T( ^- F3 T - $t = time().strval(mt_rand(100,999));
4 L6 f% Y: l- `! j4 |2 g( H - $send_snoopy = new Snoopy;
$ g( y" {5 P- H( V - $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t;) y" v2 p* a7 Y; g/ W, j
- $send_snoopy->rawheaders['Cookie']= $this->cookie; B; P" A0 d2 K/ Q: R V" n& d
- $send_snoopy->referer = "https://wx.qq.com/";4 a6 L* \ x2 @7 S
- $send_snoopy->submit($submit,array());4 P7 l; t0 t4 [; n" D& d J0 u1 t* w
- $this->log('login_info:'.$send_snoopy->results);+ |! M2 t: z0 o' c5 @, t
- $result = json_decode($send_snoopy->results,true);
( T" r: \9 L3 N. e: i: `4 w- F ^. m - if ($result['BaseResponse']['Ret']<0) return false;$ B1 k& A5 T1 {3 @. K8 N
- $this->_login_user = $result['User'];
1 F# x* A# h0 ` - return $result;$ z |" p8 b% K
- }
/ H6 @- n \8 W- L8 B6 s - 9 X/ L! M, e5 }" a1 U% g( N
- /**
' x: m P$ H6 u& ^ - * 获取头像& I1 K5 Q( K/ I2 P1 D- Q% q
- * @param string $url 传入从用户信息接口获取到的头像地址6 t0 O* {. L# b7 ]& B5 T5 i
- */& X5 w" `$ j" P1 h% `! {) [
- public function get_avatar($url) {( g# C! x8 d+ i5 R- G
- if (!$this->cookie) return false;
% Q; }5 w9 x; l5 P M/ y - if (strpos($url, 'http')===false) {" o, A! P2 v# P+ T
- $url = 'http://wx.qq.com'.$url;
1 v d( _2 x* o; o - }* d; b2 K& c; `
- $send_snoopy = new Snoopy; 9 M0 d) D( D+ a& o
- $send_snoopy->rawheaders['Cookie']= $this->cookie;; A# v8 k% X d% C, @3 E( [
- $send_snoopy->referer = "https://wx.qq.com/";# k3 W7 f$ S; k5 f
- $send_snoopy->fetch($url);
# {+ w- F$ \6 K u - $result = $send_snoopy->results;
& I% _* m; s8 ^0 ? - if ($result) , I, C. F" _+ \) F- n$ M
- return $result;, z8 h3 @% g0 O# U! }
- else
h ?. m9 ?& a* l, Z1 B - return false;
! }0 I6 C' B) M# q9 `: d - }
+ l% _& F7 k U& s -
& q: W' Z: I% t; j- ]1 Z( Y - /**; m: G. ~- a. M8 L! ^6 Q8 B8 P3 |
- * 登出当前登陆用户
! |' s! G& I6 y- y2 V - */' L+ O* o/ I+ Q* A; A
- public function logout(){8 @5 W& V5 `$ I: ?$ o
- if (!$this->cookie) return false;. c) F2 _3 s& }
- preg_match("/wxuin=(\w+);/",$this->cookie,$matches);" z3 h" K3 M' M/ L% P0 S
- if (count($matches)>1) $uid = $matches[1];
! Q4 p" `# c8 e, \9 @ - preg_match("/wxsid=(\w+);/",$this->cookie,$matches);( s# s/ k" N7 O/ S3 D- R% S& _
- if (count($matches)>1) $sid = $matches[1];
3 u: g& v# A. O$ I7 O9 H0 U - $this->log('logout: uid='.$uid.';sid='.$sid);1 J9 E( V9 h( u
- $send_snoopy = new Snoopy; 8 W7 n0 T& l7 G$ s3 k2 g
- $submit = 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';
. Z( o; D% F. i4 H; T$ M r - $send_snoopy->rawheaders['Cookie']= $this->cookie;
6 O# @) l% P/ i3 b) u! P4 h* S - $send_snoopy->referer = "https://wx.qq.com/";0 c) l5 q8 r. y7 G" h# |6 ]6 F
- $send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));
/ ]0 D6 r; W9 m. p+ o) C - $this->deleteCookie($this->_cookiename);/ g7 D5 e) a8 t# c0 m! f
- return true;( n' ~. v$ u; ^' ^% O1 k
- }% T) @! ~1 E% Q$ ]8 b* D+ {
- }
复制代码
" C, b& [- N& r |