I use auth:api middleware in controller (Laravel 5.2).
class RestfulController extends Controller
{
public function __construct() {
$this->middleware(['api', 'auth:api'], ['except' => ['login'] ]);
}
}
routes:
Route::group(['prefix' => 'api'], function () {
Route::get('/login', ['uses' => 'RestfulController#login', 'as'=>'login']);
Route::get('/list', ['uses' => 'RestfulController#list', 'as'=>'list']);
});
If request doesn't contain or contains invalid api_token framework redirects to login page. Instead I would like to return JSON response with error. How it can be implemented?
change app/Http/Middleware/Authenticate.php handle method,it will response json
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
$response = [
'status' => 'error',
'message' => 'This is error message'
];
return Response::json($response);
}
}
return $next($request);
}
You should check api and auth:api middleware group and look for witch one is doing it. If it's inside a vendor package, you'll need to extend it and make your changes.
Related
I have route api.php like so
Route::group(['middleware' => ['jwt.verify']], function() {
Route::get('logout', [ApiController::class, 'logout']);
Route::get('pengguna', [ApiController::class, 'getAuthenticatedUser']);
Route::get('get_kabupaten/{provid}', [KabupatenController::class, 'get_kabupaten']);
Route::get('get_kecamatan/{kabid}', [KecamatanController::class, 'get_kecamatan']);
Route::get('get_kelurahan/{kecid}', [DesaController::class, 'get_kelurahan']);
Route::get('get_bencana', [JenisbencanaController::class, 'get_bencana']);
Route::get('saport', [ReportController::class, 'get_laporan']);
Route::post('saport/create', [ReportController::class, 'store']);
Route::get('saport/{id}', [ReportController::class, 'show']);
// Route::get('laporan', [LaporanController::class, 'get_laporan']);
// Route::post('laporan/create', [LaporanController::class, 'store']);
// Route::get('laporan/{id}', [LaporanController::class, 'show']);
// Route::put('update/{product}', [LaporanController::class, 'update']);
// Route::delete('delete/{product}', [LaporanController::class, 'destroy']);
});
all everything else work except
Route::get('pengguna', [ApiController::class, 'getAuthenticatedUser']);
Route::get('saport', [ReportController::class, 'get_laporan']);
Route::post('saport/create', [ReportController::class, 'store']);
Route::get('saport/{id}', [ReportController::class, 'show']);
and this my reportcontroller
<?php
namespace App\Http\Controllers;
use App\Models\Laporan;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\Validator;
use Auth;
class ReportController extends Controller
{
public function get_laporan()
{
$laporan=Laporan::where('user_id', Auth::id())->get();;
return response()->json(compact('laporan'));
}
public function store(Request $request)
{
$data = $request->only( 'desa_id','bencana_id','koordinat','korban_kk','korban_orang','sebab_bencana');
$validator = Validator::make($data, [
'desa_id' => 'required',
'bencana_id' => 'required',
'koordinat' => 'required',
'korban_kk' => 'required',
'korban_orang' => 'required',
'sebab_bencana' => 'required',
]);
//Send failed response if request is not valid
if ($validator->fails()) {
return response()->json(['error' => $validator->messages()], 200);
}
$laporan = new Laporan;
$laporan->bencana_id = $request->bencana_id;
$laporan->desa_id= $request->desa_id;
$laporan->koordinat= $request->koordinat;
$laporan->user_id= Auth::id();
$laporan->korban_kk= $request->korban_kk;
$laporan->korban_orang= $request->korban_orang;
$laporan->sebab_bencana= $request->sebab_bencana;
$laporan->bantuan_diperlukan= $request->bantuan_diperlukan;
$laporan->respon_instansi= $request->respon_instansi;
$laporan->lokasi_pengungsian= $request->lokasi_pengungsian;
$laporan->pengungsi_kk= $request->pengungsi_kk;
$laporan->pengungsi_orang= $request->pengungsi_orang;
$laporan->permintaan_bantuan= $request->permintaan_bantuan;
$laporan->save();
return response()->json([
'success' => true,
'message' => 'laporan telah di input',
'data' => $laporan
], Response::HTTP_OK);
}
public function show($id)
{
$laporan=Laporan::where('user_id', Auth::id())->find($id);;
if (!$laporan) {
return response()->json([
'success' => false,
'message' => 'Sorry, Laporan not found.'
], 400);
}
return response()->json(compact('laporan'));
}
}
i have rename int from laporan to report to saport, create new controller, and make it HTTPS for saport always return 400.
as far as i know the structure of controler the same with other controller, couse i use meke:controller, and why it return 400 400 Bad Request.
and i make new basic route, and it return 400
Route::get('saport', function () {
return 'Hello World';
});
cahche:clear
route:clear
dumptautoload
trying remove saport from outside jwt,verify
all return 400
i have try all.
btw in local it run like charm, it case only in sharehosting.
i think it postman issue, not laravel. but if any solve for it issue please tell me
{
public function handle($request, Closure $next)
{
if (! $request->expectsJson()) {
abort(response()->json([
'success' => false,
'data' => 'Unauthorize'
]));
}
return $next($request);
}
}
I tried this but doesn't matter whether the condition is true, it nevershows me data i should / souldn't be able to see (doesn't matter that I provide a token or no).
This is how I call it in controller
public function __construct()
{
$this->middleware('auth:api');
}
api.php
Route::group([
'middleware' => 'api',
], function ($router) {`
Route::post('login', [\App\Http\Controllers\AuthController::class, 'login']);
Route::post('register', [\App\Http\Controllers\AuthController::class, 'register']);
});
in app/Exceptions/Handler.php add this
use Illuminate\Auth\AuthenticationException;
protected function unauthenticated($request, AuthenticationException $exception)
{
return $request->expectsJson()
? response([
'success' => false,
'data' => 'Unauthorize'
])
: redirect('/login');
}
NOTE:_ it will work if you add header Accept:application/json
As a checklogin function in my Controller I have
public function checkLogin(Request $request)
{
//if the validation rule isn't passed it will be redirected to login form with validation error
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:3'
]);
$user_data = array(
'email' => $request->get('email'),
'password' => $request->get('password'),
);
if (Auth::attempt($user_data)) {
return redirect('/successlogin');
//user will be redirected to successlogin method
} else {
return back()->with('error', 'Wrong Login Details');
//by using back() he will be redirected to the previous location
}
}
And I added a $table->boolean('is_admin')->default(0); column to my model
Also I've tried to make a middleware. Something like
IsAdmin.php
public function handle($request, Closure $next)
{
if (Auth::user()) {
if (Auth::user()->is_admin) {
return $next($request);
}
return Redirect::to('successlogin');
}
}
But it throws me an error
"Call to a member function send() on null"
Thanks a lot in advance!
when I login with wrong credentials I got the right response.
when I login with the right credentials the login page reload with 302 request
but it never redirect to statistics page.
when I debug it I found that the code goes to this authinticate.php in the middleware folder,
it redirect to the guest login state
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
see the code:-
Route.php
Route::get('login', 'LoginController#index');
Route::post('signin', 'LoginController#signin');
Route::get('signout', 'LoginController#signout');
Route::group(['prefix' => 'api'], function() {
Route::resource('authenticate', 'AuthenticateController', ['only' => ['index']]);
Route::post('authenticate', 'AuthenticateController#authenticate');
});
Route::group(['middleware' => ['web']], function () {
Route::auth();
Route::get('/', 'StatisticsController#index');
Route::get('/statistics', 'StatisticsController#statistics');
});
Login Controller
public function index() {
return view('login');
}
public function signin(Request $request) {
$errors = [];
$email=$request['email'];
$password= $request['password'];
$credentials = array('email' => $email, 'password' => $password);
if(Auth::attempt($credentials))
{
return redirect('/statistics');
}
return "bad request";
}
public function signout()
{
Auth::logout();
return redirect('/login'); }
}
Statistics Controller
class StatisticsController extends Controller {
public function __construct()
{
$this->middleware('auth');
}
public function index() {
return view('statistics')->with($data);
}
public function statistics() {
return view('statistics');
}
}
Kernal.php note that there is JWT auth library I use it for restful authentication with the mobile app only.
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken'
];
middleware/authenticate.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
Check your cache.I had a similar problem, where I lost a couple of hours, so these where some of the steps I've made:
php artisan route:clear
clear browser cache
run composer update
Download a fresh copy of laravel(new project), and then slowly merge chunks of your code into the new project
Quick Analysis:
There's no problem with your Authentication method, or your controllers.
The problem lies with the fact that you don't have a route for "/statistics"
And with Laravel at-least starting version 5, you have to be explicit about your routes "PS: they deprecated Route::Controller()"
By the way
Route::get('/', 'StatisticsController#index');
Refers to your application base route
Solution
Add the statistics route
Route::get('/statistics', 'StatisticsController#statistics');
For example.
You are redirecting to StatisticsController#statistics but there is no statistics function defined in your StatisticsController.
I'm using laravel 5.1 and the modular package.
In my controller I use the following login method:
public function postLogin(Request $request)
{
$email = $request->input('email');
$password = $request->input('password');
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return redirect()->intended('admin/dashboard');
}
return redirect('/login')->withErrors([
'email' => 'These credentials do not match our records.']);
}
My route:
Route::group(array('module' => 'Admin', 'namespace' => 'App\Modules\Admin\Controllers'), function() {
Route::get('admin/dashboard', [
'middleware' => 'auth',
'uses' => 'AdminController#index'
]);
}}
My controller:
public function index()
{
return view("Admin::index");
}
My Middleware/Authenticate:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
return $next($request);
}
This works and redirects me to the index view after login.
When the user is not logged in, it is still possible to access the index view by accessing the url: localhost/admin/dashboard.
How can I redirect the user to a custom page which shows an error to the user that it is not possible to access the url localhost/admin/dashboard when he is not logged in?
Any ideas? Thank you
The issue is with your route the middleware should be at the top level as soon as you hit the controller it should redirect if not authenticated
Route::group(['middleware'=>'auth','module' => 'Admin', 'namespace' => 'App\Modules\Admin\Controllers'], function()
{
Route::get('admin/dashboard', ['uses' => 'AdminController#index']);
});
secondly if you want to redirect user to a custom page you can do this
public function redirectUnAuthenticateUser()
{
\Session::flash('login_error', 'Kindly login before you can access this page');
//create a view that user would be redirected to
return view('session.unauthenticated') ;
}
and the change your auth function to below
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->route('you-custom-rout-name-matching-above-function');
}
}
return $next($request);
}
and on your view you can get the value of the flash message