Coder Social home page Coder Social logo

jwt-auth's Introduction

JWT Auth

WordPress JWT (JSON Web Token) Authentication allows you to do REST API authentication via token. It's a simple, non-complex, and easy to use.

This plugin probably is the most convenient way to do JWT Authentication in WordPress. Download it from WordPress plugin page.

Requirements

PHP

Minimum PHP version: 7.2

Enable PHP HTTP Authorization Header

Shared Hosts

Most shared hosts have disabled the HTTP Authorization Header by default.

To enable this option you'll need to edit your .htaccess file by adding the following:

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

WPEngine

To enable this option you'll need to edit your .htaccess file by adding the following (see this issue):

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

Installation

Through the WordPress Administrative Area:

  • From WordPress administrative area, go to Plugins -> Add New
  • Search for JWT Auth
  • Install it
  • Easily configure it (see Configuration below)
  • and then activate it

Download Manually:

  • Download the plugin from WordPress plugins page
  • Upload to your wp-content directory
  • Easily configure it (see Configuration below)
  • Activate it from Plugins menu in admin area

Configuration

Configurate the Secret Key

The JWT needs a secret key to sign the token. It must be unique and never be revealed.

To add the secret key, edit your wp-config.php file and add a new constant called JWT_AUTH_SECRET_KEY.

define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');

You can use a string from here https://api.wordpress.org/secret-key/1.1/salt/

Configurate CORs Support

This plugin has the option to enable CORs support.

To enable the CORs Support edit your wp-config.php file and add a new constant called JWT_AUTH_CORS_ENABLE

define('JWT_AUTH_CORS_ENABLE', true);

Finally activate the plugin within the plugin dashboard.

Namespace and Endpoints

When the plugin is activated, a new namespace is added.

/jwt-auth/v1

Also, three new endpoints are added to this namespace.

Endpoint HTTP Verb
/wp-json/jwt-auth/v1/token POST
/wp-json/jwt-auth/v1/token/validate POST
/wp-json/jwt-auth/v1/token/refresh POST

Requesting/ Generating Token

/wp-json/jwt-auth/v1/token

To generate token, submit a POST request to this endpoint. With username and password as the parameters.

It will validates the user credentials, and returns success response including a token if the authentication is correct or returns an error response if the authentication is failed.

You can use the optional parameter device with the device identifier to let user manage the device access in your profile. If this parameter is empty, it is ignored.

Sample of success response when trying to generate token:

{
	"success": true,
	"statusCode": 200,
	"code": "jwt_auth_valid_credential",
	"message": "Credential is valid",
	"data": {
		"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcG9pbnRzLmNvdXZlZS5jby5pZCIsImlhdCI6MTU4ODQ5OTE0OSwibmJmIjoxNTg4NDk5MTQ5LCJleHAiOjE1ODkxMDM5NDksImRhdGEiOnsidXNlciI6eyJpZCI6MX19fQ.w3pf5PslhviHohmiGF-JlPZV00XWE9c2MfvBK7Su9Fw",
		"id": 1,
		"email": "[email protected]",
		"nicename": "contactjavas",
		"firstName": "Bagus Javas",
		"lastName": "Heruyanto",
		"displayName": "contactjavas"
	}
}

Sample of error response when trying to generate token:

{
	"success": false,
	"statusCode": 403,
	"code": "invalid_username",
	"message": "Unknown username. Try again or check your email address.",
	"data": []
}

Once you get the token, you must store it somewhere in your application. It can be:

  • using cookie
  • or using localstorage
  • or using a wrapper like localForage or PouchDB
  • or using local database like SQLite or Hive
  • or your choice based on app you develop ;)

Then you should pass this token as Bearer Authentication header to every API call. The header format is:

Authorization: Bearer your-generated-token

and here's an example:

"Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcG9pbnRzLmNvdXZlZS5jby5pZCIsImlhdCI6MTU4ODQ5OTE0OSwibmJmIjoxNTg4NDk5MTQ5LCJleHAiOjE1ODkxMDM5NDksImRhdGEiOnsidXNlciI6eyJpZCI6MX19fQ.w3pf5PslhviHohmiGF-JlPZV00XWE9c2MfvBK7Su9Fw";

The jwt-auth will intercept every call to the server and will look for the authorization header, if the authorization header is present, it will try to decode the token and will set the user according with the data stored in it.

If the token is valid, the API call flow will continue as always.

Validating Token

You likely don't need to validate the token your self. The plugin handle it for you like explained above.

