——引子
去年我在网页版qq空间看到了一个扫描二维码安全登录的功能,也就是在pc端不用输入账号和密码,直接用qq手机客户端扫一扫网页上的二维码就可以在网页安全登录。
这个功能真是太神奇了,我想知道是怎么实现的,于是我用二维码扫描软件读出二维码图片的内容,再用firebug查看了网页的网络请求。根据上面的信息大概知道了这个功能的实现原理,然后我就萌生出把这个功能移植到WordPress的想法。
去年我已经利用一些空余时间把网页前端和服务端做好了,但是当时还不会做手机客户端,所以就暂停了这个功能的开发。不过现在我已经做了一段时间的ioser,于是在不久前我就把手机客户端做好了,总算是完成了扫描二维码登录WordPress这个功能。
演示视频如下:
后来我整理了一下代码,发现用到的知识还挺多的,所以我把实现扫码登录可能会遇到的坑记录下来。不过一篇文章应该写不完,就分开几篇写了。
一、如何让WordPress自动登录帐号
扫码登录的功能就是为了让某个帐号能够在网页能够自动登录,所以首先要完成WordPress自动登录帐号的功能。
百度一下"WordPress自动登录",发现了这篇文章:通过PHP脚本自动登陆WordPress
文章内容是忘记管理员密码时让管理员自动登录的方法,实现原理都是一样的。
新建一个test.php文件,把文章里的代码复制进去,然后把文件上传到网站根目录:
<?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文件,发现文件里面只有两行代码:
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()
,得到以下结果:
可以发现"class-wp.php"的代码有点可疑,查看该文件的代码:
/**
* 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错误了。
require('wp-blog-header.php');
status_header( 200 );
不过后来在google发现更优雅的实现方法,就是改成引用"wp-load.php"文件,完整的代码如下:
<?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);
}
?>
2015/11/17 10:39:18
博主是否可以继续分享扫码登录的文章啊
2015/11/17 23:40:23
有时间的话会继续写的
2015/09/20 08:04:40
[…] 于是乎,我就在网上开始不停地寻找类似的功能,公开的可能就只有一个洋葱扫码登录,不过看起来不怎么喜欢,但是这货居然有Windows Phone客户端,不得不说简直是良心公司,点个赞!还有一个就是这位同学,也是自己写的。还有一些就像是这样的二维码登录接入系统,我也没有尝试,正好昨天写完QQ互联插件手痒,那不如自己写一个吧。 […]
2014/09/09 10:30:26