WordPress记录用户登录记录并显示在用户个人中心

为了进一步提高User-Agent的解析效果,决定弃用目前的UA解析函数,采用百度前端团队开发的Node.js开源项目UA-Device,并封装为Api供WordPress调用。目前接口向公网开放,但随时有可能视情况关闭或者实行对接口要求鉴权等减少并发量的措施。
体验地址:htps://api.hanada.info/ua 请求方式为?ua={user-agent}。Get请求后将会返回json格式的UA解析结果,如未指定text参数,则输出当前访问该Api的设备的UA解析结果。解析结果仅供参考。

4月1日更新(不是愚人节玩笑):优化User Agent判断函数(发现在Ubuntu里Chrome无法获取系统名);登录记录改为直接记录UA,输出时再调用判断函数输出系统名、版本、浏览器等信息。

对于用户数比较多的WordPress站点,用户的个人账号的安全性就变得更重要,尤其是购物网站等站点更对用户账号的安全更为关心。此时如果记录用户登录记录数据并提供给用户查看,用户便能很容易察觉到异常的登录情况。
大部分互联网公司都有提供登录记录查询,例如百度( https://passport.baidu.com/ )、微博( https://security.weibo.com/loginrecord/active )等。

百度的登录记录

微博的登录记录

既然要显示登录记录,就得先记录。因此要向用户元数据里写入一个新的记录登录情况的值。登录记录的内容有登录时间、IP地址、地理位置、设备系统和浏览器信息以及登录类型。

  • 登录时间:登录时记录时间。
  • 登录IP:登录时记录用户IP。
  • 地理位置:将IP地址利用IP数据库接口得出地理位置。
  • 设备系统和浏览器信息:登录时记录用户浏览器User Agent信息,并通过正则即可得出系统和浏览器信息。
  • 登录类型:用于区分用户是使用用户名/密码还是第三方账号Oauth登录。

以上便是在登录时要记录的信息。
为了在用户元数据中记录登录记录,这里使用login_message和login_num来存储,其中login_message登录记录数据,login_num用于定位login_message中最新数据的位置,为了减少数据量,只记录最新的8条数据,旧的数据将会被覆盖。

地理位置这里调用了ipip.net的免费接口,这个接口限制每天2000请求,以及同时请求,如果用户数较多登录记录请求数较大的话可以考虑购买其收费接口或使用其他接口。地理位置这里调用了ipip.net的免费接口,这个接口限制每天2000请求,以及同时请求,如果用户数较多登录记录请求数较大的话可以考虑购买其收费接口或使用其他接口。

分析UA并得出操作系统和浏览器型号使用hanada_get_user_agent()函数,向其传参UA即可返回操作系统和浏览器型号。分析浏览器UA代码如下。

分析浏览器UA代码

function clrs_get_user_agent($useragent)
{
    $stitle = $sver = null;
    if(preg_match('/iPad/i',$useragent)){
        $stitle = 'iPad';
        if(preg_match('/CPU\ OS\ ([.<em>0-9a-zA-Z]+)/i',$useragent,$regmatch)) $sver = 'iOS '.str_replace('</em>','.',$regmatch[1]);
    }elseif(preg_match('/iPod/i',$useragent)){
        $stitle = 'iPod';
        if(preg_match('/iPhone\ OS\ ([.<em>0-9a-zA-Z]+)/i',$useragent,$regmatch)) $sver = 'iOS '.str_replace('</em>','.',$regmatch[1]);
    }elseif(preg_match('/iPhone/i',$useragent)&&!preg_match('/Windows Phone/i',$useragent)){
        $stitle = 'iPhone';
        if(preg_match('/iPhone\ OS\ ([.<em>0-9a-zA-Z]+)/i',$useragent,$regmatch)) $sver = 'iOS '.str_replace('</em>', '.', $regmatch[1]);
    }elseif(preg_match('/Windows Phone OS 7/i',$useragent)||preg_match('/ZuneWP7/i',$useragent)||preg_match('/WP7/i',$useragent)){
        $stitle = 'Windows Phone';
        $sver = '7';
    }elseif(preg_match('/Windows Phone OS 8.1/i',$useragent)||preg_match('/Windows Phone 8.1/i',$useragent)||preg_match('/WP8.1/i',$useragent)){
        $stitle = 'Windows Phone';
        $sver = '8.1';
    }elseif(preg_match('/Windows Phone OS 8/i',$useragent)||preg_match('/Windows Phone 8/i',$useragent)||preg_match('/WP8/i',$useragent)){
        $stitle = 'Windows Phone';
        $sver = '8';
    }elseif(preg_match('/Windows Phone 10/i',$useragent)||preg_match('/WP10/i',$useragent)){
        $stitle = 'Windows Phone';
        $sver = '10';
    }elseif(preg_match('/wp-windowsphone/i',$useragent)){
        $stitle = 'Windows Phone';
    }elseif(preg_match('/Android/i',$useragent)){
        $stitle = 'Android';
        if(preg_match('/Android[\ |\/]?([.0-9a-zA-Z]+)/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/[^A-Za-z]Arch/i',$useragent)){
        $stitle = 'Arch Linux';
    }elseif(preg_match('/CentOS/i',$useragent)){
        $stitle = 'CentOS';
        if(preg_match('/.el([.0-9a-zA-Z]+).centos/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/Debian/i',$useragent)){
        $stitle = 'Debian GNU/Linux';
    }elseif(preg_match('/Edubuntu/i',$useragent)){
        $stitle = 'Edubuntu';
        if(preg_match('/Edubuntu<a href="[.0-9a-zA-Z]+">\/|\ </a>/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/FreeBSD/i',$useragent)){
        $stitle = 'FreeBSD';
    }elseif(preg_match('/Kubuntu/i',$useragent)){
        $stitle = 'Kubuntu';
        if(preg_match('/Kubuntu<a href="[.0-9a-zA-Z]+">\/|\ </a>/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/Linux\ Mint/i',$useragent)){
        $stitle = 'Linux Mint';
        if(preg_match('/Linux\ Mint\/([.0-9a-zA-Z]+)/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/Lubuntu/i',$useragent)){
        $stitle = 'Lubuntu';
        if (preg_match('/Lubuntu<a href="[.0-9a-zA-Z]+">\/|\ </a>/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/Mac/i',$useragent)||preg_match('/Darwin/i',$useragent)){
        $stitle = 'Mac';
        if(preg_match('/Mac OS X/i',$useragent)||preg_match('/Mac OSX/i',$useragent)){
            if(preg_match('/Mac OS X/i',$useragent)){
                $sver = substr($useragent,strpos(strtolower($useragent),strtolower('OS X'))+4);
            }else{
                $sver = substr($useragent,strpos(strtolower($useragent),strtolower('OSX'))+3);
            }
            $sver = substr($sver,0,strpos($sver,')'));
            if(strpos($sver,';') > -1) $sver = substr($sver,0,strpos($sver,';'));
            $sver = str_replace('<em>','.',$sver);
            if($wpua_show_version==='simple'&&preg_match('/([0-9]+.[0-9]+)/i',$sver,$regmatch)) $sver = $regmatch[1];
            $sver = (empty($sver))?'OS X':"OS X $sver";
        }elseif(preg_match('/Darwin/i',$useragent)){
            $sver = 'OS Darwin';
        }else{
            $stitle = 'Macintosh';
        }
    }elseif(preg_match('/NetBSD/i',$useragent)){
        $stitle = 'NetBSD';
    }elseif(preg_match('/Nova/i',$useragent)){
        $stitle = 'Nova';
        if(preg_match('/Nova<a href="[.0-9a-zA-Z]+">\/|\ </a>/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/OpenBSD/i',$useragent)){
        $stitle = 'OpenBSD';
    }elseif(preg_match('/Red\ Hat/i',$useragent)||preg_match('/RedHat/i',$useragent)){
        $stitle = 'Red Hat';
        if(preg_match('/.el([._0-9a-zA-Z]+)/i',$useragent,$regmatch)){
            $stitle .= ' Enterprise Linux';
            $sver = str_replace('</em>','.',$regmatch[1]);
        }
    }elseif(preg_match('/Xubuntu/i',$useragent)){
        $stitle = 'Xubuntu';
        if(preg_match('/Xubuntu<a href="[.0-9a-zA-Z]+">\/|\ </a>/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/Ubuntu/i',$useragent)){
        $stitle = 'Ubuntu';
        if(preg_match('/Ubuntu<a href="[.0-9]+[.0-9a-zA-Z]+">\/|\ </a>/i',$useragent,$regmatch)) $sver = $regmatch[1];
    }elseif(preg_match('/Unix/i',$useragent)){
        $stitle = 'Unix';
    }elseif(preg_match('/Linux/i',$useragent)){
        $stitle = 'Linux';
    }elseif(preg_match('/Windows/i',$useragent)||preg_match('/WinNT/i',$useragent)||preg_match('/Win32/i',$useragent)){
        $stitle = 'Windows';
        if(preg_match('/Windows NT 10.0/i',$useragent)||preg_match('/Windows NT 6.4/i',$useragent)){
            $sver = '10';
        }elseif(preg_match('/Windows NT 6.3/i',$useragent)){
            $sver = '8.1';
        }elseif(preg_match('/Windows NT 6.2/i',$useragent)){
            $sver = '8';
        }elseif(preg_match('/Windows NT 6.1/i',$useragent)){
            $sver = '7';
        }elseif(preg_match('/Windows NT 6.0/i',$useragent)){
            $sver = 'Vista';
        }elseif(preg_match('/Windows NT 5.2 x64/i',$useragent)){
            $sver = 'XP';
        }elseif(preg_match('/Windows NT 5.2/i',$useragent)){
            $sver = 'Server 2003';
        }elseif(preg_match('/Windows NT 5.1/i',$useragent)||preg_match('/Windows XP/i',$useragent)){
            $sver = 'XP';
        }elseif(preg_match('/Windows NT 5.01/i',$useragent)){
            $sver = '2000, Service Pack 1 (SP1)';
        }elseif(preg_match('/Windows NT 5.0/i',$useragent)||preg_match('/Windows NT5/i',$useragent)||preg_match('/Windows 2000/i',$useragent)){
            $sver = '2000';
        }elseif(preg_match('/Windows NT 4.0/i',$useragent)||preg_match('/WinNT4.0/i',$useragent)){
            $sver = 'NT 4.0';
        }elseif (preg_match('/Windows NT 3.51/i',$useragent)||preg_match('/WinNT3.51/i',$useragent)){
            $sver = 'NT 3.11';
        }elseif(preg_match('/Windows NT/i',$useragent)||preg_match('/WinNT/i',$useragent)){
            $sver = 'NT';
        }elseif(preg_match('/Windows 3.11/i',$useragent)||preg_match('/Win3.11/i',$useragent)||preg_match('/Win16/i',$useragent)){
            $sver = '3.11';
        }elseif(preg_match('/Windows 3.1/i',$useragent)){
            $sver = '3.1';
        }elseif(preg_match('/Windows 98; Win 9x 4.90/i',$useragent)||preg_match('/Win 9x 4.90/i',$useragent)||preg_match('/Windows ME/i',$useragent)){
            $sver = 'Millennium Edition (Windows Me)';
        }elseif(preg_match('/Win98/i',$useragent)){
            $sver = '98 SE';
        }elseif(preg_match('/Windows 98/i',$useragent)||preg_match('/Windows\ 4.10/i',$useragent)){
            $sver = '98';
        }elseif(preg_match('/Windows 95/i',$useragent)||preg_match('/Win95/i',$useragent)){
            $sver = '95';
        }elseif(preg_match('/Windows CE/i',$useragent)){
            $sver = 'CE';
        }elseif(preg_match('/WM5/i',$useragent)){
            $sver = 'Mobile 5';
        }elseif(preg_match('/WindowsMobile/i',$useragent)){
            $sver = 'Mobile';
        }else{
        }
    }
    $btitle = null;
    if(preg_match('/BonEcho/i',$useragent)){
        $btitle = 'BonEcho';
    }elseif(preg_match('/chromeframe/i',$useragent)){
        $btitle = 'Google Chrome Frame';
    }elseif(preg_match('/ChromePlus/i',$useragent)){
        $btitle = 'ChromePlus';
    }elseif(preg_match('/Chromium/i',$useragent)){
        $btitle = 'Chromium';
    }elseif(preg_match('/CrMo/i',$useragent)){
        $btitle = 'Chrome Mobile';
    }elseif(preg_match('/CriOS/i',$useragent)){
        $btitle = 'Chrome';
    }elseif(preg_match('/Galaxy/i',$useragent)&&!preg_match('/Chrome/i',$useragent)){
        $btitle = 'Galaxy';
    }elseif(preg_match('/GoBrowser/i',$useragent)){
        $btitle = 'GO Browser';
    }elseif(preg_match('/Google\ Wireless\ Transcoder/i',$useragent)){
        $btitle = 'Google Wireless Transcoder';
    }elseif(preg_match('/GreenBrowser/i',$useragent)){
        $btitle = 'GreenBrowser';
    }elseif(preg_match('/GSA/i',$useragent)&&preg_match('/Mobile/i',$useragent)){
        $btitle = 'Google Search App';
    }elseif(preg_match('/Lorentz/i',$useragent)){
        $btitle = 'Lorentz';
    }elseif(preg_match('/MiniBrowser/i',$useragent)){
        $btitle = 'MiniBrowser';
    }elseif(preg_match('/Minimo/i',$useragent)){
        $btitle = 'Minimo';
    }elseif(preg_match('/MiuiBrowser/i',$useragent)){
        $btitle = 'MIUI Browser';
    }elseif(preg_match('/Mosaic/i',$useragent)){
        $btitle = 'Mosaic';
    }elseif(preg_match('/MozillaDeveloperPreview/i',$useragent)){
        $btitle = 'Mozilla Developer Preview';
    }elseif(preg_match('/MQQBrowser/i',$useragent)||preg_match('/QQBrowser/i',$useragent)){
        $btitle = 'QQbrowser';
    }elseif(preg_match('/MultiZilla/i',$useragent)){
        $btitle = 'MultiZilla';
    }elseif(preg_match('/NokiaBrowser/i',$useragent)){
        $btitle = 'Nokia Browser';
    }elseif(preg_match('/OneBrowser/i',$useragent)){
        $btitle = 'OneBrowser';
    }elseif(preg_match('/Opera Mini/i',$useragent)){
        $btitle = 'Opera Mini';
    }elseif(preg_match('/Opera Mobi/i',$useragent)){
        $btitle = 'Opera Mobile';
    }elseif(preg_match('#Opera.([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'Opera';
        if(preg_match('/Edition ([\ .<em>0-9a-zA-Z]+)/i',$useragent,$regmatch)){
            $btitle .= ' '.$regmatch[1];
        }elseif(preg_match('/Opera ([\ ._0-9a-zA-Z]+)/i',$useragent,$regmatch)){
            $btitle .= ' '.$regmatch[1];
        }
    }elseif(preg_match('/SeaMonkey/i',$useragent)){
        $btitle = 'SeaMonkey';
    }elseif(preg_match('/Series60/i',$useragent)&&!preg_match('/Symbian/i',$useragent)){
        $btitle = 'Nokia Series60';
    }elseif(preg_match('/S60/i',$useragent)&&!preg_match('/Symbian/i',$useragent)){
        $btitle = 'Nokia S60';
    }elseif(preg_match('#SE 2([a-zA-Z0-9.]+)#i',$useragent,$matches)&&preg_match('/MetaSr/i',$useragent)){
        $btitle = 'Sogou Explorer';
    }elseif(preg_match('/Shiretoko/i',$useragent)){
        $btitle = 'Shiretoko';
    }elseif(preg_match('/SlimBrowser/i',$useragent)){
        $btitle = 'SlimBrowser';
    }elseif(preg_match('#SAMSUNG-(S.H-[a-zA-Z0-9</em>/.]+)#i',$useragent)){
        $btitle = "Samsung";
    }elseif(preg_match('/Songbird/i',$useragent)){
        $btitle = 'Songbird';
    }elseif(preg_match('/TheWorld/i',$useragent)){
        $btitle = 'TheWorld Browser';
    }elseif(preg_match('/Thunderbird/i',$useragent)){
        $btitle = 'Thunderbird';
    }elseif(preg_match('#TencentTraveler ([a-zA-Z0-9.]+)#i',$useragent)){
        $btitle = 'TT Explorer';
    }elseif(preg_match('/uBrowser/i',$useragent)&&!preg_match('/Chrome/i',$useragent)){
        $btitle = 'uBrowser';
    }elseif((preg_match('/Ubuntu\;\ Mobile/i',$useragent)||preg_match('/Ubuntu\;\ Tablet/i',$useragent)&&preg_match('/WebKit/i',$useragent))){
        $btitle = 'Ubuntu Web Browser';
    }elseif(preg_match('#UBrowser([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'UC Browser';
    }elseif(preg_match('#UCBrowser([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'UC Browser';
    }elseif(preg_match('#UC\ Browser([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'UC Browser';
    }elseif(preg_match('#UCWEB([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'UC Browser';
    }elseif(preg_match('/UltraBrowser/i',$useragent)){
        $btitle = 'UltraBrowser';
    }elseif(preg_match('/UP.Browser/i',$useragent)){
        $btitle = 'Openwave Mobile Browser';
    }elseif(preg_match('/UP.Link/i',$useragent)){
        $btitle = 'Openwave Mobile Browser';
    }elseif(preg_match('/AppleWebkit/i',$useragent,$matches)&&preg_match('/Android/i',$useragent)&&!preg_match('/Chrome/i',$useragent)){
        $btitle = 'Android Webkit';
    }elseif(preg_match('/WebExplorer/i',$useragent)){
        $btitle = 'Web Explorer';
    }elseif(preg_match('/Chrome/i',$useragent)&&preg_match('/Mobile/i',$useragent)&&(preg_match('/Version/i',$useragent)||preg_match('/wv/i',$useragent,$matches))){
        $btitle = 'WebView';
    }elseif(preg_match('/wp-android/i',$useragent)){
        $btitle = 'Wordpress App';
    }elseif(preg_match('/wp-blackberry/i',$useragent)){
        $btitle = 'wp-blackberry';
    }elseif(preg_match('/wp-iphone/i',$useragent)){
        $btitle = 'Wordpress App';
    }elseif(preg_match('/wp-nokia/i',$useragent)){
        $btitle = 'wp-nokia';
    }elseif(preg_match('/wp-webos/i',$useragent)){
        $btitle = 'wp-webos';
    }elseif(preg_match('/wp-windowsphone/i',$useragent)){
        $btitle = 'wp-windowsphone';
    }elseif(preg_match('/YaBrowser/i',$useragent)){
        $btitle = 'Yandex Browser';
    }elseif(preg_match('#Edge/([a-zA-Z0-9.]+)#i',$useragent,$matches)&&preg_match('/Chrome/i',$useragent)&&preg_match('/Safari/i',$useragent)){
        $btitle = 'Microsoft Edge';
    }elseif(preg_match('#Chrome/([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'Google Chrome';
}elseif(preg_match('/Safari/i',$useragent)&&!preg_match('/Nokia/i',$useragent)){
        $btitle = 'Safari';
    }elseif(preg_match('/Nokia/i',$useragent)){
        $btitle = 'Nokia Web Browser';
    }elseif(preg_match('#(Firefox|Phoenix|Firebird|BonEcho|GranParadiso|Minefield|Iceweasel)/([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = 'Firefox';
    }elseif(preg_match('#360([a-zA-Z0-9.]+)#i',$useragent,$matches)){
        $btitle = '360Safe Explorer';
    }elseif(preg_match('/baidubrowser/i',$useragent)){
        $btitle = 'Baidu Browser';
    }elseif(preg_match('/\ Spark/i',$useragent)){
        $btitle = 'Baidu Spark';
}elseif(preg_match('/MSIE/i',$useragent)||preg_match('/Trident/i',$useragent)){
        $btitle = 'Internet Explorer';
    }
    if(!$stitle){
        $stitle = 'Unknown System';
    }
    if(!$btitle){
        $btitle = 'Unknown Browser';
    }
    return $sver ?  $stitle.' '.$sver.' '.$btitle :  $stitle.' '.$btitle;
}

记录用户登录信息使用了hanada_user_login_message()函数,将其hook到wp_login之后,该函数将会在登录时被执行。

记录用户登录信息代码

function hanada_user_login_message($user_login)
{
    global $user_ID;
    date_default_timezone_set(PRC);  // 纠正8小时时差
    $current_user = get_user_by( 'login', $user_login );//获取当前登录信息
    $login_date = date('Y-m-d H:i:s');//获取登录时间
    $login_ip = $<em>SERVER['REMOTE_ADDR'];//获取登录IP
    $login_addr_arr = json_decode(@file_get_contents('https://freeapi.ipip.net/'.$login_ip),true);//使用接口获得登录IP对应地理位置json数组并解码为php数组
    $login_addr = $login_addr_arr[0].$login_addr_arr[1].$login_addr_arr[2].$login_addr_arr[3].$login_addr_arr[4];//拼接地理位置
    $login_ua = $_SERVER['HTTP_USER_AGENT'];//获取UA
    $login_type = '密码';//标记登录类型为使用密码登录
    //将登录记录写入用户表
    if(empty(get_user_meta($current_user->ID,'login_num', true))) {
        update_user_meta($current_user->ID, 'login_num', 1);
        $login_message_arr = array(
            'login_num_1' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_2' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_3' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_4' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_5' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_6' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_7' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            'login_num_8' => array( 'date' => '', 'ip' => '', 'addr' => '', 'ua' => '', 'type' => '' ),
            );
    }else if(get_user_meta($current_user->ID,'login_num', true) >= 8) {
        update_user_meta($current_user->ID, 'login_num', 1);
        $login_message_arr = get_user_meta($current_user->ID, 'login_message', true);
    }else {
        update_user_meta($current_user->ID, 'login_num', get_user_meta($current_user->ID,'login_num', true) + 1 );
        $login_message_arr = get_user_meta($current_user->ID, 'login_message', true);
    }
    $login_num = get_user_meta($current_user->ID,'login_num', true);
    $login_message_arr['login_num</em>'.$login_num]['date'] = $login_date;
    $login_message_arr['login_num_'.$login_num]['ip'] = $login_ip;
    $login_message_arr['login_num_'.$login_num]['addr'] = $login_addr;
    $login_message_arr['login_num_'.$login_num]['ua'] = $login_ua;
    $login_message_arr['login_num_'.$login_num]['type'] = $login_type;
    update_user_meta($current_user->ID, 'login_message', $login_message_arr);
}

add_action('wp_login','hanada_user_login_message');

登录信息记录好了,输出可以参考以下代码,由于无法从系统获得当前登录对应的记录,因此利用了登录时间和cookies过期时间来判断对应登录记录。这里利用短代码[login_message]来输出结果。

代码如下

function hanada_shotcode_login_message()
{
    //未登录时返回空值
    if (!is_user_logged_in()) {
        return null;
    }
    //获取登录记录信息
    $current_user = wp_get_current_user();
    $login_num = get_user_meta($current_user->ID,'login_num', true);
    $login_message_arr = get_user_meta($current_user->ID,'login_message', true);
    //正则替换隐藏IP地址后两位
    $login_ip_reg = '~(\d+).(\d+).(\d+).(\d+)~';
    //设置北京时间
    date_default_timezone_set("PRC");
    //获取当前cookie
    $cookie = wp_parse_auth_cookie( '', 'logged_in' );
    //获取当前账号sessions
    $sessions = wp_get_all_sessions();
    //格式化输出登录记录信息
    $login_message_table = '

<table class="login_message_table"><thead><tr>
            <th>时间</th>
            <th>IP地址</th>
            <th>地理位置</th>
            <th>登录设备</th>
            <th>登录方式</th>
        </tr></thead><tbody class="row-hover">';
    for( $i=$login_num; $i>0; $i-- ) {
        if(!empty($login_message_arr['login_num_'.$i]['date'])) {
            $login_message_table = $login_message_table.'
        <tr>
            <td class="login_message_date">'.$login_message_arr['login_num_'.$i]['date'].'</td>
            <td class="login_message_op">'.preg_replace($login_ip_reg, "$1.$2.*.*", $login_message_arr['login_num_'.$i]['ip']).'</td>
            <td class="login_message_addr">'.$login_message_arr['login_num_'.$i]['addr'].'</td>
            <td class="login_message_ua" title="'.$login_message_arr['login_num_'.$i]['ua'].'">'.clrs_get_user_agent($login_message_arr['login_num_'.$i]['ua']).'</td>
            <td class="login_message_type">'.$login_message_arr['login_num_'.$i]['type'];
            if( strtotime($login_message_arr['login_num_'.$i]['date']) == $cookie['expiration'] - 1209600 || strtotime($login_message_arr['login_num_'.$i]['date']) == $cookie['expiration'] - 172800){
                $login_message_table = $login_message_table.'<span class="current_session">当前登录</span></td></tr>';
            }else{
                $has_seesion = false;
                foreach($sessions as $value){
                    if( strtotime($login_message_arr['login_num_'.$i]['date']) == $value['login'] ){
                        $login_message_table = $login_message_table.'<span class="other_session">尚未登出</span></td></tr>';
                        $has_seesion = true;
                        break;
                    }
                }
                if( $has_seesion == false ) $login_message_table = $login_message_table.'<span class="loggedout_session">已经登出</span></td></tr>';
            }
        }
    }
    for( $i=8; $i>$login_num; $i-- ) {
        if(!empty($login_message_arr['login_num_'.$i]['date'])){
                $login_message_table = $login_message_table.'
        <tr>
            <td class="login_message_date">'.$login_message_arr['login_num_'.$i]['date'].'</td>
            <td class="login_message_ip">'.preg_replace($login_ip_reg, "$1.$2.*.*", $login_message_arr['login_num_'.$i]['ip']).'</td>
            <td class="login_message_addr">'.$login_message_arr['login_num_'.$i]['addr'].'</td>
            <td class="login_message_ua" title="'.$login_message_arr['login_num_'.$i]['ua'].'">'.clrs_get_user_agent($login_message_arr['login_num_'.$i]['ua']).'</td>
            <td class="login_message_type">'.$login_message_arr['login_num_'.$i]['type'];
            if( strtotime($login_message_arr['login_num_'.$i]['date']) === $cookie['expiration'] - 1209600 || strtotime($login_message_arr['login_num_'.$i]['date'] ) == $cookie['expiration'] - 172800){
                $login_message_table = $login_message_table.'<span class="current_session">当前登录</span></td></tr>';
            }else{
                $has_seesion = false;
                foreach($sessions as $value){
                    if( strtotime($login_message_arr['login_num_'.$i]['date']) == $value['login'] ){
                        $login_message_table = $login_message_table.'<span class="other_session">尚未登出</span></td></tr>';
                        $has_seesion = true;
                        break;
                    }
                }
                if( $has_seesion == false ) $login_message_table = $login_message_table.'<span class="loggedout_session">已经登出</span></td></tr>';
            }
        }
    }
    $login_message_table = $login_message_table.'</tbody></table>

';
    return $login_message_table;
}
add_shortcode('login_message', 'hanada_shotcode_login_message');

table表格的样式名为login_message_table,可根据自己需要使用CSS进行美化。

最终输出效果如下图(非本博客截图)
登录记录

其中当前登录是指目前查看这个登录记录表格者使用的Session对应的登录记录,尚未登出是指这一条登录记录目前未过期,已经登出是指这一条登录记录已经登出(注销)。登录方式中第三方账号登录相关内容因非WordPress自带功能因此没有说明,本站使用Open Social插件,可以对其加以修改来同样达到记录登录信息的目的。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注