But if you want to test or validate the token manually, then send a POST request to this endpoint (don't forget to set your Bearer Authorization header):

/wp-json/jwt-auth/v1/token/validate

Valid Token Response

{
	"success": true,
	"statusCode": 200,
	"code": "jwt_auth_valid_token",
	"message": "Token is valid",
	"data": []
}

Refreshing the Access Token

For security reasons, third-party applications that are integrating with your authentication server will not store the user's username and password. Instead they will store the refresh token in a user-specific storage that is only accessible for the user. The refresh token can be used to re-authenticate as the same user and generate a new access token.

When authenticating with username and password as the parameters to /wp-json/jwt-auth/v1/token, a refresh token is sent as a cookie in the response.

/wp-json/jwt-auth/v1/token

To generate new access token using the refresh token, submit a POST request to the token endpoint together with the refresh_token cookie.

Use the optional parameter device with the device identifier to associate the token with that device.

If the refresh token is valid, then you receive a new access token in the response.

By default, each access token expires after 10 minutes.

/wp-json/jwt-auth/v1/token/refresh

To generate new refresh token using the refresh token, submit a POST request to the token refresh endpoint together with the refresh_token cookie.

Use the optional parameter device with the device identifier to associate the refresh token with that device.

If the refresh token is valid, then you receive a new refresh token as a cookie in the response.

By default, each refresh token expires after 30 days.

Refresh Token Rotation

Whenever you are authenticating afresh or refreshing the refresh token, only the last issued refresh token remains valid. All previously issued refresh tokens can no longer be used.

This means that a refresh token cannot be shared. To allow multiple devices to authenticate in parallel without losing access after another device re-authenticated, use the parameter device with the device identifier to associate the refresh token only with that device.

curl -F device="abc-def" -F username=myuser -F password=mypass /wp-json/jwt-auth/v1/token
curl -F device="abc-def" -b "refresh_token=123.abcdef..." /wp-json/jwt-auth/v1/token
curl -F device="abc-def" -b "refresh_token=123.abcdef..." /wp-json/jwt-auth/v1/token/refresh

Error Responses

If the token is invalid an error will be returned. Here are some samples of errors:

No Secret Key

{
	"success": false,
	"statusCode": 500,
	"code": "jwt_auth_bad_config",
	"message": "JWT is not configured properly.",
	"data": []
}

No HTTP_AUTHORIZATION Header

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_no_auth_header",
	"message": "Authorization header not found.",
	"data": []
}

Bad Iss

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_bad_iss",
	"message": "The iss do not match with this server.",
	"data": []
}

Invalid Signature

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_invalid_token",
	"message": "Signature verification failed",
	"data": []
}

Incomplete Payload

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_bad_request",
	"message": "User ID not found in the token.",
	"data": []
}

User Not Found

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_user_not_found",
	"message": "User doesn't exist",
	"data": []
}

Expired Token

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_invalid_token",
	"message": "Expired token",
	"data": []
}

Obsolete Token

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_obsolete_token",
	"message": "Token is obsolete",
	"data": []
}

Invalid Refresh Token

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_invalid_refresh_token",
	"message": "Invalid refresh token",
	"data": []
}

Obsolete Refresh Token

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_obsolete_refresh_token",
	"message": "Refresh token is obsolete",
	"data": []
}

Expired Refresh Token

{
	"success": false,
	"statusCode": 401,
	"code": "jwt_auth_expired_refresh_token",
	"message": "Refresh token has expired",
	"data": []
}

Available Filter Hooks

JWT Auth is developer friendly and has some filters available to override the default settings.

jwt_auth_cors_allow_headers

The jwt_auth_cors_allow_headers allows you to modify the available headers when the CORs support is enabled.

Default Value:

'X-Requested-With, Content-Type, Accept, Origin, Authorization'

Usage example:

/**
 * Change the allowed CORS headers.
 *
 * @param string $headers The allowed headers.
 * @return string The allowed headers.
 */
add_filter(
	'jwt_auth_cors_allow_headers',
	function ( $headers ) {
		// Modify the headers here.
		return $headers;
	}
);

jwt_auth_authorization_header

The jwt_auth_authorization_header allows you to modify the Authorization header key used to validating a token. Useful when the server already uses the 'Authorization' key for another auth method.

Default value:

'HTTP_AUTHORIZATION'

Usage example:

/**
 * Modify the response of Authorization header key.
 *
 * @param string $header The Authorization header key.
 * .
 * @return string The Authorization header key.
 */
add_filter(
	'jwt_auth_authorization_header',
	function ( $header ) {
		// Modify the response here.
		return $header;
	},
	10,
	1
);

jwt_auth_iss

The jwt_auth_iss allows you to change the iss value before the payload is encoded to be a token.

Default Value:

get_bloginfo( 'url' )

Usage example:

/**
 * Change the token issuer.
 *
 * @param string $iss The token issuer.
 * @return string The token issuer.
 */
add_filter(
	'jwt_auth_iss',
	function ( $iss ) {
		// Modify the "iss" here.
		return $iss;
	}
);

jwt_auth_not_before

The jwt_auth_not_before allows you to change the nbf value before the payload is encoded to be a token

Default Value:

// Creation time.
time()

Usage example:

/**
 * Change the token's nbf value.
 *
 * @param int $not_before The default "nbf" value in timestamp.
 * @param int $issued_at The "iat" value in timestamp.
 *
 * @return int The "nbf" value.
 */
