抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

一、前言

去年我在网页版QQ空间看到了一个扫描二维码安全登录的功能,也就是在pc端不用输入账号和密码,直接用QQ手机客户端扫一扫网页上的二维码就可以在网页安全登录。
这个功能真是太神奇了,我想知道是怎么实现的,于是我用二维码扫描软件读出二维码图片的内容,再用firebug查看了网页的网络请求。根据上面的信息大概知道了这个功能的实现原理,然后我就萌生出把这个功能移植到WordPress的想法。
去年我已经利用一些空余时间把网页前端和服务端做好了,但是当时还不会做手机客户端,所以就暂停了这个功能的开发。不过现在我已经做了一段时间的iOSer,于是在不久前我就把手机客户端做好了,总算是完成了扫描二维码登录WordPress这个功能。

演示视频如下:
https://v.youku.com/v_show/id_XNzM5NDMwNTcy.html

后来我整理了一下代码,发现用到的知识还挺多的,所以我把实现扫码登录可能会遇到的坑记录下来。
不过一篇文章应该写不完,所以就分开几篇写了。

二、如何让WordPress自动登录帐号

扫码登录的功能就是为了让某个帐号能够在网页能够自动登录,所以首先要完成WordPress自动登录帐号的功能。

百度一下WordPress自动登录,发现了这篇文章:《通过PHP脚本自动登陆WordPress》,文章内容是忘记管理员密码时让管理员自动登录的方法,实现原理都是一样的。

新建一个test.php文件,把文章里的代码复制进去,然后把文件上传到网站根目录:

1
2
3
4
5
6
7
8
<?php
require('wp-blog-header.php');
$user_login = '[username]';
$user = get_userdatabylogin($user_login);
$user_id = $user->ID;
wp_set_current_user($user_id, $user_login);
do_action('wp_login', $user_login);
?>

访问后出现 HTTP/1.1 404 Not Found,也就是找不到网页。
而把require('wp-blog-header.php');这一句代码去掉后就不会出现404,但是为了使用WordPress里的函数,又必须要引用这个文件。
为什么会出现404呢,一开始我也觉得很奇怪,于是看了index.php文件,发现文件里面只有两行代码:

1
2
define('WP_USE_THEMES', true);
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

复制index.php,改名为index2.php,放到网站根目录,访问后也出现了404
为什么同样的代码,index.php访问正常,index2.php就不能访问呢?
最可能的答案就是WordPress判断了引用wp-blog-header.php的网页是不是网站首页,不是首页就会出现404

WordPress的源码里搜索is_home(),得到以下结果:
This is a picture without description

可以发现class-wp.php的代码有点可疑,查看该文件的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* Set the Headers for 404, if nothing is found for requested URL.
*
* Issue a 404 if a request doesn't match any posts and doesn't match
* any object (e.g. an existing-but-empty category, tag, author) and a 404 was not already
* issued, and if the request was not a search or the homepage.
*
* Otherwise, issue a 200.
*
* @since 2.0.0
*/
function handle_404() {
global $wp_query;

// If we've already issued a 404, bail.
if ( is_404() )
return;

// Never 404 for the admin, robots, or if we found posts.
if ( is_admin() || is_robots() || $wp_query->posts ) {
status_header( 200 );
return;
}

// We will 404 for paged queries, as no posts were found.
if ( ! is_paged() ) {

// Don't 404 for these queries if they matched an object.
if ( ( is_tag() || is_category() || is_tax() || is_author() || is_post_type_archive() ) && $wp_query->get_queried_object() ) {
status_header( 200 );
return;
}

// Don't 404 for these queries either.
if ( is_home() || is_search() ) {
status_header( 200 );
return;
}
}

// Guess it's time to 404.
$wp_query->set_404();
status_header( 404 );
nocache_headers();
}

该函数判断了很多个条件,最后判断了if ( is_home() || is_search() ),如果访问的是首页或者是搜索页就返回200,否则就返回404
所以可以在test.php里面加上一行代码,强制输出200状态码,这样就不会出现404错误了。

1
2
require('wp-blog-header.php');
status_header( 200 );

不过后来在Google发现更优雅的实现方法,就是改成引用wp-load.php文件,完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
require('wp-load.php');

if (!is_user_logged_in()) {
$user_login = 'admin';
$user = get_userdatabylogin($user_login);
$user_id = $user->ID;
wp_set_current_user($user_id, $user_login);
wp_set_auth_cookie($user_id);
do_action('wp_login', $user_login);
}
?>

评论