Tmeister / wp-api-jwt-auth

A simple plugin to add JSON Web Token (JWT) Authentication to WP REST API
GNU General Public License v2.0
555 stars 160 forks source link

http_authorizaion header #1

Closed itibook closed 9 years ago

itibook commented 9 years ago

Hi there,

playing around with your plugin... looks really well done. I had some issues with the Authorization header not showing up. I googled around and found this. I used it instead of your htaccess code and it did the trick for me... hope it helps others

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

Tmeister commented 9 years ago

Hey Thanks,

Can you please tell me your server setup, is a local install or a live server to include the info in the readme file.

itibook commented 9 years ago

Live server on WPEngine...

your plugin works like a charm! Where can I pay you a beer? :-)

simonh1000 commented 7 years ago

I needed this line too with a simple apache setup on my dev machine. As I did not know what WPEngine is I ignored this first time around and lost some time with rest_forbidden errors as a result. I'm not sure what would be an accurate change, but I do suggest updating the README a little

gravyplaya commented 7 years ago

I added the lines to my htaccess. I an getting the following error. {"code":"jwt_auth_bad_auth_header","message":"Authorization header malformed.","data":{"status":403}} I am on wpengine and php7.

---- htaccess begin ------

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

-----htaccess end-----

tiomno commented 6 years ago

For users of AWS Lightsail with a bitnami/WordPress instance:

To make this work go and edit /home/bitnami/apps/wordpress/conf/htaccess.conf and set the SetEnvIf statement there:

RewriteEngine On
RewriteRule /<none> / [L,R]

#Right here worked for me!!!
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

<IfDefine USE_PHP_FPM>
    <Proxy "unix:/opt/bitnami/php/var/run/wordpress.sock|fcgi://wordpress-fpm" timeout=300>
    </Proxy>
</IfDefine>
...

Don't forget to restart Apache!

It didn't work for me in the .htaccess. :(

riteshtailor2002 commented 6 years ago

Getting error after configuring this plugin as per the steps mentioned over here : https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/

Error : { "code": "jwt_auth_bad_auth_header", "message": "Authorization header malformed.", "data": { "status": 403 } }

Any suggestion ?

tiomno commented 6 years ago

@riteshtailor2002 what is your server setup? If Apache + PHP do you access to httpd.conf?

Mulli commented 6 years ago

Have the same(?) problem: {"code":"jwt_auth_bad_auth_header","message":"Authorization header malformed.","data":{"status":403}} WP 4.9.3, JWT 1.2.4, PHP 7+ Hosting: shared on SiteGround with Apache. No special tweaks.

My .htaccess:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</IfModule>
# END HTTPS
# 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]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

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

</IfModule>

# END WordPress

``

tiomno commented 6 years ago

@Mulli, this is me just guessing; I have no idea how the mode_rewrite of Apache works or environment variables manipulation for that matter.

Have you tried to move the line SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 to the very beginning of the .htaccess file? Out of any block?

nabilzidane commented 6 years ago

Hi guys. This is the right way to add your code in the htaccess file and it's work fine for me.

# 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]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
</IfModule>
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# END WordPress

This line SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 must be outside of IFMODULE

nabilzidane commented 6 years ago

I have only one problem, If I add a new plugin, or change my theme. I loose my JWT config on the htaccess. Do I have to edit it every time?

nabilzidane commented 6 years ago

Hi @Mulli You have to remove the # before SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

tiomno commented 6 years ago

@nabilzidane what about moving the line SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 out of the block # BEGIN WordPress <-> # END WordPress. Put that line after # END WordPress and try again. Hope that fixes the problem. :)

alexbjorlig commented 5 years ago

@itibook can you share your .htaccess setup?

I am running wordpress on wp-engine, and using the code suggested by @nabilzidane does not work. The error I get is { "code": "rest_cannot_access", "message": "Only authenticated users can access the REST API.", "data": { "status": 401 } }, not sure if it's related?

itibook commented 5 years ago

@dauledk I haven't tried it out in a long time, but this is what I had at the time... wouldn't be surprised if it doesn't work anymore

###################################################
# Used for the the JWT Plugin
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
alexbjorlig commented 5 years ago

@itibook ok, I gave up and is now successfully using the https://wordpress.org/plugins/application-passwords/ plugin instead and it works. But thanks

N-Molham commented 5 years ago

@Tmeister what is the solution for other special hosting env like FlyWheel or pantheon ?

mikedoubintchik commented 5 years ago