add_filter(
	'jwt_auth_not_before',
	function ( $not_before, $issued_at ) {
		// Modify the "not_before" here.
		return $not_before;
	},
	10,
	2
);

jwt_auth_expire

The jwt_auth_expire allows you to change the exp value before the payload is encoded to be a token

Default Value:

time() + (MINUTE_IN_SECONDS * 10)

Usage example:

/**
 * Change the token's expire value.
 *
 * @param int $expire The default "exp" value in timestamp.
 * @param int $issued_at The "iat" value in timestamp.
 *
 * @return int The "nbf" value.
 */
add_filter(
	'jwt_auth_expire',
	function ( $expire, $issued_at ) {
		// Modify the "expire" here.
		return $expire;
	},
	10,
	2
);

jwt_auth_refresh_expire

The jwt_auth_refresh_expire filter hook allows you to change the expiration date of the refresh token.

Default Value:

time() + (DAY_IN_SECONDS * 30)

Usage example:

/**
 * Change the refresh token's expiration time.
 *
 * @param int $expire The default expiration timestamp.
 * @param int $issued_at The current time.
 *
 * @return int The custom refresh token expiration timestamp.
 */
add_filter(
	'jwt_auth_refresh_expire',
	function ( $expire, $issued_at ) {
		// Modify the "expire" here.
		return $expire;
	},
	10,
	2
);

jwt_auth_alg

The jwt_auth_alg allows you to change the supported signing algorithm for your application.

Default Value:

'HS256'

Usage example:

/**
 * Change the token's signing algorithm.
 *
 * @param string $alg The default supported signing algorithm.
 * @return string The supported signing algorithm.
 */
add_filter(
	'jwt_auth_alg',
	function ( $alg ) {
		// Change the signing algorithm here.
		return $alg;
	}
);

jwt_auth_payload

The jwt_auth_payload allows you to modify all the payload / token data before being encoded and signed.

Default value:

<?php
$token = array(
    'iss' => get_bloginfo('url'),
    'iat' => $issued_at,
    'nbf' => $not_before,
    'exp' => $expire,
    'data' => array(
        'user' => array(
            'id' => $user->ID,
        )
    )
);

Usage example:

/**
 * Modify the payload/ token's data before being encoded & signed.
 *
 * @param array $payload The default payload
 * @param WP_User $user The authenticated user.
 * .
 * @return array The payload/ token's data.
 */
add_filter(
	'jwt_auth_payload',
	function ( $payload, $user ) {
		// Modify the payload here.
		return $payload;
	},
	10,
	2
);

jwt_auth_valid_credential_response

The jwt_auth_valid_credential_response allows you to modify the valid credential response when generating a token.

Default value:

<?php
$response = array(
    'success'    => true,
    'statusCode' => 200,
    'code'       => 'jwt_auth_valid_credential',
    'message'    => __( 'Credential is valid', 'jwt-auth' ),
    'data'       => array(
        'token'       => $token,
        'id'          => $user->ID,
        'email'       => $user->user_email,
        'nicename'    => $user->user_nicename,
        'firstName'   => $user->first_name,
        'lastName'    => $user->last_name,
        'displayName' => $user->display_name,
    ),
);

Usage example:

/**
 * Modify the response of valid credential.
 *
 * @param array $response The default valid credential response.
 * @param WP_User $user The authenticated user.
 * .
 * @return array The valid credential response.
 */
add_filter(
	'jwt_auth_valid_credential_response',
	function ( $response, $user ) {
		// Modify the response here.
		return $response;
	},
	10,
	2
);

jwt_auth_valid_token_response

The jwt_auth_valid_token_response allows you to modify the valid token response when validating a token.

Default value:

<?php
$response = array(
	'success'    => true,
	'statusCode' => 200,
	'code'       => 'jwt_auth_valid_token',
	'message'    => __( 'Token is valid', 'jwt-auth' ),
	'data'       => array(),
);

Usage example:

/**
 * Modify the response of valid token.
 *
 * @param array $response The default valid token response.
 * @param WP_User $user The authenticated user.
 * @param string $token The raw token.
 * @param array $payload The token data.
 * .
 * @return array The valid token response.
 */
add_filter(
	'jwt_auth_valid_token_response',
	function ( $response, $user, $token, $payload ) {
		// Modify the response here.
		return $response;
	},
	10,
	4
);

jwt_auth_extra_token_check

The jwt_auth_extra_token_check allows you to add extra criterias to validate the token. If empty, has no problem to proceed. Use empty value to bypass the filter. Any other value will block the token access and returns response with code jwt_auth_obsolete_token.

Default value:

''

Usage example:

/**
 * Modify the validation of token. No-empty values block token validation.
 *
 * @param array $response An empty value ''.
 * @param WP_User $user The authenticated user.
 * @param string $token The raw token.
 * @param array $payload The token data.
 * .
 * @return array The valid token response.
 */
add_filter(
	'jwt_auth_extra_token_check',
	function ( $response, $user, $token, $payload ) {
		// Modify the response here.
		return $response;
	},
	10,
	4
);

