Giter Club home page Giter Club logo

cakephp-jwt-auth's People

Contributors

admad avatar alysson-azevedo avatar bravo-kernel avatar ceeram avatar curtisgibby avatar hmic avatar ramosisw avatar stickler-ci avatar voycey 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cakephp-jwt-auth's Issues

getToken() causes authentication error when using query param 'token'

The function getToken() was recently changed and caused an authentication error in my project. I think an incorrect variable was introduced in a recent change when a token is provided as a query param.

Ie. $this->_token was possibly incorrectly replaced by $token

Made the change in my fork to check and test.

Authentication does not work when the user password is in clear text

I know we should ever encrypt passwords but I just do not understood why it does not work ;)

When I add to my User Entity

use Cake\Auth\DefaultPasswordHasher;

protected function _setPassword($password)
    {
        return (new DefaultPasswordHasher)->hash($password);
    }

every thing works well. But without those lines (I just not encrypt passwords) the authentication does not work. The token is ok.

Token check without expiration

Hello, is there a way to do not check the token expiration? So if the token is expired, I want to get logged in correctly.

Messed up security when using different Alg than HS256

As the config array get merged (deep):
If you specify allowedAlgs => ['RS256'], you end up with allowedAlgs beeing set to ['HS256', 'RS256'], which is NOT the intended result and causes an attacker to be able to alter the Token and create a good signature with just the public key!

Is it possible to use this plugin with cakeph 2 hashed password?

Hello,

I just tried with this, but without success :

$this->loadComponent('Auth', [ 'storage' => 'Memory', 'authenticate' => [ 'Form' => [ 'passwordHasher' => [ 'className' => 'Weak', 'hashers' => [ 'Weak', 'Default', ] ] ], 'ADmad/JwtAuth.Jwt' => [ 'parameter' => 'token', 'userModel' => 'Users', 'fields' => [ 'username' => 'id' ], 'passwordHasher' => [ 'className' => 'Weak', 'hashers' => [ 'Weak', 'Default', ] ], 'queryDatasource' => true ] ], 'unauthorizedRedirect' => false, 'checkAuthIn' => 'Controller.initialize' ]);

Thank You

CakePHP 3.6 deprecation: Deprecated (16384): The `scope` and `contain` options for Authentication are deprecated. Use the `finder` option instead to define additional conditions. - /home/public_html/vendor/admad/cakephp-jwt-auth/src/Auth/JwtAuthenticate.php, line: 105 [CORE/src/Core/functions.php, line 305]

Running into this problem with 3.6, though things seem to be otherwise working. This is occurring with

public function __construct(ComponentRegistry $registry, $config)
{
    $this->setConfig([
        'header' => 'authorization',
        'prefix' => 'bearer',
        'parameter' => 'token',
        'queryDatasource' => true,
        'fields' => ['username' => 'id'],
        'unauthenticatedException' => UnauthorizedException::class,
        'key' => null,
    ]);

    if (empty($config['allowedAlgs'])) {
        $config['allowedAlgs'] = ['HS256'];
    }

    parent::__construct($registry, $config);
}

Is there anything I can do to fix this in code?

$this->auth->allow() Not Working in Non-User Controller

I am following the "Bravo" tutorial and I have the api method to add a User on the controller working but the same style of logic does not allow other methods to be public for some reason?

Here is the controller code I am trying to make the add method public on:

<?php

namespace App\Controller\Api;

use App\Controller\Api\AppController;
use Cake\Event\Event;

class UserInfoController extends AppController
{
    public function beforeFilter(Event $event)
    {
        parent::beforeFilter($event);
        $this->Auth->allow('add');
    }

    public function add()
    {
        $this->Crud->on('afterSave', function(\Cake\Event\Event $event) {
            if ($event->subject->created) {
                $this->set('data', [
                    'id' => $event->subject->entity->id,
                    'message' => 'Request Saved!'
                ]);
                $this->Crud->action()->config('serialize.data', 'data');
            }
        });
        return $this->Crud->execute();
    }
}

I make the request http://localhost:8765/api/userinfo with POST and the correct JSON only to get a 401 unauthorized exception. My UserController is practially identical to the "Bravo" tutorial and has no problems with the public add() method. Is there something I am doing wrong or are the restrictions set by the plugin too "aggresive" for what I want to accomplish?

UPDATE - For some reason it will only work if I add the following route definition to alias the add method (but again only the alias will work not the direct api/userinfo call):

