hi,
i m developping an project with laravel5, and i try to include JWTAuth in this project
i follow this tuto http://laravelista.com/json-web-token-authentication-for-lumen/ who is in laravel 4
and i'm trying to change their instructions to laravel 5, I arrived to generate a secret key
but i am blocked in step : Authentication,
after i change middleware in route:
$router->group(['prefix' => 'auth'], function () {
get('login', ['middleware' => 'jwt.auth', 'as' => 'login', 'uses' => 'AuthController@getLogin']);
post('login', ['as' => 'login.post', 'uses' => 'AuthController@postLogin']);
});
when i try to authenticate i get this exception
ReflectionException in Container.php line 741:
Class Tymon\JWTAuth\src\MiddlewareGetUserFromToken does not exist
i verified this class in directory tymon, i found it, so i don't know what is the problem,
Any thoughts?
thanks in advance
Did you follow the instructions here on the wiki? You likely have an issue with your kernel where you configure the middleware names.
ReflectionException in Container.php line 741:
Class Tymon\JWTAuth\src\MiddlewareGetUserFromToken does not exist
There probably shouldn't be a \src\ in there. That's part of the file structure, but it isn't reflected in the namespaces; the correct class is just Tymon\JWTAuth\Middleware\GetUserFromToken.
(This assumes version 0.5. The middleware classes all change in 0.6.)
for \src\ i detecte that and i change it but still some places where i forgot it,
thantks @tdhsmith now i havent the last error but i have an other error:)
{"error":"token_not_provided"}
i know that means user is not authenticated to access the route with middleware auth.
but how can i authenticated user to acces to this route:
$router->group(['prefix' => 'auth'], function () {
Route::get('test', ['middleware' => ['jwt.auth', 'jwt.refresh']], function(){
return response()->json(['foo'=>'bar']);
});
# Login
get('login', ['middleware' => ['jwt.auth', 'jwt.refresh'], 'as' => 'login', 'uses' => 'AuthController@login']);
post('login', ['as' => 'login.post', 'uses' => 'AuthController@login']);
get('logout', ['middleware' => ['jwt.auth', 'jwt.refresh'],'as' => 'logout', 'uses' => 'AuthController@logout']);
});
in class AuthController :
class AuthController extends BasePublicController
{
use DispatchesJobs;
/**
* API Login, on success return JWT Auth token
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request) {
$credentials = $request->only('email', 'password');
try {
// attempt to verify the credentials and create a token for the user
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['error' => 'could_not_create_token'], 500);
}
// all good so return the token
return response()->json(compact('token'));
}
/**
* Log out
* Invalidate the token, so user cannot use it anymore
* They have to relogin to get a new token
*
* @param Request $request
*/
public function logout(Request $request) {
$this->validate($request, [
'token' => 'required'
]);
JWTAuth::invalidate($request->input('token'));
}
}
i have in kernel :
'jwt.auth' => 'Tymon\JWTAuth\MiddlewareGetUserFromToken',
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
where can i set Authorization: Bearer {yourtokenhere} !!!
You must set it in the client. JSON Web Tokens are for exchanging information between a client app and server app.
How you set it will depend on what you are using for your client. For example, many people are using AngularJS, where you can create an http interceptor that attaches the header to requests (some use the Satellizer library which does most of this for you). In plain JS you can call something like request.setRequestHeader('Authorization', 'Bearer '+token); before sending the request. You don't even need to be using JS, there are server-to-server set ups and non-web applications that use JWT.
If you are looking for a simple way to start testing, maybe check out Postman? It's a free app you can use to create HTTP requests and test APIs.
thanks a lot @tdhsmith for your responses, as client i use blades templates( blade.html )
i inculde it with this method
header(' Authorization : Bearer {mytoken}');
?>
but still the header don't have the token when i check the header of the request :
print_r($request->headers->all());
header(...) is going to set the HTTP header going from server to client (the response). You need to set the header going from the client to server (the request). Though I'm not sure if Laravel even provides a way to do that... Blade generates your views, but it isn't really a "client". Your _client_ would be the HTML that Blade generates (in this case an empty document).
Also to be clear, you must replace the {mytoken} part with a token generated for the user.
To take a step back: why are you using JWTs? When everything is served from the same Laravel app (and there is no client code), you should probably be using sessions.
thanks @tdhsmith , i know that i must replace {mytoken} by my token,
for the raison why i use jwt : my application will communicate with mobile apps
look at this link http://blog.nedex.io/create-an-api-server-for-mobile-apps-using-laravel-5-1/ for more information about that
now i have this problem
TokenInvalidException in NamshiAdapter.php line 58: Could not decode token: The token "expzsveQMSNvz.UXpHcWH2gv9.vGpMXd6a" is an invalid JWS
Well according to http://jwt.io, that _isn't_ a valid token. (Even without the validator, it looks too short to have any of the expected content.)
How did you generate it?
i generate it with this instruction
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
$token = JWTAuth::attempt($credentials);
That is very weird, and something else must be happening. Are you doing any string operations on the token, or manipulating it in any way? What happens when you try to generate a token with hardcoded credentials? What about with JWTAuth::encode(JWTAuth::getPayloadFactory()->make());?
Ok, so this is an easy fix. In the Kernel.php file you need to add slashes to pull from the root namespace.
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
@jeffdupont : I've already done that;
thanks a lot @tdhsmith : i have question can i create the token when the user do the registre in my website !
because i want to save the value of token in database after register of user
and i did some test :
-when i create the token after login
public function postLogin(LoginRequest $request)
{
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
$token = JWTAuth::attempt($credentials);
print_r($token);
exit;
....
}
after execution of this code i get the token !
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL3Rlc3RjbXNsYXJhdmVsXC9lblwvYXV0aFwvbG9naW4iLCJpYXQiOjE0NTUxMDM3NzIsImV4cCI6MTQ1NTEwNzM3MiwibmJmIjoxNDU1MTAzNzcyLCJqdGkiOiI2ZTcxMTAyMWI5MDRkYTJkNTk3YTkwM2EwZDZlYWM0MyJ9.DHRYYY0hwKPzvL10eki2f7SYYERQXAyZ7ePiBHvJNNI
public function postRegister(RegisterRequest $request)
{
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
```
$token = JWTAuth::attempt($credentials);
print_r($token);
```
exit;
....
}
after execution, i get the null as value of token
@hamalatifa That fixed the error from the OP for me and I didn't see any reference to that in the comments, so I wanted to make sure that anyone finding this gets the correct solution.
Second, the postRegister method, you're trying to attempt to login a user that was just created? The code doesn't show that the Register is creating a user first, so the JWTAuth::attempt is probably failing. I think what you're looking for is to create the token from the newly created user object:
$user = User::first();
$token = JWTAuth::fromUser($user);
Then you can save the token back to the user.
@hamalatifa - There shouldn't be any reason for attempt to behave differently in those situations. I suspect your user provider must not be finding your new user for some reason. Can you try updating to the most recent master branch? It has a fix (#398) that isn't in 0.5.6 that should let you see if there are any exceptions happening in attempt.
I'd guess something is slightly different in your credentials, or perhaps you aren't actually creating the new user (as jeff suggests).
In any case, isn't it easier to do something like Auth::setUser($user) in your register function and then JWTAuth::fromUser(Auth::user()) in post-register?
@jeffdupont - Isn't User::first() going to get the first sequential user?
@tdhsmith yes User::first() get the first sequential user
@jeffdupont i will try your proposition thanks
finally i resolved this problem by getting the token after the registre of user
here is the code :
public function postRegister(RegisterRequest $request)
{
app('Modules\User\Services\UserRegistration')->register($request->all());
flash()->success(trans('user::messages.account created check email for activation'));
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
$token = JWTAuth::attempt($credentials);
$user=User::where('email','=',$request->email)->first();
$user->token=$token;
$user->save();
return redirect()->route('register');
}
On a sidenote, everyone make sure they keep close attention to where the slashes are in their Kenerl.php file. For me I was missing the "\" before "Tymon\JWTAuth...", etc. Hard to catch!
@jeffdupont thanks I had also forgotten to have the slashes at the beginning.
'jwt.auth' => \Tymon\JWTAuth\MiddlewareGetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
The best thing to do is to go to the Kernel.php file and change
'jwt.auth' => Tymon\JWTAuth\Middleware\GetUserFromToken::class, to
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
Most helpful comment
Ok, so this is an easy fix. In the Kernel.php file you need to add slashes to pull from the root namespace.