Automated Tests

There are end-to-end tests you can run to confirm that the API works correctly:

$ URL=https://example.local USERNAME=myuser PASSWORD=mypass composer run test
> ./vendor/bin/phpunit
PHPUnit 9.5.13 by Sebastian Bergmann and contributors.

.............                                                     13 / 13 (100%)

Time: 00:12.377, Memory: 6.00 MB

OK (13 tests, 110 assertions)

Credits

License

GPL-3.0 License

Keep This Plugin Alive & Maintained

You can help us to keep this plugin alive and continue to maintain it by:

Thank You!

jwt-auth's People

Contributors

bradmkjr avatar cedricdevwp avatar chaoste avatar contactjavas avatar dominic-ks avatar fabrizim avatar lxbdr avatar pesseba avatar psaikali avatar rhurling avatar sun avatar tousdan avatar wavedeck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jwt-auth's Issues

Request Header missing authorization

When i try to edit the saved page in the admin, it reports an error

request:

POST /wp-json/batch/v1?_locale=user HTTP/1.1
Host: ******.com
Connection: keep-alive
Content-Length: 330
sec-ch-ua: "Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"
DNT: 1
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
Content-Type: application/json
Accept: application/json, */*;q=0.1
X-WP-Nonce: 0dbb6db3fa
sec-ch-ua-platform: "macOS"
Origin: https://******.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://******.com/wp-admin/widgets.php
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: _ga=GA1.1.1406211796.1631495409; session_prefix=c446c69889d033af4e30307fffbf410b; __gads=ID=aabf2a2960bd4f18-22a58ecf9bcb006c:T=1631495410:RT=1631495410:S=ALNI_MbUylNOr3FHGSEUaOClC6ggaVMCYw; Hm_lvt_0632da004bdbc2cf30e83e362fbe3e19=1631261645,1632273780; wordpress_logged_in_684baaaad6781cc40e3eb2fe5df7a5c8=angrycat123%7C1633576138%7C21580mOAIXzlgdW5xmmFee1Wp2A1WQ3jzJfqLO9zpev%7C4a389108aadc4fcdcbe035631907c999d201da6e0cdb0321adae232de1d7e9e0; wp-settings-1=mfold%3Do%26libraryContent%3Dbrowse; wp-settings-time-1=1632366560; wpcom_panel_nav=0; _ga_ELRHFLW13Q=GS1.1.1632373877.12.1.1632378536.0; Hm_lpvt_0632da004bdbc2cf30e83e362fbe3e19=1632378536

response:

code: "jwt_auth_no_auth_header"
data: []
message: "Authorization header not found."
statusCode: 403
success: false

Authorization Header conflicts with protected sites

Hi, the HTTP_AUTHORIZATION header can conflict with page protection header parameter, like in WPEngine hosting, per example. This kind of page protection is usefull for sites under construction, staging and development environments with no external access.
Please, could you create a filter to change the header key used. Something like this:

$headerkey = apply_filters('jwt_auth_authorization_header', 'HTTP_AUTHORIZATION'); $auth = isset( $_SERVER[$headerkey] ) ? $_SERVER[$headerkey] : false;

Whitelist Woocommerce Default Endpoints

Hey guys, great plugin. I'm having an issue where all the Woocommerce default endpoints that are whitelisted by default in your plugin are being blocked? We're on NGINX if that matters and still having the issue after disabling plugins. I tried manually adding them to the whitelist with my other custom URL's that do work and no luck. Have you come across this?

Cannot destructure property 'isEnabled' of 'Object(...)(...)' as it is undefined.

Conflict with Elementor

Hi,

there has a problem with your plugin and Elementor when i active JWT, i can’t preselect color from global in builder of Elementor.

Can you correct this ? or have you an idea to solve this problem ?

Cédric

how to add custom rest api routes via single plugin file?

Hi

i have created a single file plugin and named it as jwt-auth-routes and upload it into plugins directory of wordpress and finally activate the plugin through wordpress admin panel but my custom routes returns 403 with message "JWT is not configurated properly."

my plugin information:

plugin file name: jwt_auth_routes.php

code:

/**
* wordpress comments and plugin name & etc.
*/

defined( 'ABSPATH' ) || die( "Can't access directly" );

$routes = [
	'/wp-json/hm/v1/*'
];

add_filter( 'jwt_auth_whitelist', function ( $endpoints ) {
	
    return $routes;
	
});

BUT IT's NOT WORKING. the other routes such as /token and /token/validate are working and the generated token is valid.

please help me.

Wrong HTTP Code when no Authorization header is passed

Current behavior :
When using a protected route, if no Authorization header is passed, we get a success response with code 200 with an error body :

{
	"success": false,
	"statusCode": 403,
	"code": "jwt_auth_no_auth_header",
	"message": "Authorization header not found.",
	"data": []
}

Expected behavior :
When using a protected route, if no Authorization header is passed, we should get an error with a 403 HTTP Status code.