Router::connect('/api/userinfo/create', ['controller' => 'UserInfo', 'action' => 'add', 'prefix' => 'api']);

Documentation error

There is an error in the documentation which has had me on a wild goose chase ;-)

the config params read

'authenticate', [ ... ]
but should read
'authenticate' => [ ... ]

How do I test the action with your JWT?

I have this unit test

    public function testEmployeeSignIn() {
      $this->configRequest([
        'headers' => [
            'authorization' => 'Bearer: oauth-token'
        ]
      ]);

      $this->post('/api/transactions/add', $this->getPostData("IN"));
      $this->assertResponseOk();
    }

How do I get the token to put it in the header?

Issues with production server

Hello, I have been looking all around for a couple hours with no answer. I completed this tutorial:

http://www.bravo-kernel.com/2015/04/how-to-build-a-cakephp-3-rest-api-in-minutes/

It works great locally but the same code on my production server (Siteground) and I keep getting this error:

{
"message": "You are not authorized to access that location.",
"url": "/customers",
"code": 401
}

I did add this to .htaccess:

RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.)
RewriteRule .
- [e=HTTP_AUTHORIZATION:%1]

I also checked http://jwt.io/ and validated my token, not sure what to do, please point me in the right direction

here is my UsersController:

 <?php
 namespace App\Controller;

 use Cake\Event\Event;
 use Cake\Network\Exception\UnauthorizedException;
 use Cake\Utility\Security;
 use Firebase\JWT\JWT;

 class UsersController extends AppController{
     public function initialize(){
         parent::initialize();
         $this->Auth->allow(['add', 'token']);
    }

public function add(){
    $this->Crud->on('afterSave', function(Event $event) {
        if ($event->subject->created) {
            $this->set('data', [
                'id' => $event->subject->entity->id,
                'token' => JWT::encode(
                    [
                        'sub' => $event->subject->entity->id,
                        'exp' =>  time() + 604800
                    ],
                Security::salt())
            ]);
            $this->Crud->action()->config('serialize.data', 'data');
        }
    });
    return $this->Crud->execute();
}




public function token(){
    $user = $this->Auth->identify();
    if (!$user) {
        throw new UnauthorizedException('Invalid username or password');
    }

    $this->set([
        'success' => true,
        'data' => [
            'token' => JWT::encode([
                'sub' => $user['id'],
                'exp' =>  time() + 604800
            ],
            Security::salt())
        ],
        '_serialize' => ['success', 'data']
    ]);
}


 }

'storage' => 'Memory' must stay outside 'authenticate' node

I was using like the readme example but was not behaving stateless:

$this->loadComponent('Auth', [
        'authenticate', [
            'ADmad/JwtAuth.Jwt' => [
                'storage' => 'Memory'
                'userModel' => 'Users',
                'fields' => [
                    'username' => 'id'
                ],

                'parameter' => 'token',

                // Boolean indicating whether the "sub" claim of JWT payload
                // should be used to query the Users model and get user info.
                // If set to `false` JWT's payload is directly returned.
                'queryDatasource' => true,
            ]
        ],
        'unauthorizedRedirect' => false,
        'checkAuthIn' => 'Controller.initialize',
    ]);

So I made a request sending the JWT and all requests after that even if without JWT was authorized and if I did $this->Auth->user() I was getting the user, again, even if when I was not sending the JWT.

I just moved the storage outside authenticate node and now everything is working properly:

  $this->loadComponent('Auth', [
        'storage' => 'Memory'
        'authenticate', [
            'ADmad/JwtAuth.Jwt' => [
                'userModel' => 'Users',
                'fields' => [
                    'username' => 'id'
                ],

                'parameter' => 'token',

                // Boolean indicating whether the "sub" claim of JWT payload
                // should be used to query the Users model and get user info.
                // If set to `false` JWT's payload is directly returned.
                'queryDatasource' => true,
            ]
        ],
        'unauthorizedRedirect' => false,
        'checkAuthIn' => 'Controller.initialize',
    ]);

GetToken not working

Hi
I can not authenticate why the getToken function is coming empty.
And my request is sending the data.
I did a test, manually included my token as a return of the $ this-> token attribute and ran normally.
What can it be?

appcomponent

For generate token
generatetoken

To test, manually I did this and it worked!
gambiarra

Cakephp 3.6

Manage multiple tokens