I added the lines to my htaccess. I an getting the following error. {"code":"jwt_auth_bad_auth_header","message":"Authorization header malformed.","data":{"status":403}} I am on wpengine and php7.

---- htaccess begin ------

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

-----htaccess end-----

I got it working. The important part is the authorization header. It must be Authorization: 'Bearer ' (Bearer with a capital B)

axios.post(`${env.backendURL}/wp-json/jwt-auth/v1/token/validate`, {}, {headers: {Authorization: 'Bearer ' + localStorage.token}})
            .then(response => console.log(response))
            .catch(error => console.log(error.response));
eicksl commented 5 years ago

In my case it wasn't working because I was using SiteGround's staging environment. Works fine in production.

yagnikv commented 4 years ago

what is url for user logout api, means how to revoke user token

carlosen14 commented 4 years ago

@yagnikv remove the token from client. token on WP is not saved on DB, it just validates if it is still valid.

fabdelgado commented 4 years ago

How to configure this for nginx? I try with

global fastcgi config

fastcgi_pass_header Authorization;

server { listen 80; ...}

but this not work. Any help?

dhsathiya commented 4 years ago

@fabdelgado and all the future Nginx-ers

These are the Nginx location blocks

location /app/login/ {
        try_files $uri $uri/ /index.php?$args;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param HTTP:Authorization $http_authorization;
        more_set_headers 'Authorization: $http_authorization';
        include fastcgi_params;
}
location ~ \.php$ {
        try_files $uri =404;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param HTTP:Authorization $http_authorization;
        more_set_headers 'Authorization: $http_authorization';
        include fastcgi_params;
        fastcgi_pass php;
}

Main part

        fastcgi_param HTTP:Authorization $http_authorization;
        more_set_headers 'Authorization: $http_authorization';

When you do curl request with

https://example.com/app/login -H 'Authorization: 1234123412341234'

The response will have

authorization: 1234123412341234
ahmedelatab commented 4 years ago

@tiomno

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 works with me, and can be placed outside the portions that might be rewritten in the .htaccess file.

And it is more suitable than placing the following lines after the RewriteBase / that is enclosed in the environment of WordPress since it will be rewritten frequently!

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
itibook commented 3 years ago

@alexbjorlig did you managed to get Application Passwords to work without any issues?

I can get it to work locally and works just fine when testing, but on WPEngine I am getting 403 from Nginx... no idea what else I could do

itibook commented 3 years ago

@alexbjorlig figured out the issue... not sure why, but WPEngine requires a User-Agent header when doing a call via the Python requests library, as silly as that.

jacobraccuia commented 3 years ago

I'm using WPEngine found this issue after intense debugging.... The app was logging into the wrong user account (the previously logged in user, i believe) when the User-Agent had the word google or facebook in it. I'm not sure if this is a WP API bug or a JWT bug or what. Currently passing a custom user agent to avoid this issue.

madhanshan0401 commented 3 years ago

I am trying JWT Authentication for WP-API for building an Flutter App for Wordpress . I am facing issue with login , Its working good for Administrator account but it not allows the user account to login . But for my case i need my users to login to view the content . Please help me I tried to give permission through .htaccess file .

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

but no help .....

melomontoya commented 3 years ago

This might help if any of you guys are on AWS Lightsail Wordpress https://www.youtube.com/watch?v=pmfVL3yeq84

ahinkle commented 2 years ago

(for anyone using WpEngine)

WpEngine has deprecated .htaccess in favor of their control panel. This is recommended by WpEngine support - I confirmed with them that this method is safe as to reach the jwt_auth_bad_auth_header header you must be authenticated.

Note: takes ~15-20 minutes to activate and work on their side.

  1. Navigate to Web Rules -> Header Rules
  2. Action: Set
  3. Name: jwt_auth_bad_auth_header
  4. Value: jwt_auth_bad_auth_header
  5. When: 2xx Status Codes
  6. Add Condition
  7. Type: Header
  8. Name: jwt_auth_bad_auth_header
  9. Operator: Equal to (=)
  10. Value: 1
davidglines commented 1 year ago

(for anyone using WpEngine)

WpEngine has deprecated .htaccess in favor of their control panel. This is recommended by WpEngine support - I confirmed with them that this method is safe as to reach the jwt_auth_bad_auth_header header you must be authenticated.

Note: takes ~15-20 minutes to activate and work on their side.

  1. Navigate to Web Rules -> Header Rules
  2. Action: Set
  3. Name: jwt_auth_bad_auth_header
  4. Value: jwt_auth_bad_auth_header
  5. When: 2xx Status Codes
  6. Add Condition
  7. Type: Header
  8. Name: jwt_auth_bad_auth_header
  9. Operator: Equal to (=)
  10. Value: 1