Fix :
Use the second constructor argument when instanciating WP_REST_Response() in class-auth.php at line 293 to send an actual 403 Response.

if ( ! $auth ) {
	return new WP_REST_Response(
		array(
			'success'    => false,
			'statusCode' => 403,
			'code'       => 'jwt_auth_no_auth_header',
			'message'    => $this->messages['jwt_auth_no_auth_header'],
			'data'       => array(),
		),
		403 // add the actual status code here
	);
}

Login from a mobile app with a token as a param

Hello,

Thanks for the plugin.
I am using the rest api in a mobile app and I want to generate a link to the website with the token as param and redirect the user to it.
I wonder how can I auto login in the website with the token, is there a hook to call and pass the token to it to connect the user automatically ?

Thanks

Plugin causing Javascript issues on other plugins

I have some troubles with 'jwt-auth' on my website using Theme X.

When I try to open the Theme X editor (/x/theme-options), it fails with the followings javascript errors :

In one picture :
image

Here is the text :

app.514eb0c.js:42 

Failed to inflate gzip data buffer error
app.514eb0c.js:42 

TypeError: Cannot read property 'groups' of undefined
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at db (app.514eb0c.js:42)
react-dom.min.js?ver=16.13.1:125 

TypeError: Cannot read property 'reduce' of undefined
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at Ia (app.514eb0c.js:42)
    at app.514eb0c.js:42
    at app.514eb0c.js:42
    at Object.useMemo (react-dom.min.js?ver=16.13.1:216)
app.514eb0c.js:42 

Uncaught (in promise) TypeError: Cannot read property 'reduce' of undefined
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at app.514eb0c.js:42
    at r (lodash.min.js?ver=4.17.19:88)
    at Ia (app.514eb0c.js:42)
    at app.514eb0c.js:42
    at app.514eb0c.js:42
    at Object.useMemo (react-dom.min.js?ver=16.13.1:216)

I seems that is a mess in the javascript resources ! I desactivated all others plugins on my website and only 'jwt-auth' is causing this issue.

app.514eb0c.js is a static file from Cornerstone, a plugin used by Theme X to edit pages. The location is : /www/wp-content/plugins/cornerstone/assets/dist/js

Is anything the plugin trying to minify or uglify ? Is there a dependencies conflict (lodash ? react ?) ?
I looked at the plugin's code but I'm not really good in PHP ^^

Any idea ?

Thanks !

How to enable HTTP Authorization Header on the Nginx server?

I am trying to configure JWT Authentication for WordPress REST API. But the problem is there is no direct config available for enabling the HTTP Authorization Header. Nginx doesn't have a .htaccess file, so I can't add the rewrite rules.

Here are the rules for apache based server:

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

I believe it's not going to work with Nginx. What is the solution available for the Nginx side?

CORS Issue

Hi,

I installed the plugin on a new clean Wordpress on localhost environment.
I am trying to create a login via local React app and get CORS errors.
I understand the reason but do you know how can I get through it?

htaccess
image

wp-config
image

wp-admin
image

react call
image

error
image

request
image

Thanks,
Daniel

Dependencies are not locked

The composer.lock file should also be committed though; otherwise every new invocation of composer install will install a different version of the JWT library.

Originally posted by @sun in #33 (comment)

Output user data from custom endpoint

Hi

I am probably missing something obvious by how to I get the user data of an authenticated user in a custom endpoint?

function get_user_data( $response ) {

	// HOW DO I OUTPUT USER DATA HERE?
	error_log(print_r($response, true));
 
  	return 'User';
}


add_action( 'rest_api_init', function () {
  register_rest_route( 'access/v1', '/content/(?P<id>\d+)', array(
    'methods' => 'GET',
    'callback' => 'get_user_data',
    'args' => array(
      'id' => array(
        'validate_callback' => function($param, $request, $key) {
          return is_numeric( $param );
        }
      ),
    ),
  ) );
} );

It is validating successful and I am getting the response but I am not sure how to parse the token to get the user data?

I know with another plugin you do this.

$user = JWTAuth::parseToken()->authenticate()

Thanks

Using the plugin with WordPress installed in a sub-directory

Hi @contactjavas