Thank you for this, I have a situation where I use a separate table for users and tokens joined by a one-to-many relationship, is there way to make it work without having to add an additional username field at the tokens table? Would it check all the available keys or just the first one it finds?

Extend _findUser

I have a login-form where the user can either enter e-mail, nickname or mobile no as username. At the moment it obviously works only with one field. What is the best way to extend that functionality? I tried to extend the class JwtAuthenticate and override _findUser but it didn't work so far.

Issues logging in, initializing function.

$this->loadComponent('Auth', [
        'storage' => 'Memory',
        'authenticate' => [
        'ADmad/JwtAuth.Jwt' => [
             'parameter' => 'token',
              'userModel' => 'Users',
              'fields' => [
                   'username' => 'email',
	            'password' => 'password'
                    ],
                    'queryDatasource' => true
                ]
            ],
            'unauthorizedRedirect' => false,
            'checkAuthIn' => 'Controller.initialize'
  ]);

I have issues logging in with a POST request on www.example.com/users/token with an email

'Form' => [
      'fields' => [
       'username' => 'email',
       'password' => 'password'
    ]
 ]

Putting in 'Form' before 'ADmad/JwtAuth.Jwt' works fine, but causes problems with the tokens.

RefreshToken

is there an alternative to solve this problem?

ExpiredException throws 500 error

Hello, great plugin, very useful.

The plugin uses firebase JWT to authenticate based on the given token.
However, if the token is expired, firebase throws an ExpiredException, which results in a generic 500 error code.

This can make things problematic when trying to connect the backend with a client-side frontend, as RESTful apps generally check for a 401 error to know they need a new login. A 500 error can mean anything. Yes, a good client-side program can just know when it needs to throw away the token, but with RESTful APIs it is assumed it will serve a wide variety of client-side apps.

Usermodel

I need to change UserModel but it's doesn't work... why ?

Using on server can't be authorized

I used this plugin for my project. However, the plugin gives me a token (which is valid), but can't validate it on a requests, which gives me a 'not Authorized' error.

Here I got some info:

Token request giving me the token

image

A request which uses authorization

image

Stack

image

how to use with Acl ?

How to use with acl

I set up all the acl and authentication but by doing a get it returns me
AclNode :: node () - Could not find Aros node identified by "Array ([Aros0.model] => Users [Aros0.foreign_key] => 1)"

My controller

$this->loadComponent('Auth', [ 'authorize' => [ 'Acl.Actions' => ['actionPath' => 'controllers/'] ], 'authenticate' => [ AuthComponent::ALL => ['userModel' => 'Employes'], 'Form' => [ 'fields' => [ 'username' => 'email', 'password' => 'senha' ], 'scope' => ['Employes.status' => 1] ], 'ADmad/JwtAuth.Jwt' => [ 'parameter' => 'token', 'scope' => ['Employes.status' => 1], 'queryDatasource' => true ] ], 'unauthorizedRedirect' => false, 'checkAuthIn' => 'Controller.initialize', 'storage' => 'Memory' ]);

The name of my tables employes and roles where they are configured

Employes entity
public function parentNode() { if (!$this->id) { return null; } if (isset($this->role_id)) { $roleId = $this->role_id; } else { $employes = TableRegistry::get('Employes'); $employes = $employes->find('all', ['fields' => ['role_id']])->where(['id' => $this->id])->first(); $roleId = $employes->role_id; } if (!$roleId) { return null; } return ['Roles' => ['id' => $roleId]]; }

Update docs \JWT namespace

Since firebase\JWT version 3.0 they added \Firebase\JWT namespace, so the readme part about generating the token should be modified like this

Token Generation
You can use \Firebase\JWT\JWT::encode() [...]

Logout

Hello, thank you very much for this plugin, my question is: how can I expire the token at the time of making a logout in the application ?, try with the typical $ this->Auth->logout(), but the session and the token is not destroy.

kinds regards

RESTfull API example

Hi,
great job!

It would be nice to have a full example of how to implement RESTful api for integrating JWT auth with client side apps

Problem with using Environment to provide Auth since plugin upgrade

I haven't been able to catch you on IRC so I thought I would raise an issue, I'm not entirely sure where the problem is but since upgrading to the latest version of this plugin, setting an environment variable for authorisation for tests doesn't seem to be working:

I created this function to test it in one place and am running it through xdebug to inspect the data:

