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
Related
{
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
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();
}
}
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!
I created a user auth system based on Passport in my app and now I have some troubles. When I send a token, my details() method returned all app users instead of specific one. I paste my code to show exactly what is going on.
Login method:
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('myapp')->accessToken;
$user->api_token = $success['token'];
$user->save();
return response()->json(['user' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
It return something like that:
{
"user": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFjMzEwM2UyMzIwNGIxMjg3M2E3ZWMyZmUyNGJkNDEzMTQyN2I1ZWUzMWRjOGFhZjRhMzcyMDQzM2ZmNGJiZGJjZGU3ZjQ1ZjZkNzZmMGRkIn0.eyJhdWQiOiIxIiwianRpIjoiYWMzMTAzZTIzMjA0YjEyODczYTdlYzJmZTI0YmQ0MTMxNDI3YjVlZTMxZGM4YWFmNGEzNzIwNDMzZmY0YmJkYmNkZTdmNDVmNmQ3NmYwZGQiLCJpYXQiOjE1NTIxMzIyODMsIm5iZiI6MTU1MjEzMjI4MywiZXhwIjoxNTgzNzU0NjgzLCJzdWIiOiIxOCIsInNjb3BlcyI6W119.LmwTCSlRTrZ9pq01JK6tfsx5yjjA9qfidTws-0_vVc-UsFKQOJSk-K1uAYMR5gd0SQzC8VyG8bIJLVdPZbm5ggXkk-itN1bHEdZPFT7zdx7rOTFVF1ri9-chZIDL6nElosk3SOw_1QwuwOxiMHBB7ss9ItPHrtwkNEMxpeh16henknIZVYct0Vn1grztdnh7EJCM9SkKjIxqF0yozuw-wsN-UmsLvNoFZkOFWuNCPC9Mawx_ip2VBD26mwcxzTgD1XFwRloTCtDOAZfQ4DfgS_YuuXEPn8pfrkp92C1lxGXp09Wu0ZdzFaIf8LWEQXCgwlqvsVuFSnKt3lGyEPuHuJc_DjZZTcWgjslVQr7RhEqWQmRK2xlJpiAcZyWoI1vhfYLmullr1vf7nGCoRsp3UDZB64J2oPVjomcClEfseAKQbIq_9roKxIGjTeYdaF2vwHCosaxzrak7AqBHkze-z5cL8ix9G6rWBeg4sDUPhiLDgrgHK4ywxBqHMyto-Ywak56pzq1767r4reunDyNYDhLwSt0IiK1Hmx7ZQ9j6_EWy3NLf1oy7eGc33bj7eQNusbEa0TfcXujNK299RAEnTFLEc4kuS_otHzGrwSvOx2zYPsZkctZYn19YoyKaeP7hM1ek0zfIlGXsxQI84osPl91U7PHqAufIK6YJeizcik0"
}
}
When I have my token for specific user I send that token to details().
Details method:
public function details(Request $request)
{
$userData = $request->user()->with('kids')->with('hobbies')->with('conversations')->get();
return response()->json(['user' => $userData], $this->successStatus);
}
Here is my api.php route file:
Route::group(['middleware' => 'auth:api'], function(){
Route::get('details', 'UserController#details');
});
Route::post('login', 'UserController#login');
Route::post('register', 'UserController#register');
I don't know why my details method return all app users. Do you have any advice how I can fix that? I really appreciate any help with that trouble.
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.