• Resolved nilsnolde

    (@nilsnolde)


    I’m coming from the a previous JWT plugin wp-api-jwt-auth and used it to authenticate to WooCommerce REST routes. However, I needed a way to also authenticate to normal routes (i.e. not part of REST) via JWT, so I thought this plugin might help. And it looks so much more powerful than the old one, I’d love to make it work. I run WordPress v5.3.2.

    Somehow I can’t get it to even successfully authenticate to ANY WooCommerce REST route.. It’s all installed (and old plugin deactivated), set up and the /simple-jwt-login/v1 endpoints work: I can generate a JWT and I can do /autologin. But using the JWT as Bearer token in any call to WooCommerce I get 401: woocommerce_rest_cannot_view (e.g. /wp-json/wc/v3/customers/1). The exact same thing does work with the old wp-api-jwt-auth plugin.

    When I tried some debugging I found that this plugin doesn’t login the authenticated user.. During the WC permission check ((which happens after the authorization happened) the function get_current_user_id() returns 0, while for the old plugin it returns the user ID of the JWT authenticated user. Is that intended?

    Can you recommend anything I could try? If I could find the part of the code it uses to hook into the whole authorization flow I could probably help myself I guess. I’m unable to find that though..

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Author Nicu Micle

    (@nicu_m)

    Hello,

    Currently, the simple-jwt-login plugin does not make the authentication on API.
    I’m working on a beta version for this feature. I think that by the end of the week it will be available (as beta version).

    I will come back with updates.

    Best regards,
    Nicu.

    Thread Starter nilsnolde

    (@nilsnolde)

    Thanks for your swift response! That’d be indeed incredible:) Do you reckon one can also authenticate routes outside of the REST API? E.g. WooCommerce has these https://domain.com?download_file=2129... routes, which I’d like to be able to authenticate via JWT.

    Is the code public somewhere? I’d be glad to help out a little.

    Plugin Author Nicu Micle

    (@nicu_m)

    Hello,

    I’m pretty sure that it will be possible.

    The beta version will allow you to choose where you want to use the JWT parameter. When provided, it will enter in the context of “logged in” user. So, if this download_file can be accessed only by logged in users, then, I’m pretty sure you will be able to download it if you will enable the JWT for this route, and you will add a JWT in the URL/Session/Cookie/Header of the request.

    I will come back with updates, once I release the new version.

    Best regards,
    Nicu.

    Thread Starter nilsnolde

    (@nilsnolde)

    Beautiful, thanks so much Nicu! Happy to see someone as dedicated as you to their JWT plugin (or even generally WP plugins), there’s too many unmaintained ones out there..

    Plugin Author Nicu Micle

    (@nicu_m)

    Hello,

    I’ve just released version 2.2.5. In this version, it is included a beta version for accessing private endpoints.

    You can attach the JWT by URL, session, cookie, or in the header.

    Please let me know what do you think.

    Best regards,
    Nicu.

    Thread Starter nilsnolde

    (@nilsnolde)

    Thanks so much for the headsup! Wanted to quickly try it yesterday but I can’t even log in anymore to my local wordpress installation, seems I completely busted it over the past week tinkering with JWT plugins. I’ll fix asap and let you know if it worked for me.

    Plugin Author Nicu Micle

    (@nicu_m)

    I forgot to mention that, if you want to use the JWT on other endpoints, you have to check the option from plugin “general” settings.

    Thread Starter nilsnolde

    (@nilsnolde)

    Hi Nicu,

    I found my WP bug, stupid statement in wp-config… I also successfully tried your new version with the REST API. However, note, that I had to enable auto-login in your plugin, since the code needs the getJwtLoginByParameter() output. Took a little while, but worked just fine. Great progress!

    However, sadly it doesn’t work for “normal” WP routes. The ?download_file= route is not part of the REST API. And the plugin “only” hooks into REST API actions rest_api_init and rest_endpoints. I really don’t know yet how to do this. But is HAS to be possible. I’ll dig more now and let you know if I find a way.

    Thread Starter nilsnolde

    (@nilsnolde)

    Ok, I solved it! It’s a little brute-force, but as long as it works ??

    I replaced the rest_api_init action with a global init action and removed the rest_endpoints action:

    
    
    add_action( 'init', function () {
    	if(empty(session_id())){
    		session_start();
    	}
    	$jwtService = new SimpleJWTLoginService();
    	$jwtSettings = new SimpleJWTLoginSettings( new WordPressData() );
    	$jwtService->withSettings( $jwtSettings );
    	$jwtService->withRequest($_REQUEST);
    	$jwtService->withCookie( $_COOKIE );
    	$jwtService->withSession( $_SESSION );
    
    	$corsService = new CorsService($jwtSettings);
    	if($corsService->isCorsEnabled()) {
    
    		if($corsService->isAllowOriginEnabled()){
    			$corsService->addHeader('Access-Control-Allow-Origin', $corsService->getAllowOrigin());
    		}
    		if($corsService->isAllowMethodsEnabled()){
    			$corsService->addHeader('Access-Control-Allow-Methods', $corsService->getAllowMethods());
    		}
    		if($corsService->isAllowHeadersEnabled()){
    			$corsService->addHeader('Access-Control-Allow-Headers', $corsService->getAllowHeaders());
    		}
    	}
    
    	if ( $jwtSettings->isMiddlewareEnabled() ) {
            $currentURL =
                "http"
                .(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "s" : "")
                . "://" .$_SERVER['HTTP_HOST']
                .$_SERVER['REQUEST_URI'];
            if( strpos($currentURL, $jwtSettings->getRouteNamespace()) !== false){
                //Skip middleware for simple-jwt-plugin
                return ;
            }
    
            $jwt = $jwtService->getJwtFromRequestHeaderOrCookie();
            if ( ! empty( $jwt ) ) {
                try {
                    $userID = $jwtService->getUserIdFromJWT( $jwt );
                    wp_set_current_user( $userID );
                } catch ( \Exception $e ) {
                    @header( 'Content-Type: application/json; charset=UTF-8' );
                    wp_send_json_error( [
                        'message'   => $e->getMessage(),
                        'errorCode' => $e->getCode(),
                        'type'      => 'simple-jwt-login-middleware'
                    ],
                        400
                    );
                    die();
                }
            }
    	}
    
    	$routeService    = new RouteService();
    	$availableRoutes = $routeService->getAllRoutes();
    
    	foreach ( $availableRoutes as $route ) {
    		register_rest_route( $jwtService->getRouteNamespace(), $route['name'], [
    				'methods'  => $route['method'],
    				'callback' => function ( $request ) use ( $route, $routeService, $jwtService, $jwtSettings ) {
    					/***
    					 * @var $request WP_REST_Request
    					 */
    
    					try {
    						$jwtService->withRequest( $request->get_params() );
    						$routeService->withService( $jwtService );
    
    						return $routeService->makeAction( $route['name'], $route['method'] );
    					} catch ( Exception $e ) {
    						@header( 'Content-Type: application/json; charset=UTF-8' );
    						wp_send_json_error( [
    							'message'   => $e->getMessage(),
    							'errorCode' => $e->getCode()
    						],
    							400
    						);
    
    						return false;
    					}
    				}
    			]
    		);
    	}
    }
    

    If there’s any better suggestion, I’m all ears:)

    Thread Starter nilsnolde

    (@nilsnolde)

    Quick update: I had to tweak a little more since the line

    
            if( strpos($currentURL, $jwtSettings->getRouteNamespace()) !== false){
                //Skip middleware for simple-jwt-plugin
                return ;
            }
    

    was preventing the plugin to register its endpoints.

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘JWT does not login user’ is closed to new replies.