So at this point the plugin has returned the token and I have written it to the environment:

http auth header problem

Before I step into PHPUnit's GET function - you can see that I am Authorised in $_SESSION['Auth']

auth ok before get

I step into PHPUnit's GET function and can see the Environment variable is still set there so all seems good so far (I am also still Authorized in SESSION['Auth'])

http auth header problem - step into get

But on the other side of it - Auth is now telling me I am not authorized and I really dont understand why? (The environment variable is still there at this point as well).

The line it occurs on is 109 of Dispatcher.php: $result = $controller->startupProcess();

Before this line my user is in Auth and as soon as the startupProcess is called on the comments controller it removes the Auth and replaces it with a redirect and a Flash message saying not Authorised

http auth header problem - after get - auth not authorized

My AppController initialize is:

public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Flash');
        $this->loadComponent('RequestHandler');
        $this->loadComponent('Crud.Crud', [
            'actions' => [
                'Crud.Index',
                'Crud.View'
            ]
        ]);
        $this->Crud->addListener('relatedModels', 'Crud.RelatedModels');
        $this->Crud->addListener('Crud.Api');
        $this->Crud->addListener('Crud.ApiQueryLog');

        //JWT Auth
        $this->loadComponent('Auth', [
            'loginAction' => [
                'controller' => 'Users',
                'action' => 'login',
            ],
            'unauthorizedRedirect' => false,
            'authenticate' => [
                'ADmad/JwtAuth.Jwt' => [
                    'storage' => (Configure::read('debug') ? "Session" : "Memory"),
                    'parameter' => 'token',
                    'queryDatasource' => true,
                    'userModel' => 'Users',
                    'scope' => ['Users.active' => 1],
                    'fields' => [
                        'id' => 'id'
                    ]
                ],
                'Form' => [
                    'passwordHasher' => [
                        'className' => 'Legacy'
                    ]
                ]
            ]
        ]);
    }

Am I doing something idiotic or is there some gotcha I need to be aware of in the new version? I saw your notes on ensuring the server set either $_SERVER or $_ENV - I have tried both to no avail.

I'll also add that for development purposes I am using Auth->setUser as well so I can run requests on the front end without having to use postman for all get requests

how to get the logged in user id

hi @ADmad thanks for the beautiful plugin you made for the cakephp community, I am very confused about, that how can I get the logged in user id in other api's after logged in and sending the token received in login api?

please reply as fast as possible i will be very thankful of yours

request header Authorization is null

Hi @ADmad
I was working in my local PC testing my app with bin\cake server and every thing was OK.

but when I upload my app to the server I had an issue that my request header Authorization is always null.

I made two reuest in the same time one to the test server and one to the remote server and made some checks.

I found that the problem starts from environment because this array is different in the two servers.

this is the test server _environment array

[
  {
    "DOCUMENT_ROOT": "...",
    "REMOTE_ADDR": "::1",
    "REMOTE_PORT": "50858",
    "SERVER_SOFTWARE": "PHP 5.5.12 Development Server",
    "SERVER_PROTOCOL": "HTTP/1.1",
    "SERVER_NAME": "localhost",
    "SERVER_PORT": "8765",
    "REQUEST_URI": "/api/users/token",
    "REQUEST_METHOD": "GET",
    "SCRIPT_NAME": "/index.php",
    "SCRIPT_FILENAME": "D:\\...",
    "PATH_INFO": "/api/users/token",
    "PHP_SELF": "/index.php",
    "HTTP_HOST": "localhost:8765",
    "HTTP_CONNECTION": "keep-alive",
    "HTTP_AUTHORIZATION": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJlNjY2ZTE5Ny03NGQzLTRkNmMtOWFlMS0yYmU5ZWFiNzYzNDkiLCJleHAiOjE0NjU5Nzc1OTV9.H6ZxKsmEdc5huQ5lXYLf2Mz-4Thb1sQs1BLbJIGwjdc",
    "HTTP_CACHE_CONTROL": "no-cache",
    "HTTP_USER_AGENT": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
    "HTTP_POSTMAN_TOKEN": "88e43421-63a1-9530-1f2c-2d7f4c3c6ad7",
    "HTTP_ACCEPT": "*/*",
    "HTTP_ACCEPT_ENCODING": "gzip, deflate, sdch",
    "HTTP_ACCEPT_LANGUAGE": "tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4",
    "REQUEST_TIME_FLOAT": 1465373939.0754,
    "REQUEST_TIME": 1465373939,
    "HTTP_X_HTTP_METHOD_OVERRIDE": null,
    "ORIGINAL_REQUEST_METHOD": "GET",
    "HTTPS": false,
    "HTTP_X_REQUESTED_WITH": null
  }
]

