Accessing Laravel Api using POSTMAN (404 not found) - laravel

I wrote an API for User Login using Laravel 5.8
When I tested the Login on Postman, it generated an error.
Status: 404 Not Found.
The File Path is Http->Controllers->UserController->Login
The project is laravelapi. I used POST in Postman and added this:
http://localhost/laravelapi/public/user/api/login
But when I run php artisan serve and used:
http://localhost:8000/api/login
Status was OK.
Controller
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'));
}
api.php
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('login', 'UserController#login');
What do I do to make http://localhost/laravelapi/public/user/api/login work and have Status: OK
Thanks.

link must be localhost/laravelapi/public/api/login

Related

Laravel feature test using middleware

I'm trying to make a feature test for the start page of my Laravel application.
Route:
Route::domain('{subdominio}.'.env("APP_DOMAIN"))->middleware('mapNumserie')->group(function () {
Route::get('/', 'FarmaciaController#show')->middleware('modomtofarmacia')->name('inicio');
})
For some reasons, I use a middleware mapNumserie where I map the subdomain aganist a serial number $idfarmacia in order to use it after in controller:
public function handle($request, Closure $next){
try{
$route = $request->route();
$idfarmacia = \App\Farmacia::where('subdominio', $route->subdominio)->value('numserie');
$route->setParameter('idFarmacia', $idfarmacia);
$route->forgetParameter('subdominio');
}
catch (\Exception $e){
abort(404);
}
return $next($request);
}
In my ModoMtoFarmacia middleware I just check that an app instance is not in maintenance mode or disabled:
public function handle(Request $request, Closure $next){
$farmacia = \App\Farmacia::find($request->idFarmacia);
if($farmacia->inactiva){
abort(404);
}
if(!$farmacia->modomantenimiento){
return $next($request);
}
else{
return response()->view('errors.503')->setStatusCode(503);
}
}
In my controller symply get some data using this $idfarmacia and return a view:
public function show(Request $request, $idfarmacia) {
$data =
//Query...
if($data){
return view('inicio', ['data' => $data]);
}
else{
abort(404);
}
}
With a very simple test method I hope to validate a 200 response :
public function test_example(){
$response = $this->get('http://mysubdomain.domain.prj');
$response->assertStatus(200);
}
But when I run the test I get:
Expected response status code [200] but received 404.
The used URL works correctly in web environment, but the test fails. Where am I wrong?
Finally a found the problem in my phpunit.xml settings, which caused an error in the first query (also in any other), in this case the one found in the MapNumserie middleware:
$idfarmacia = \App\Farmacia::where('subdominio', $route->subdominio)->value('numserie');
I had to set up properly the values of DB_DATABASE and DB_CONNECTION

Laravel 8.61.0 - redirection not working after login

I have facing the issue for after login user page 404 error. Please check the below code and help me the issue solve.
web.php
Route::get('/login','UserAuthController#login');
Route::post('/login-user','UserAuthController#LoginUser')->name('login-user');
Route::get('user/myprofile','UserAuthController#UserDashboard');
//Route::get('user/myprofile','UserAuthController#UserProfile')->name('UserProfile');
UserAuthController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Users;
use Hash;
use Session;
class UserAuthController extends Controller
{
public function login(Request $request)
{
return view('pages.login');
}
protected function LoginUser(Request $request)
{
$request->validate([
'username'=>'required',
'password'=>'required'
],[
'username.required'=>"The User Name is Required.",
'password.required'=>"The Password is Required."
]);
$user = Users::where('username', '=', $request->username)->where('status', '=', 1)->first();
if ($user){
if (Hash::check($request->password, $user->password)){
$request->session()->put('userId',$user->userid);
//return redirect('user.myprofile');
//return redirect()->route('user.myprofile');
//return redirect()->intended('user/myprofile');
return redirect('UserDashboard');
}else{
return back()->with('fail', 'Password not matches. Please try again!!');
}
}else{
return back()->with('fail', 'This Username is not registered.');
}
}
public function UserDashboard (){
return view('user.dashboard');
}
}
After Login Page
http://127.0.0.1:8000/UserDashboard
404 NOT FOUND
Hi Replace your code from
return redirect('UserDashboard');
to
return redirect('user/myprofile');
You should redirect with name route like:
Route::get('user/myprofile','UserAuthController#UserDashboard')->name('user-profile');
In Controller:
return redirect()->route('user-profile');
Also, make sure user.dashboard view file exist.