With my team, we found out where the problem (https://wordpress.org/support/topic/whitelisting-token-generation-endpoint/) came from. It is due to our custom installation with WordPress in a sub-directory (https://wordpress.org/support/article/giving-wordpress-its-own-directory/).

To make it work in this case too,

if ( '/' . $this->rest_api_slug . '/jwt-auth/v1/token' !== $request_uri ) {

should be

if ( home_url('/' . $this->rest_api_slug,'relative') . '/jwt-auth/v1/token' !== $request_uri ) {

Wrong repo link on packagist

The package on packagist (link) uses ogabrielaraujo instead of usefulteam, which results in a 404 when downloading the package via composer.

Breaks Rankmath

This plugin breaks Rankmath SEO plugin.

Makes you unable to set focus keywords or update snippet settings on a per post basis.

Any possible fixes?

Device parameter is not parsed from request body if sent with 'content-type: json'.

Discovered during #33

Problem

  • When sending REST parameters as a JSON object together with a Content-Type: json instead of multipart/form-data, then the device parameter is not handled; i.e., the device is not registered and does not appear in the user account.

Cause

  • The code directly accesses $_POST['device'] instead of retrieving the request parameter from WP_REST_Request.

register_rest_route was called incorrectly

Since latest version 5.5 I am now getting error:

{"type":1024,"message":"register_rest_route was called <strong>incorrectly&lt;\/strong&gt;. The REST API route definition for <code>jwt-auth\/v1\/token&lt;\/code&gt; is missing the required <code>permission_callback&lt;\/code&gt; argument. For REST API routes that are intended to be public, use <code>__return_true&lt;\/code&gt; as the permission callback. Please see <a href="https:\/\/wordpress.org\/support\/article\/debugging-in-wordpress\/">Debugging in WordPress&lt;\/a&gt; for more information. (This message was added in version 5.5.0.)","file":"\/Users\/me\/Projects\/project\/wp-includes\/functions.php","line":5225}

Whitelist route and method http

Hi,

It's possible to whitelist route and method http ?

for example :

GET /users => No whitelist
POST /users => Whitelist

if this is not possible, is it possible to consider implementing this feature?

Thx,
Cédric

UI / option page in admin area

Hi Guys, is it a good idea to have a UI in the admin area to allow people to whitelist some endpoints / maybe modify the default whitelisted endpoints?

Sure, we have some filters. But seems like it's quite often people come with issues like "x or y or z" plugins don't work (due to blocked request).
And then we suggest using a filter to solve that, and then they ask where to put the codes.

Not sure if an options page in the admin area is necessary, but what do you think?

Fatal error on plugin activation

Not sure why this is happening as there is no additional error.

I am trying to set up JWT Auth on a local docker container and I cannot seem to activate the plugin. I get the following error message:

screenshot-localhost_9998-2020 09 11-11_14_56

I am able to install and activate other plugins so I wondering what the reason is. I am using WP 5.5.1

Any help is appreciated.

2.0 - Error "Token is obsolete" with "password changed"

Hello,

Since the update I have problems with the validation of the JWT token.

In class-auth.php when apply filter "jwt_auth_extra_token_check" in line 391, i have a payload with
object(stdClass)#897 (1) { [ "user" ]=> object(stdClass)#896 (1) { [ "id" ]=> int(35) } }

And so, i don't have "$payload->data->user->pass" in file "class-devices.php" line 99.

do you have any advice to solve my problem?

Contact form 7 not working when JWT is active

When submitting a contact form I get an error in the console
when I deactivate the plugin it starts working again I tried uninstalling and reinstalling the actual plugin functionality is working fine I am able to login using the API has anyone else had the same problem?
I have left the Plugin activated if you need more info on the error just submit the form at the bottom of the home page https://chocolatebash.com/careers/

Uncaught TypeError: Cannot read property ‘replace’ of undefined

Allow to emit the refresh token in the response body instead of a cookie

Follow-up on #1 (comment)

Goal

  • Add an option or constant to emit the refresh token in the response body instead of a cookie.

Details

  • For security reasons with regard to web/browser clients, #33 implemented the refresh token only as a cookie.
  • In cases where no web (browser) apps are involved (e.g. only native apps), it would be secure to emit the refresh token as part of the token response body.

Notes

  • I have no use-case for this myself, so I will probably not implement it myself. PRs are welcome though.

Not able to use wp_verify_nonce in jwt_auth_whitelist filter

Trying to use wp_verify_nonce in jwt_auth_whitelist filter results in infinite loop in function calls. The plugin adds determine_current_user filter, and wp_verify_nonce also uses this.

PHP Fatal error:  Uncaught Error: Maximum function nesting level of '256' reached, aborting! in /Project/wp-includes/class-wp-hook.php:287
Stack trace:
#0 /Project/wp-includes/class-wp-hook.php(287): array_keys(Array)
#1 /Project/wp-includes/plugin.php(189): WP_Hook->apply_filters('user', Array)
#2 /Project/wp-includes/formatting.php(2124): apply_filters('sanitize_user', 'user', 'user', false)
#3 /Project/wp-includes/class-wp-user.php(231): sanitize_user('user')
#4 /Project/wp-includes/pluggable.php(105): WP_User::get_data_by('login', 'user')
#5 /Project/wp-includes/pluggable.php(707): get_user_by('login', 'user')
#6 /Project/wp-includes/class-wp-hook.php(303): wp_validate_auth_cookie(false)
#7 /Project/wp in /Project/wp-includes/class-wp-hook.php on line 287

Invalidate token.

Hi,

is there any endpoint or a function that I can call and invalidate the token ? let's say the logout function for Example.

Compatible with Basic Authentication

When enabled, I see if the request header come with Basic Authorization (WC using it), the plugin throw an error jwt_auth_bad_auth_header. Could we make it no error so that other plugins can work with other authentications?

Throwing jwt_auth_no_auth_header in this case is a good idea?

Not able to update images through admin login while plugin is active

On Wordpress site with NewspaperX theme.

Description:
Not able to update the inline content ad or add a new element to the page with TagDiv editor while this plugin is active.
Checking chrome console provides with this info

code: "jwt_auth_no_auth_header"
data: []
message: "Authorization header not found."
statusCode: 403
success: false

TagDiv editor is opened only after logging in at example.com/wp-admin/ by manually entering username and password.

Expected behaviour:
Jwt request should not be send as user is already authenticated and logged in.

Possible solutions:

  • Only check for authorization header for requests to rest api endpoints.
  • Add some sort of filter to filter out requests send from site itself, like the case here.

If there is already a fix for this, please do let me know!

Shared hosting 403 jwt_auth_bad_config with $auth = $_SERVER['HTTP_AUTHORIZATION'] mod

Edit: Using version 2.1 installed from Wordpress admin
After adding
RewriteEngine on RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
I manage to have
isset($headers['Authorization']) = 1 var_dump($headers['Authorization']) = string(0) "" isset($_SERVER['HTTP_AUTHORIZATION']) = 1
but nothing for
isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) =

  1. I can create a token
  2. I can validate it with axios
  3. I have a 403 'jwt_auth_bad_config' when I try to GET a custom api with the token and axios

Edit2: I tried the github version 3.0 and still same problem. Cookie refresh returns 'JWT is not configured properly.'
Edit3: It's weird, it seems it can read JWT_AUTH_SECRET_KEY on the first 2 steps (I was able to send it in json response to test) but on line 392 of class-auth.php it's empty...

Who manages the plugin on WordPress.org

Probably a question for @contactjavas, but just noting your recent comments that you haven't much time for this repo at present, I may be interested in becoming more active and I'm a heavy user of this plugin, but wanted to know who manages it on WordPress.org?

I seem to remember a while ago there was a Discord or Slack for this as well? Or am I making that up?

Whitelisting isn't implemented at all?

Hello,

We're using this plugin (v1.2.6), and it mentions in the documentation of adding a whitelist filter:

add_filter( 'jwt_auth_whitelist', function ( $endpoints ) { return array(...); });

However, I've implemented this, and after looking into why it wasn't working, it seems that this filter isn't called anywhere whatsoever in the plugin code, nor is the word 'whitelist' mentioned anywhere in the code. So is this not implemented within the plugin at all, or are we to use it differently or manually ourselves?

I tried moving the filter definition around to the beginning of the initialization code, as the documentation suggests, but it still doesn't seem to do anything.

I had to implemented my own whitelisting logic in the class-jwt-auth-public.php determine_current_user function.

Former token generated still works as auth bearer token

I thought that if you create a new token then a previously generated token would no longer work?

wp-json/jwt-auth/v1/token -> old token

wp-json/wp/v2/users/me bearer: old token -> "200 ok"

wp-json/jwt-auth/v1/token -> new token

wp-json/wp/v2/users/me bearer: new token -> "200 ok"

wp-json/wp/v2/users/me bearer: old token -> "200 ok"

Is this intensional?
I'm using Postman to test this, though I assume that is not relevant.
jwt-auth Version: 2.1.0

Whitelist not working

Not sure if I am doing something wrong here but I can't get the whitelist function to work. I have tried it in functions.php and in a plugin but I still get a 403 error.

Basic example:

add_filter( 'jwt_auth_whitelist', function ( $endpoints ) {
	return array(
		'/wp-json/custom/v1/*',
	);
} );


function hello_world( $data ) {
	return 'Hello World';
}

add_action( 'rest_api_init', function () {
	register_rest_route( 'custom/v1', 'test', array(
		'methods'  => 'GET',
		'callback' => 'hello_world',
	) );
} );

Empty response

Something broke with jwt-auth.

When I do POST https://{{host}}/wp-json/jwt-auth/v1/token with username, password or even blank credentials it takes around 1 minute and I get a 504 Gateway Time-out response back.

There are no logs or anything.

Wordpress 5.7.2
PHP 7.4

Error: Authorization header malformed.

I followed your documentation and I can generate the token. But the generated token is not working 😥

image

I got a response like this when I tried to use generated token.

{
    "success": false,
    "statusCode": 403,
    "code": "jwt_auth_bad_auth_header",
    "message": "Authorization header malformed.",
    "data": []
}

image
image
image

Plugin breaks Gutenberg post creation after activation

Expected Behaviour

A new post in Gutenberg should be created as it does without the plugin being activated.

Actual Behaviour

When clicking on "Publish" in Gutenberg, the post says that it has been published but it has not as it does not appear in the database nor on the posts listing page in the dashboard.

This happens even if I whitelist this URL: /wp-json/wp/v2/posts

Steps to Reproduce the Problem

  1. Install and activate the plugin.
  2. Attempt to publish a new post in Gutenberg.
  3. See that the post is not asserted in the database or the posts listing page.

Additional Information

When activating the plugin, all REST API endpoints are protected even if they are public by default, such as this URL: /wp-json/wp/v2/posts, would it be possible to add configuration so that only routes that need authentication require it by JWT?

Configuration with Nginx + AWS

Hi I have WordPress website which is running on Nginx server on AWS.
I'm not sure how to configure JWT auth correctly.
I receive error "jwt_auth_no_auth_header"
Thanks!

Function to generate a token for a user (public API)

First of all, thank you for developing this plugin! It's really great.
I'm using it to authenticate users from a React Native app.

I'm creating my own API route for that, where I directly call the generate_token() method on the JWTAuth\Auth class, like so:

public function process() {
	$login    = sanitize_text_field( $this->get_param( 'login' ) );
	$password = sanitize_text_field( $this->get_param( 'password' ) );
	$user     = wp_authenticate( $login, $password );

	if ( is_wp_error( $user ) ) {
		return $user;
	}

	$auth    = ( new \JWTAuth\Auth() )->generate_token( $user, false );
	$payload = apply_filters( 'project/ajax/user-login/payload', $auth['data'], $user );

	return [
		'success' => true,
		'auth'    => $payload,
	];
}

So far so good, but I'm wondering if it would be safer and more practical for everybody if we had access to a basic function to generate the token, instead of instantiating the class and calling the right method.
Maybe something like jwtauth_generate_token( $user, false ).

That way, it's update-proof: if something changes (class name, method, parameters), we make sure to reflect these changes in the publicly available function, so we ensure long-term compat.

What do you think?

I can take care of creating such a function and add a PR if necessary.

Whitelist plugin "Illegal string offset 'slug'" in /wp-admin

Hello @contactjavas,

We created a custom plugin for the whitelist filters like so:

<?php

if (!defined('WPINC')) {    die;    }
if ( ! defined( 'ABSPATH' ) ) die( 'restricted access' );

class CustomPlugin {

    public function __construct(){
        add_filter('jwt_auth_whitelist', function ( $endpoints ) {
            array_push($endpoints,'/wp-json/dummy/*');
            array_push($endpoints,'/wc-admin/*');
            array_push($endpoints,'/wc/*');
            array_push($endpoints,'/wc-auth/*');
            array_push($endpoints,'/wc-analytics/*');
            array_push($endpoints,'/wp-json/wc-admin/*');
            array_push($endpoints,'/wp-json/wc/*');
            array_push($endpoints,'/wp-json/wc-auth/*');
            array_push($endpoints,'/wp-json/wc-analytics/*');
            return $endpoints;
        });
    }
}

//======================================================
new CustomPlugin();

We were able to resolve this warning in the other areas:

[20-Apr-2021 08:46:03 UTC] PHP Warning:  Illegal string offset 'slug' in /home/dummyuser/repos/dummyproject/wp-content/plugins/woocommerce/packages/woocommerce-admin/src/API/Reports/PerformanceIndicators/Controller.php on line 149
[20-Apr-2021 08:46:03 UTC] PHP Warning:  Illegal string offset 'slug' in /home/dummyuser/repos/dummyproject/wp-content/plugins/woocommerce/packages/woocommerce-admin/src/API/Reports/PerformanceIndicators/Controller.php on line 149

The only remaining case that it appears is when we access /wp-admin, could you provide us some insight about this?

Regex check for jwt_auth_whitelist

I came across some issues adding some patterns to the jwt_auth_whitelist to whitelist them from auth and when I looked at the plugin code I found a TODO for this very point in JWTAuth::is_whitelisted()

I'm trying to whitelist something with the following pattern:

  • /wp-json/bdvs/v1/services/(?P\d+)/action

If I add a check that looks something like this I get what I need:

$regex = '/' . str_replace( '/' , '\/' , $endpoint ) . '/'; if( preg_match( $regex , $request_uri )) { return true; }

I need to use this because I only want to whitelist this route if it has /action on the end of it.

What do you think about adding this in there?

Whitelist doesn't work in folder installation

When the site is installed in folder, $_SERVER['REQUEST_URI'] comes with the folder name in path. The plugin must use only the rest base to compare. So, to avoid this problem you can add this code to define the $resquest_uri in is_whitelisted() function:

$prefix = rest_get_url_prefix();
$split = explode( $prefix, $_SERVER['REQUEST_URI'] );
$request_uri = '/'.$prefix.'/'. ( (count($split)>1)?$split[1] : $split[0] );

jwt_auth_no_auth_header when enabling plugin

Hi, i am currently using your plugin and it works fine. Now we are using a library plugin to manage images better. But after we enable it, we get an error:

{ "success": false, "statusCode": 403, "code": "jwt_auth_no_auth_header", "message": "Authorization header not found.", "data": [] }

Plugin installed: https://de.wordpress.org/plugins/filebird/

When disabling it, everything works fine again. Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.