Undefined Variable: token in Laravel Login Postman test - laravel

I wrote an API in Laravel 5.8 for User Login and Register.
I use JWTAuth in Laravel 5.8. When I tested the Login on Postman, it generated an error, undefined variable: token. I tried to write the API for register, when I tested it, it worked perfectly. Based on what I saw online, I tried adding \Illuminate\View\Middleware\ShareErrorsFromSession::class, to the kernel but still the same error.
LoginController
public function login(Request $request)
{
$credentials = $request->json()->all();
try
{
if(! $token == JWTAuth::attempt($credentials))
{
return response()->json(['error' => 'invalid_credentials'], 400);
}
}
catch(JWTException $e)
{
return response()->json(['error' => 'could_not_create_token'], 500);
}
return response()->json(compact('token'));
}
public function register(Request $request)
{
$validator = Validator::make($request->json()->all() , [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
'username' => 'required|string|max:255',
]);
if($validator->fails()){
return response()->json($validator->errors()->toJson(), 400);
}
$user = User::create([
'name' => $request->json()->get('name'),
'email' => $request->json()->get('email'),
'password' => Hash::make($request->json()->get('password')),
'username' => $request->json()->get('username'),
]);
$token = JWTAuth::fromUser($user);
return response()->json(compact('user', 'token'), 201);
}
api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('register', 'UserController#register');
Route::post('login', 'UserController#login');
Route::get('profile', 'UserController#getAuthenticatedUser');
I expected success, but it gave error:
ErrorException: Undefined variable: token in file C:\xampp\htdocs\laravelapi\app\Http\Controllers\UserController.php on line 52
This is my line 52:
if(! $token == JWTAuth::attempt($credentials))

define $token before line 52
$token = null;

You should use assignment operator and not equal ==:
$token = JWTAuth::attempt($credentials))
Also in the login function you should generate a token from user to return
public function login(Request $request)
{
$credentials = $request->json()->all();
try
{
if(! $token = JWTAuth::attempt($credentials))
{
return response()->json(['error' => 'invalid_credentials'], 400);
} else {
// Generate token from user
$token = JWTAuth::attempt($credentials);
return response()->json(compact('token'));
}
}
catch(JWTException $e)
{
return response()->json(['error' => 'could_not_create_token'], 500);
}
}

Related

Laravel forgot and reset password API with jwt authentication

please am trying to create a forgot password and reset password API in Laravel using JWT but it gave me this error ' "email": "passwords.throttled"',
I want it to send a password reset link to the email provided but it gives me that error.
or if anyone has any idea of how I will go about it
please can anyone help
this is my code
public function forgotPassword(Request $request){
// $request->validate(['email' => 'required|email']);
$email = $request->only('email');
$rules = ['email'=>'required:users,email'];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
// handler errors
$erros = $validator->errors();
// echo $erros;
return $erros;
}else{
$user = User::where('email', '=', $email)->first();
try {
// verify the credentials and create a token for the user
if (! $token = JWTAuth::fromUser($user)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
// return response()->json(compact('token'));
$status = Password::sendResetLink($email);
return $status === Password::RESET_LINK_SENT
? response()->json(['status' => $status])
: response()->json(['email' => $status]);
}
}
public function resetPassword(Request $request)
{
// $this->validate($request, [
// 'token' => 'required',
// 'email' => 'required|email',
// 'password' => 'required|confirmed',
// ]);
$rules = ['email'=>'required:users,email','password' => 'required|confirmed',
'token'=>'required '];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
// handler errors
$erros = $validator->errors();
// echo $erros;
return $erros;
}else{
$credentials = $request->only(
'email', 'password', 'password_confirmation', 'token'
);
// $response = $request->password->reset($credentials, function($user, $password) {
// $user->password = bcrypt($password);
// $user->save();
// $this->auth->login($user);
// });
// return json_encode($response);
}

How can I delete the token when the user log out?

I made a UserController which generats an accessToken when a user registered succesfully on a page.
class UserController extends Controller
{
/**
* Login Method: in here we call Auth::attempt with the credentials the user supplied.
* If authentication is successful, we create access tokens and return them to the user.
* This access token is what the user would always send along with all API calls to have access to the APIs.
* Register Method: like the login method, we validated the user information,
* created an account for the user and generated an access token for the user.
*/
public function login()
{
$credentials = [
'email' => request('email'),
'password' => request('password')
];
if (Auth::attempt($credentials)) {
$success['token'] = Auth::user()->createToken('MyApp')->accessToken;
return response()->json(['success' => $success]);
}
$status = 401;
$response = ['error' => 'Unauthorized'];
return response()->json($response, $status);
}
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'password' => 'required',
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors()], 401);
}
$input = $request->all();
$input['password'] = bcrypt($input['password']);
$user = User::create($input);
$success['token'] = $user->createToken('MyApp')->accessToken;
$success['name'] = $user->name;
return response()->json(['success' => $success]);
}
public function getDetails()
{
return response()->json(['success' => Auth::user()]);
}
}
My problem is that I want to remove the token when the user logs out but I dont know how to remove the access token from the user.
logout function in my UserController
public function logout()
{
Auth::user()->tokens->each(function($token, $key) {
$token->delete();
});
return response()->json([
'message' => 'Logged out successfully!',
'status_code' => 200
], 200);
}
When I test it with postman with the GET route: http://127.0.0.1:8000/api/logout. Am I missing something?
UPDATE
Here s my api.php file:
Route::resource('categories', 'App\Http\Controllers\CategoryController');
Route::post('register', 'App\Http\Controllers\UserController#register');
Route::post('login', 'App\Http\Controllers\UserController#login');
/**
* We can group the routes we need auth for
* under common middleware. It secures our routes
*/
Route::group(['middleware' => 'auth:api'], function(){
Route::get('logout', 'App\Http\Controllers\UserController#logout');
});
I am testing it in postman using the route: http://127.0.0.1:8000/api/logout and passing the Bearer token, which I get from the login request, as a value.
It should be POST Request instead of GET request, because your deleting/making change to the database.
The route should look like this:
Route::POST('logout', 'App\Http\Controllers\UserController#logout')->middleware('auth:api');
And the logout method in in UserController should be.
public function logout()
{
auth()->user()->tokens->each(function ($token, $key) {
$token->delete();
});
return response()->json([
'message' => 'Logged out successfully!',
'status_code' => 200
], 200);
}
In your logout function, it should expire the token, not delete it
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([], Response::HTTP_NO_CONTENT);
}
OR if you wanna expire all his tokens:
use Illuminate\Support\Facades\Auth;
public function logout(Request $request)
{
$userTokens = Auth::user()->tokens();
foreach($userTokens as $token)
{
$token->revoke();
}
}