Call to a member function tokens() on null on Laravel Sanctum

I get this error when i am trying to logout the user
public function logout(Request $request)
{
$request->user()->tokens()->delete();
}
You need to include the API route inner the Sanctum Auth middleware like below:
Route::group(['middleware' => ['auth:sanctum']], function() {
Route::post('logout', [AuthController::class, 'logout']);
});
Auth::user()->token() is only valid by passing the Sanctum middleware.
Check this #1
Check this #2
This worked for me, Change this code in your Controller.php to,
public function logout(Request $request){
Auth::user()->tokens()->delete();
return [
'message' => 'logged out'
];
}
And make sure your Route POST request is protected in api.php, change the code to below
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
use token() instead of tokens()
$request->user()->token()->delete();
Or you can use it as below.
Auth::user()->tokens->each(function($token, $key) {
$token->delete();
});
by using revoke
$user = $request->user();
foreach ($user->tokens as $token) {
$token->revoke();
}

Laravel:Error when Implementing JWT authentication

I am experiencing an error when trying to post the API through Postman to authenticate users in the site.
login function:
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
the guard function
public function guard()
{
return Auth::guard();
}
The error shown on postman
"message": "Call to undefined method Tymon\\JWTAuth\\Contracts\\Providers\\Auth::guard()",
"exception": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError",
How to solve this?
You can use \JWTAuth::attempt function in order to get token if the user inserts valid email and password like:
....
use Tymon\JWTAuth\Exceptions\JWTException;
....
try {
$token = \JWTAuth::attempt($request->only('email', 'password'));
return $this->respondWithToken($token);
} catch (JWTException $exception) {
return response()->json([
'status' => false,
'data' => null,
'message' => 'Could not create token'
]);
}
EDIT 1
The above answer you submitted is correct.
try replacing Auth::guard() to Auth::guard('api')
public function guard()
{
return Auth::guard('api');
}
For more information there is a similar issue in GitHub for reference
Use a construct method like
public function __construct(){
auth()->setDefaultDriver('api');
}
and your login function like
public function login(){
$credentials = request(['email', 'password']);
if(!$token = auth()->attempt($credentials)){
return response()->json(['error' => 'Incorrect email/password'], 401);
}
return $this->respondWithToken($token);
}
And comment out your guard function
I have faced this problem continuously. But the solution was when I used bcrypt() on the password.
bcrypt($password);
Use dependency injection and inject the Auth interface into your class. Code example below.
From the Tymon package import the Auth interface.
use Tymon\JWTAuth\Contracts\Providers\Auth;
In your constructor
public function __construct(Auth $auth)
{
$this->_authentication = $auth;
}
Then use the "byCredentials" method
if (! $token = $this->_authentication->byCredentials($credentials))
{
return response()->json(['message' => 'Unauthorized'], 401);
}

Change Password using API Laravel

I was trying to do the change password using API Laravel. But it didn't work. I'm new to API Laravel.
Any suggestion to solve my problem?
public function __construct()
{
$this->middleware('auth');
}
public function store(ChangePasswordValidation $request)
{
if(Auth::check($data['current_password'], $user->password))
{
$user = User::find(Auth::user()->id)->update(["password"=> bcrypt($request->password)]);
$success['token'] = $user->createToken('newToken')->accessToken;
return response()->json(['success' => $success], 200);
}
else
{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
the result shown in Postman is:
{
"message": "Unauthenticated."
}
You need to use guard as you are using API
so change
Auth::user()
To
Auth::user('api')
also
$this->middleware('auth');
To
$this->middleware('auth:api');
Edit this line
if(Auth::check($data['current_password'], $user->password))
Into
if(Auth::check($request['current_password'], $user->password))

Resources