this is the remote server _environment array

[
  {
    "REDIRECT_REDIRECT_STATUS": "200",
    "REDIRECT_STATUS": "200",
    "HTTP_HOST": "server.com",
    "HTTP_CONNECTION": "keep-alive",
    "HTTP_CACHE_CONTROL": "no-cache",
    "HTTP_USER_AGENT": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36",
    "HTTP_POSTMAN_TOKEN": "3e6afeb1-410c-5e95-2dcd-11c72df55941",
    "HTTP_ACCEPT": "*/*",
    "HTTP_ACCEPT_ENCODING": "gzip, deflate, sdch",
    "HTTP_ACCEPT_LANGUAGE": "tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4",
    "HTTP_COOKIE": "CAKEPHP=r7gi0qkpcgfbg9au1h9bc3bvf3",
    "PATH": "C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\wamp\\bin\\php\\php5.5.12;C:\\Program Files (x86)\\Git\\cmd;C:\\ProgramData\\ComposerSetup\\bin;C:\\Program Files\\nodejs\\;C:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C:\\Program Files (x86)\\Microsoft SDKs\\TypeScript\\1.0\\;C:\\Program Files\\Microsoft SQL Server\\120\\Tools\\Binn\\",
    "SystemRoot": "C:\\Windows",
    "COMSPEC": "C:\\Windows\\system32\\cmd.exe",
    "PATHEXT": ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC",
    "WINDIR": "C:\\Windows",
    "SERVER_SIGNATURE": "<address>Apache/2.4.9 (Win64) OpenSSL/1.0.1g PHP/5.5.12 Server at server.com Port 80</address>\n",
    "SERVER_SOFTWARE": "Apache/2.4.9 (Win64) OpenSSL/1.0.1g PHP/5.5.12",
    "SERVER_NAME": "server.com",
    "SERVER_ADDR": "192.168.85.21",
    "SERVER_PORT": "80",
    "REMOTE_ADDR": "76.44.73.54",
    "DOCUMENT_ROOT": "C:/wamp/www/",
    "REQUEST_SCHEME": "http",
    "CONTEXT_PREFIX": "",
    "CONTEXT_DOCUMENT_ROOT": "C:/wamp/www/",
    "SERVER_ADMIN": "[email protected]",
    "SCRIPT_FILENAME": "C:/wamp/www/reporter/webroot/index.php",
    "REMOTE_PORT": "50837",
    "REDIRECT_URL": "/reporter/webroot/api/users/token",
    "GATEWAY_INTERFACE": "CGI/1.1",
    "SERVER_PROTOCOL": "HTTP/1.1",
    "REQUEST_METHOD": "GET",
    "QUERY_STRING": "",
    "REQUEST_URI": "/reporter/api/users/token",
    "SCRIPT_NAME": "/reporter/webroot/index.php",
    "PHP_SELF": "/reporter/webroot/index.php",
    "REQUEST_TIME_FLOAT": 1465373833.462,
    "REQUEST_TIME": 1465373833,
    "HTTP_X_HTTP_METHOD_OVERRIDE": null,
    "ORIGINAL_REQUEST_METHOD": "GET",
    "HTTPS": false,
    "HTTP_X_REQUESTED_WITH": null
  }
]

I will make a patch to explain how I fixed the issue as an instant solution

Can't avoid deprecationWarning on Cake\Network\Exception\UnauthorizedException

If I don't force plugin config with :

'unauthenticatedException' => 'Cake\Http\Exception\UnauthorizedException'

I always have the depracation warning.
After investigate, if I switch in JwtAuthenticate (l.101 ) from :