Laravel, JWT authentication is successful but check return false

I use this class for multiple projects and I never had any problems,
Today impossible to check user after JWT authentication
public function check()
{
return response()->json( Auth::guard()->check());
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = Auth::guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['message' => __('commons.response.error.login')], 401);
}
protected function respondWithToken(string $token)
{
return response()->json([
'check' => Auth::guard()->check(),
'access_token' => $token,
'token_type' => 'bearer',
'auth' => true,
'me' => Auth::guard()->user(),
'message' => __('commons.response.success.login', ['user' => Auth::guard()->user()->name]),
]);
}
The login function returns the user and check return true
After that, check() return false
any idea ?
Thank you
Edit
I find it, it was a front end issue, the request token cannot be found
axios.defaults.headers.common['Authorization'] = `Bearer ` + localStorage.token;
I miss the line
localStorage.setItem('token', r.data.access_token);
Done

Laravel passport create token doesnt work on plesk server

I use passport in my laravel project to authenticate users by api. API work correctly on my local host. But after i deploy it on Plesk server token doesnt create. Always show Server Error.
public function login(Request $request) {
$validator = Validator::make($request->all(),[
'email' => 'required',
'password' => 'required',
]);
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$email = $request->email;
$password = $request->password;
error_log($password);
$user = DB::table("users")->where([["email", "=", $email]])->first();
if(is_null($user)) {
return response()->json(["success" => false, "message" => "User doesn't exist"]);
}
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
$token = $user->createToken('token')->accessToken;
$success['success'] = true;
$success['user'] = $user;
$success['message'] = "Success! you are logged in successfully";
$success['token'] = $token;
return response()->json(['success' => $success ], 200);
} else {
return response()->json(['error' => 'Unauthorised'], 401);
}
}
$token = $user->createToken('token')->accessToken;
This line throw error
Problem was in my AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'Medicare\Model' => 'Medicare\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
Passport::routes();
//
}
}
After i commented 'Medicare\Model' => 'Medicare\Policies\ModelPolicy' everything works fine.

how to create a token in laravel tymons/jwt-auth

I want to create a token encoded with user role. I have tried with seeing the documentation, But I am not getting a token. what I have tried.
I am using laravel 5.8 and package version "tymon/jwt-auth": "^1.0.0-rc.2"
Thank you
AuthController
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = auth()->guard('api')->attempt($credentials)) {
return response()->json(['errors' => 'In-valid username and Password'], 401);
}
$customClaims =[
'role' => auth('api')->user()->getRoleNames()
];
$payload = JWTFactory::make($customClaims);
$token = JWTAuth::encode($payload);
return $this->respondWithToken($token);
}
protected function respondWithToken($token)
{
return response()->json([
'success' => true,
'access_token' => $token,
'token_type' => 'bearer',
]);
}
Based on the documentation, you might need to do attempt() twice, like this:
public function login()
{
$credentials = request(['email', 'password']);
if (!auth()->guard('api')->claims(['role' => 'bar'])->attempt($credentials)) {
return response()->json(['errors' => 'In-valid username and Password'], 401);
}
$token = auth('api')->claims(['role' => auth('api')->user()->getRoleNames()])->attempt($credentials);
return $this->respondWithToken($token);
}
Your User MOdel should like this
class User extends Authenticatable implements JWTSubject
{
use Notifiable, HasRoles;
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
}
public function login()
{
$credentials = request(['email', 'password']);
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json(['errors' => 'In-valid username and Password'], 401);
}
$customClaims =[
'role' => auth('api')->user()->getRoleNames()
];
$payload = JWTFactory::make($customClaims);
$token = JWTAuth::encode($payload);
return $this->respondWithToken($token);
}
Try This
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthenticateController extends Controller
{
public function login(Request $request)
{
// grab credentials from the request
$credentials = $request->only('email', 'password');
try {
// attempt to verify the credentials and create a token for the user
if (!auth()->guard('api')->claims(['role' => 'bar'])->attempt($credentials))
{
return response()->json(['errors' => 'In-valid username and Password'], 401);
}
$token = auth('api')->claims(['role' => auth('api')->user()->getRoleNames()])->attempt($credentials);
return $this->respondWithToken($token);
} 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'));
}
}

Resources