This did not work for us. We are still seeing the "authorization header not found" error.

Any other ideas?

jacobraccuia commented 1 year ago

Hi @davidglines,

I was not able to figure out what causes this issue for me. My production environment is currently working and authenticating as expected, but my staging env. wasn't. I spent hours with wpengine and we tried different things, including trying to recreate HTTP Authorization in nginx and what not, but we never figured it out.

I ended up destroying the staging envs and starting them over with fresh copies, and fortunately that is enough for me.

I never received the authorization header not found error, though. My issue was that users weren't being logged in via jwt - instead they were just getting access. So calls to woocommerce and to get their user profile didn't authenticate.

davidglines commented 1 year ago

Jacob, thanks for the information. We are still stuck and have tried 3-4 different nginx rules as well as Web rules at WPengine. No luck. We have escalated to senior techs and hoping it will get resolved very soon. Our users cannot log in to our React app.

DG

Get Outlook for iOShttps://aka.ms/o0ukef


From: jacobraccuia @.> Sent: Thursday, October 20, 2022 8:54:01 PM To: Tmeister/wp-api-jwt-auth @.> Cc: David Glines @.>; Mention @.> Subject: Re: [Tmeister/wp-api-jwt-auth] http_authorizaion header (#1)

CAUTION: External Sender

Hi @davidglineshttps://github.com/davidglines,

I was not able to figure out what causes this issue for me. My production environment is currently working and authenticating as expected, but my staging env. wasn't. I spent hours with wpengine and we tried different things, including trying to recreate HTTP Authorization in nginx and what not, but we never figured it out.

I ended up destroying the staging envs and starting them over with fresh copies, and fortunately that is enough for me.

I never received the authorization header not found error, though. My issue was that users weren't being logged in via jwt - instead they were just getting access. So calls to woocommerce and to get their user profile didn't authenticate.

— Reply to this email directly, view it on GitHubhttps://github.com/Tmeister/wp-api-jwt-auth/issues/1#issuecomment-1286356076, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AVOGGY4IWSUL2TUJEBV7DSTWEHZTTANCNFSM4BOVG25A. You are receiving this because you were mentioned.Message ID: @.***>

jacobraccuia commented 1 year ago

hey @davidglines, have you had any luck?

i'm not sure if my current issue is related, but a POST API call works perfectly in staging and in production it treats it like a GET call and returns the GET response..

davidglines commented 1 year ago

Hi, Jacob. We ended up going the WP login route as our clients needed to get into our app. If needed, we will give your plug-in a try again in the future. Thanks for checking in.

DG

Get Outlook for iOShttps://aka.ms/o0ukef


From: jacobraccuia @.> Sent: Friday, November 4, 2022 12:24:33 PM To: Tmeister/wp-api-jwt-auth @.> Cc: David Glines @.>; Mention @.> Subject: Re: [Tmeister/wp-api-jwt-auth] http_authorizaion header (#1)

CAUTION: External Sender

hey @davidglineshttps://github.com/davidglines, have you had any luck?

i'm not sure if my current issue is related, but a POST API call works perfectly in staging and in production it treats it like a GET call and returns the GET response..

— Reply to this email directly, view it on GitHubhttps://github.com/Tmeister/wp-api-jwt-auth/issues/1#issuecomment-1303912457, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AVOGGY7QZBT5TSQMIVWOLBLWGVBFDANCNFSM4BOVG25A. You are receiving this because you were mentioned.Message ID: @.***>

gbg-webops commented 1 year ago

Did anyone ever find a solution to this? I've been looking for months and keep coming back to this issue thread hoping to find something. Seems pretty crazy that WP Engine would just drop support for .htaccess and then not have a reasonable alternative. If anyone know of a way to get around this or use a different solution all together, I'd love to hear about it.

Thanks!

gbg-webops commented 1 year ago

I was finally able to resolve this. I'll outline my fix below to hopefully help the next person if they are also running into this (although my gut tells me this is fairly unique to us)

Before I had a call to "/wp-json/wp/v2/users/me" as such in a js file: return fetch.get('/wp-json/wp/v2/users/me)

I updated this to be: return fetch.get('/wp-json/wp/v2/users/me?_wpnonce=' + wpr_object.rest_nonce)

Then I updated the script enqueue function in my php file to this:

public function enqueue_public_scripts() {
     if ($this->get_current_template() === 'page-virtual-instrument.php') {
         wp_enqueue_script($this->plugin_slug . '-public-script', plugins_url('assets/js/frontend.js', dirname(__FILE__)), array('jquery', 'wp-api-fetch'), $this->version);

        wp_localize_script( $this->plugin_slug . '-public-script', 'wpr_object', array(
            'rest_nonce'    => wp_create_nonce( 'wp_rest' ),
        )
        );
    }
}

_Note the "wp_localize_script" that creates the "restnonce" variable referenced in the js file

Did anyone ever find a solution to this? I've been looking for months and keep coming back to this issue thread hoping to find something. Seems pretty crazy that WP Engine would just drop support for .htaccess and then not have a reasonable alternative. If anyone know of a way to get around this or use a different solution all together, I'd love to hear about it.

Thanks!

nicoandrade commented 1 year ago

I will leave this here, maybe it will help someone like me.

I was getting this error:

PHP Warning:  Undefined array key "HTTP_AUTHORIZATION" in .../wp-content/plugins/jwt-authentication-for-wp-rest-api/public/class-jwt-auth-public.php on line 222

This happened when using Insomnia (software like Postman) and making a GET request without any kind of Authorization.

There is a fix to be made in the code on that line Replace this:

$auth_header = $_SERVER['HTTP_AUTHORIZATION'] ? sanitize_text_field( $_SERVER['HTTP_AUTHORIZATION'] ) : false;

With this:


$auth_header = array_key_exists( 'HTTP_AUTHORIZATION', $_SERVER ) && $_SERVER['HTTP_AUTHORIZATION'] ? sanitize_text_field( $_SERVER['HTTP_AUTHORIZATION'] ) : false;

I will suggest a PR with this fix.

Update: There is already a PR created with something like this.

groiso commented 4 days ago

Hi, I'm getting the following error "Status Code Error: 401" when connecting with make (integromat), here's my .htaccess file

# BEGIN cPanel-generated php ini directives, do not edit
# Manual editing of this file may result in unexpected behavior.
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
# For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
<IfModule php8_module>
   php_flag display_errors Off
   php_value max_execution_time 60
   php_value max_input_time 60
   php_value max_input_vars 5000
   php_value memory_limit 512M
   php_value post_max_size 516M
   php_value session.gc_maxlifetime 1440
   php_value session.save_path "/var/cpanel/php/sessions/ea-php82"
   php_value upload_max_filesize 512M
   php_flag zlib.output_compression Off
</IfModule>
<IfModule lsapi_module>
   php_flag display_errors Off
   php_value max_execution_time 60
   php_value max_input_time 60
   php_value max_input_vars 5000
   php_value memory_limit 512M
   php_value post_max_size 516M
   php_value session.gc_maxlifetime 1440
   php_value session.save_path "/var/cpanel/php/sessions/ea-php82"
   php_value upload_max_filesize 512M
   php_flag zlib.output_compression Off
</IfModule>
# END cPanel-generated php ini directives, do not edit

# BEGIN WordPress
# As diretrizes (linhas) entre "BEGIN WordPress" e "END WordPress" são
# geradas dinamicamente e só devem ser modificadas através de filtros do WordPress.
# Quaisquer alterações nas diretivas entre esses marcadores serão sobrescritas.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

# BEGIN EWWWIO
# As diretrizes (linhas) entre "BEGIN EWWWIO" e "END EWWWIO" são
# geradas dinamicamente e só devem ser modificadas através de filtros do WordPress.
# Quaisquer alterações nas diretivas entre esses marcadores serão sobrescritas.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png|gif)$
RewriteCond %{REQUEST_FILENAME}.webp -f
RewriteCond %{QUERY_STRING} !type=original
RewriteRule (.+)\.(jpe?g|png|gif)$ %{REQUEST_URI}.webp [T=image/webp,L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(jpe?g|png|gif)$">
Header append Vary Accept
</FilesMatch>
</IfModule>
AddType image/webp .webp
# END EWWWIO

# WP REST API
# SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# RewriteEngine on
#RewriteCond %{HTTP:Authorization} ^(.*)
# RewriteRule ^(.*) – [E=HTTP_AUTHORIZATION:%1]
# FIM WP REST API

# php -- BEGIN cPanel-generated handler, do not edit
# Defina o pacote “ea-php82” como a linguagem padrão de programação “PHP”.
<IfModule mime_module>
  AddHandler application/x-httpd-ea-php82___lsphp .php .php8 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit

I don't usually change anything in this file, everything was installed by default

How can I resolve this error?