Jump to content
IPS Community Suite 简体中文
Sign in to follow this  
ipscn

JWT Authentication for WP-API

Recommended Posts

JWT Authentication for WP-API 是一个别人写的免费的 WordPress 插件,本文记录它的使用。

JWT 的工作流

如下图所示jwt.png

 

.htaccess 配置

这里以 Apache 的 .htaccess 配置为例:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# Enable HTTP Auth
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
</IfModule>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# END WordPress

是的,你在好多地方可以搜索出上面的重写规则,它没有什么错误,问题是,一旦你在WordPress后台更改了固定链接规则,WordPress 就会重置这一段儿,所以最佳实践是,单独写出来:

# BEGIN WP BASIC Auth
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
</IfModule>
# END WP BASIC Auth

 

在某些情况下,上面的配置,客户端可以从服务器获取到 token,但是可能无法从客户端获取不到 header 中的 token,解决方案:

文件 class-jwt-auth-public.php 的 229行:

隐藏内容
回复可见

 

 

 

wp-config.php

添加两个常量

//是否启用 JWT AUTH
define('JWT_AUTH_CORS_ENABLE', true);
// JWT AUTH 密钥
define('JWT_AUTH_SECRET_KEY', '2+H_MtCG?8)kAPYV/iME-M44<og>5|G$EZJNB|<fUUZ>-kFb!3Y%H.F7k.Cu1+R2');

可在 https://api.wordpress.org/secret-key/1.1/salt/ 复制任何一个密钥进去。

测试

假如 WordPress 安装实例是 dev-wcapi.com,已有用户 admin, 密码是 admin :

curl -X POST  -d "username=admin&password=admin" http://dev-wcapi.com/wp-json/jwt-auth/v1/token

可看到返回示例如下:

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZXYtd2NhcGkuY29tIiwiaWF0IjoxNTI0Mjg2Nzk0LCJuYmYiOjE1MjQyODY3OTQsImV4cCI6MTUyNDg5MTU5NCwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.MarZlRxhpGxsx1CZ-yf07lH9Tjtx6whtHqwtKgFCR2c",
    "user_email": "suifengtec@qq.com",
    "user_nicename": "admin",
    "user_display_name": "admin"
}

验证用户 token:

curl  -X POST  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9kZXYtd2NhcGkuY29tIiwiaWF0IjoxNTI0Mjg2Nzk0LCJuYmYiOjE1MjQyODY3OTQsImV4cCI6MTUyNDg5MTU5NCwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.MarZlRxhpGxsx1CZ-yf07lH9Tjtx6whtHqwtKgFCR2c"  http://dev-wcapi.com/wp-json/jwt-auth/v1/token/validate

可见返回示例如下:

{
    "code": "jwt_auth_valid_token",
    "data": {
        "status": 200
    }
}

在客户端用JS对token进行解密

可以在客户端,使用JS对服务器返回的,或者本地存储的token进行解密,如上面的token,可以解密为:

{
    "iss":"http://dev-wcapi.com",
    "iat":1524286794,
    "nbf":1524286794,
    "exp":1524891594,
    "data":{
        "user":{
            "id":"1"
        }
    }
}

 

以上各个键的含义:

iss:   Issuer,签发者;
sub:  Subject,所面向的用户;
aud:  Audience, 接收方;
exp:  Expiration time, 过期时间,这个过期时间必须要大于签发时间;
nbf:  Not before, 定义在什么时间之前,该JWT都是不可用的;
iat:   Issued at, 签发时间;
jti:    JWT ID, 唯一身份标识,主要用来作为一次性token,从而回避重放攻击.

关键JS代码:

https://app5.coolwp.org/tools/jwt/token/

 

模块化后,适用于微信小程序的解密脚本:

    /*
     解密JWT Token.以处理过期的问题。
     */
    decryptToken: function(app, token) {
        let that = this;
        if (!token || token.length < 1) {
            console.log('decrypt 没有获取到token');
            return false;
        }
        let base64Url = token.split('.')[1];
        let base64 = base64Url.replace('-', '+').replace('_', '/');
        let tokenDataObj = JSON.parse(atob(base64));
        console.log(tokenDataObj);

        if (!tokenDataObj || !tokenDataObj.iss) {
            return false;
        }
        let dataTxt = JSON.stringify(tokenDataObj);

        //   let now = Math.floor(Date.now() / 1000);
		let now = Math.ceil(Date.now() / 1000);

        let isExpired = now > tokenDataObj.exp;

        if (isExpired) {

            //需要重新登录

            let unionId = wx.getStorageSync('unionId');

            unionId && that.tryAutoLogin(app, unionId) && app.onLoad();


        } else {

            return {
                iss: tokenDataObj.iss,
                userId: tokenDataObj.data.user.id,
                exp: tokenDataObj.exp
            };

        }

    },
         tryAutoLogin:function(app,unionId){
           //自动登录处理

    }

 

 

JWT 的构成

header.payload.signature

它由加密后的header,有效数据,签名三部分构成,三个部分,以半角英文句号隔开。

由于JWT只进行签名和编码,但是JWT不进行可靠的加密,只对有效数据进行了base64编码,所以,使用JWT不保证敏感数据在传输时的任何安全性。由于前述原因,为了防止JWT在传输中被不法窃取,应在鉴权服务器上和应用服务器上使用 HTTPS 连接。

 

用户注册/找回密码/更新

请参考我在这个 issue 的回答: https://github.com/Tmeister/wp-api-jwt-auth/issues/50#issuecomment-383271120

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×