if (!class_exists(UnauthorizedException::class, false)) {

to :

if (!class_exists(UnauthorizedException::class)) {

So everything's fine ... is there anything to do, or have I to force the UnauthorizedException class on plugin config ?

Omitting the exp

If I omit the exp in the creating of the token, the token will live forever or theres some default value of expiration when we omit it?

username or email

How to implement a login for both username OR email , is it possible ?

Storage

Hey,

Do you have any plans to store the tokens somewhere to work with refresh-tokens?
The plugin looks good and trying it :)

Some extra docs would be welcome (as said earlier). Maybe I got some time once....

Greetz

Bob

Expired Time

How do I put expiration time on the token, do I do this on the frontend or the backend?

Undefined variable: token

I am getting this error when Authorization header is not present or empty:

Notice Error: Undefined variable: token in [vendor/admad/cakephp-jwt-auth/src/Auth/JwtAuthenticate.php, line 197]

Fixture Error when running test

Hi
I am trying to run test case for the plugin and I added

<testsuites>
        <testsuite name="App Test Suite">
            <directory>./tests/TestCase</directory>
        </testsuite>
        <!-- Add plugin test suites here. -->
        <testsuite name="JWT AUTH plugin">
            <directory>./vendor/admad/cakephp-jwt-auth/tests/TestCase</directory>
        </testsuite>
    </testsuites>

to phpunit.xml.dist file . When I run vendor/bin/phpunit from command line I am getting an Exception

Exception: Referenced fixture class "ADmad\JwtAuth\Test\Fixture\UsersFixture" not found. Fixture "plugin.ADmad\JwtAuth.users" was referenced in test case "ADmad\JwtAuth\Auth\Test\TestCase\Auth\JwtAuthenticateTest". in [/var/www/html/swiftmail/app/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureManager.php, line 180]

Can you please help here with this ?

Return Code 404 (Error: Missing Route) when requesting API

Hello,
I tried to use this plugin as described [here ](http://www.bravo-kernel.com/2015/04/how-to-add-jwt-authentication-to-a-cakephp-3-rest-api/ but for some reason it does not work as described - at least for me.

Authentication works fine. I get the token but when I try to pass the token to the API for requesting resources I get a "404" not found meesage. I cannot determine a 100% if this is an issue concerning this plugin but when I disable the authentication, I can request the resources as I could before the authentication.

AppController looks pretty straight forward:

public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');

        $this->loadComponent('Auth', [
            'storage' => 'Memory',
            'authenticate' => [
                'Form' => ['userModel' => 'Users'],
                'ADmad/JwtAuth.Jwt' => [
                    'parameter' => '_token',
                    'userModel' => 'Users',
                    'fields' => [
                        'username' => 'username',
                        'password' => 'password'
                    ],
                    'queryDatasource' => true
                ]
            ],
            'unauthorizedRedirect' => false,
            'checkAuthIn' => 'Controller.initialize'
        ]);
    }

EDIT: I think it makes sense also to post the routes.php:

Router::scope('/', function (RouteBuilder $routes) {

    $routes->connect(
        '/:path',
        ['controller' => 'Pages', 'action' => 'display', 'home'],
        ['path' => '.*']
    );

    $routes->scope('/api/', function($routes) {
        $list = ['map' => ['list' => [
            'action' => 'list',
            'method' => 'POST',
            'path' => '/list'
        ]]];

        $routes->resources('Users', $list);
        $routes->resources('Users', ['map' => ['login' => [
            'action' => 'login',
            'method' => 'POST',
            'path' => '/login'
        ]]]);
    });

The token generating method in UsersController:


    public function login()
    {
        $user = $this->Auth->identify();
        if (!$user) {
            $this->viewBuilder()->className('Json');
            $this->set([
                'success' => false,
                'data' => null,
                '_serialize' => ['success', 'data']
            ]);
        } else {
            $this->viewBuilder()->className('Json');
            $this->set([
                'success' => true,
                'data' => [
                    'token' => JWT::encode([
                        'sub' => [
                            'username' => $user['username'],
                        ],
                        'exp' =>  time() + 604800
                    ],
                    Security::salt())
                ],
                '_serialize' => ['success', 'data']
            ]);
        }
    }

This is how a dummy request looks like:

Host: localhost:4100
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.7,de;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:4100/admin
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOnsidXNlcm5hbWUiOiJ0ZXN0In0sImV4cCI6MTUxMjg0MDUzNn0.ckqcOEUELdoUoUgFF1n5zcLVTKjig9cYKWO2l6F43jM
Content-Type: application/json
Content-Length: 224
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

I tried to pass it through _token parameter:

{"_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOnsidXNlcm5hbWUiOiJ0ZXN0In0sImV4cCI6MTUxMjg0MDUzNn0.ckqcOEUELdoUoUgFF1n5zcLVTKjig9cYKWO2l6F43jM","filter":"","page":1,"pageSize":25,"sort":{"active":"","direction":""}}

All of the above configuration didn't work. Furthermore, I realized that passing the token to debugger on jwt.io results to an invalid signature. As mentioned before I get a "404 Missing Routes Error". What am I doing wrong?

EDIT: I use "cakephp/cakephp": "3.5.*"

Using alternate fields to authenticate instead of username/password?

Thank you so much for implementing this, it is extremely helpful in my development. I have a question, if I wanted to use 'email' rather than 'username' to check the db, how would I modify the app? I'm using an already existing database that uses 'email' instead of 'username' for the users credentials? Also, the database uses 'pin' instead of 'password', how could I modify the structure to accommodate for the changes in database structure? Thanks again!

Signature verification failed

Hi,

I'm always getting error "Signature verification failed" and I'm not sure why it's happening, because apparently everything is fine (in my cakephp project at least). Btw, the website is accessed using the https protocol ( not sure if it matters ). PHP version 7; Cakephp 3.6 & Apache 2 server.

{
  "message": "Signature verification failed",
  "url": "\/api\/users.json",
  "code": 500,
  "file": "\/var\/www\/Development\/appname\/vendor\/firebase\/php-jwt\/src\/JWT.php",
  "line": 112
}

To get to this point before I had to disable apache authentication with AuthType None because apache itself returned a 501 error. I also tried to get it working messing with the .htaccess but everything i tried didn't worked.

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

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

When I got the answer from cakephp instead of apache I started to track the matter and tried to put the jwt token into a validator ( https://jwt.io/ ) with the cake salt and and it seems to be valid (Signature verified).

All the base files of the library have not been modified. Here's my code:

AppController.php

namespace App\Controller\Api;

use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller {

    use \Crud\Controller\ControllerTrait;

    public function initialize() {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Crud.Crud', [
            'actions' => [
                'Crud.Index',
                'Crud.View',
                'Crud.Add',
                'Crud.Edit',
                'Crud.Delete'
            ],
            'listeners' => [
                'Crud.Api',
                'Crud.ApiPagination',
                'Crud.ApiQueryLog'
            ]
        ]);
        $this->loadComponent('Auth', [
            'storage' => 'Memory',
            'authenticate' => [
                'Form' => [
                    'fields' => ['username' => 'username', 'password' => 'password'],
                    'scope' => ['Users.active' => 1]
                ],
                'ADmad/JwtAuth.Jwt' => [
                    'parameter' => 'token',
                    'userModel' => 'Users',
                    'scope' => ['Users.active' => 1],
                    'fields' => [
                        'username' => 'id'
                    ],
                    'queryDatasource' => true
                ]
            ],
            'unauthorizedRedirect' => false,
            'checkAuthIn' => 'Controller.initialize',
            'loginAction' => true
        ]);
    }
}

UsersController.php ( where token is created )

public function index()
    {
        $this->loadmodel('Users');
        $this->paginate = [
            'order' => ['username' => 'ASC']
        ];
        $users = $this->paginate($this->Users);

        $this->set([
            'users' => $users,
            '_serialize' => ['users']
        ]);
    }

public function token() {
        $user = $this->Auth->identify();
        if (!$user) {
            throw new UnauthorizedException('Invalid username or password');
        } else {
            $this->set([
                'success' => true,
                'data' => [
                    'token' => JWT::encode([
                        'sub' => $user['id'],
                        'exp' =>  time() + 604800
                    ],
                    Security::salt())
                ],
                '_serialize' => ['success', 'data']
            ]);
        }
    }

I'm missing something?

Sorry for the Translator English :_(

Thanks.

401 Unauthorized access even on valid token

I'm using CakePHP 3.6 and this plugin to add REST to my application.

All works fine in localhost but after moving to the server, it gives 401 error

{
    "success": false,
    "data": {
        "message": "You are not authorized to access that location.",
        "url": "/api/client_accounts",
        "code": 401
    }
}

I have posted a question with more detail on Stackoverflow.

https://stackoverflow.com/q/52286806/3719167

I have also added the following in .htaccess

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule    ^(\.well-known/.*)$ $1 [L]
    RewriteRule    ^$    webroot/    [L]
    RewriteRule    (.*) webroot/$1    [L]
    
    RewriteCond %{HTTP:Authorization} ^(.*)
    RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
</IfModule>

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.