Laravel Passport API Multiple Middleware - laravel

Is it even possible to have multiple middleware in one route. Right now i have my web app making ajax requests with the middleware of auth, which is defaulted at auth:web
Route::post('/user/postAuthUserInfoAjax', [
'uses' => 'UserController#postAuthUserInfoAjax',
'middleware' => ['auth'],
]);
I also want my mobile app, which has an API Access token(using laravel passport) to authenticate a user to be able to access those same routes. In order to do that I just specify 'auth:api' in my middleware.
Route::post('/user/postAuthUserInfoAjax', [
'uses' => 'UserController#postAuthUserInfoAjax',
'middleware' => ['auth:api'],
]);
The only problem is I cant specify multiple middlewares. I can either use 'auth:api' or 'auth:web' but not both. I guess I could just have two routes for each ajax request one for the web app and another for the api requests, but it would be so much better if I could just use one route.
I have tried, but it doesnt work. Does anyone know how to do this? is it even possible
Route::post('/user/postAuthUserInfoAjax', [
'uses' => 'UserController#postAuthUserInfoAjax',
'middleware' => ['auth:web','auth:api'],
]);

This won't work because you're saying the following:
Before processing this request, validate that the user is authenticated through the web provider, however, they also must be authenticated through my api provider as well.
One way that you could approach this is to just have two controllers, but extend a base controller with the functionality already baked in:
App
|
---- Http
|
---- Controllers
|
---- UserController (this will be our base)
---- API
|
---- UserController (will extend the base)
---- Web
|
---- UserController (will extend the base)
Then you should set up route groups accordingly:
//Your "web provider" authenticated routes
Route::group(['middleware' => ['auth:web'] 'namespace' => 'Web', function(){
});
Then for your API requests:
//your "api provider" authenticated routes
Route::group(['middleware' => ['auth:api'], 'namespace' => 'API', function(){
});
This is the route we'll put inside both of our groups:
Route::post('user/info', 'UserController#info');
Then the base controller should look something like this:
class UserController extends App\Http\Controller {
/**
* Update the specified User Resource
*
* #param Illuminate\Http\Request $request
* #param App\User $user
*
* #returns mixed
*/
public function update(Illuminate\Http\Request $request, App\User $user)
{
if ($request->ajax()) {
try {
DB::transaction(function() use ($request, $user) {
$user->update($request->only($user->getFillable()));
});
DB::commit();
} catch (\Exception $e){
DB::rollback();
return response()->json($e->getMessage(), 422);
}
}
}
}
Note I'm typing this without access to real code, so the $user->getFillable() may return a collection requiring you to convert it to an array. if that's the case, just chain $user->getFillable()->toArray() on to the end.
The magic in this is that if the process requests successfully, you can capture that with .done() on the promise object. If it fails, then you'll get a 422 Unprocessable Entity in Request message back which will trigger your .fail() on the promise object.
Now, simply extend this base UserController from both of your API/Web UserControllers:
<?php
namespace App\Http\Controllers\Api;
class UserController extends App\Http\Controllers\UserController {
}
While you have to do some duplication of logic, it's important to maintain that level of separation throughout your application stack for clarity. This method will still allow you a level of granular control if you still need to alter things for either of the routes, but gives you a base to work from.
Hopefully this helps.

Related

Laravel Passport post route test on postman

I set up Laravel Passport and started to create a few Get routes to get some data, that worked fine.
Now I am trying to post to get on auth token, which currently does not work:
This is my route which I call (Get route works, Post route does not work):
Route::group(['middleware' => 'auth:api'], function ()
{;
Route::get('users', ['as' => 'users', 'uses' => 'ApiController#users']);
Route::post('login/{id}/{name}', ['as' => 'login', 'uses' => 'ApiController#login']);
});
The method in my ApiController looks currently like this:
public function login(Request $request, $id, $name)
{
if($request->isMethod('post'))
{
$id = $request->id;
$name = $request->name;
$inquiry = new Inquiry();
$inquiry->user_id = $id;
$inquiry->user_name = $name;
if($inquiry->save())
{
return redirect()->route('inquiry.index')->with('success', 'Success.');
}
else
{
return redirect()->route('inquiry.index')->with('error', 'An error accured.')->withInput();
}
}
else
{
dd("Use Post.");
}
}
I tried to call it with following options:
Edit
I somehow managed to get this work after many hours, but still dont understand something.
First I did following:
public function callback(Request $request)
{
dd($request->code) // this holds a token I need for the code parameter in the post
...
With that I could get the token for the code parameter, but I think there is a better way to do that.
And finally this is now how I get the access + refresh token:
But there has to be a better way to get the code token of the callback request ($request->code), instead of dumping it and copying it.
The problem is that you have your login route inside a route group with auth:api on it. This means the user needs to be authenticated to even be able to authenticate. Just remove the login route outside the group and you should be fine.
You should call the Passport::routes method within the boot method of your AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
/oauth/authorize route is already defined by the Passport::routes method. You do not need to manually define this route.

Permission for URLs in Laravel?

May be this type of questions already exits but i didn't find proper solution. I am new in Laravel so sorry for this question.
I am creating a laravel application where user will login and will be access information .
My questions is how to prevent user to access direct URLs.
Put your routes under 'auth' middleware in routes.php file, that way only authenticated users will able to access.
for example like below:-
Route::group(['middleware' => ['auth']], function () {
Route::get('dashboard', [
'uses' => 'DashboardController#index',
'as' => 'dashboard.index',
]);
});
Or you can write custom middleware for user validation.
Adding to Rakesh's answer,
you can also apply the middleware to the controller for the routes you need protected via the constructor.
public function __construct()
{
$this->middleware('auth');
}

Redirect to Login page if ther user not logged in Laravel

I am using Laravel version 5. I have a route file for my project which contains plenty of lines. I need to put authentication like Redirect to login page if the user is not logged in. And I also want to prevent direct URL access if the user not logged in. What can I do?
And I have used below code
Route::group(array('before' => 'auth'), function(){
Route::get('/', 'HomeController#index');
});
But this prevents only for home page. I need to protect All my routes. And also suggest me how to reduce route file lines.
You can put as many routes in a Group as you like to
Route::group(array('before' => 'auth'), function(){
Route::get('/', 'HomeController#index');
Route::post('store', 'HomeController#store');
Route::get('show', 'AnotherController#index');
// ...
});
If you really need to protect all your routes, you could add
public function __construct()
{
$this->middleware('auth');
}
To your main controller class, Http/Controllers/Controller
Edit for your comment, taken from the docs, you may use
return redirect()->intended('view');
/**
* Handle an authentication attempt.
*
* #return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password]))
{
return redirect()->intended('dashboard');
}
}
}

Laravel 5 Authentication: change the default routes

I have just set up my Laravel installation and I have been reading the documentation and it appears that it ships with a authentication system built in. Which I would like to use rather than build my own ( which I have done in the previous version)
My question is I would like to change the default routes and the structure to something like:
www.example.com/register and www.example.com/login
At the moment it uses an auth folder so www.example.com/auth/register and www.example.com/auth/login
I just think that my way is cleaner and more user friendly. I would also like to change the forgot password to www.example.com/forgot-password
I have tried various examples and even new routes etc but I keep getting a not found exception. It is just bugging me as I would like to keep what is already there but alter it slightly as they say dont fix what is not broken.
Hopefully someone can point me in the right direction.
By default the default auth routes use Route::controllers(['auth' => 'Auth\AuthController']), the Route::controller() method generates the routes based upon the functions available on the controller.
You should be able to remove this line and create your own routes for them. If you look at the Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers trait you can see the functions available. Simply map your routes to those functions available on your auth controller.
Heres a couple to get your started
Route::get('/register', ['uses' => 'Auth\AuthController#getRegister']);
Route::post('/register', ['uses' => 'Auth\AuthController#postRegister']);
Route::get('/login', ['uses' => 'Auth\AuthController#getLogin']);
Route::post('/login', ['uses' => 'Auth\AuthController#postLogin']);
You can set $loginPath property in AuthController
These are some other properties you may also need
Where user is redirected after logout
$redirectAfterLogout
The post register / login redirect path
$redirectPath
Path to the login route.
$loginPath
class AuthController extends Controller {
protected $loginPath = 'login'; //example.com/login
use AuthenticatesAndRegistersUsers;
public function __construct(Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
$this->middleware('guest', ['except' => 'getLogout']);
}
}

Auth on create resource causing routing problems

I am trying to require auth before reaching the create resource and have seperated my resource routes accordingly.
Route::resource('posts','PostsController', ['except' => ['store','edit','update','destroy','create']]);
Route::group(['before'=>'auth'], function() {
Route::resource('posts','PostsController', ['only' => ['store','edit','update','destroy','create']]);});
Now for some reason when going to posts/create it redirects me to the show route. The auth is working fine on all other routes, and when create is removed it asks for login upon posting the create, but obviously I would like this section to be off limits regardless.
I would suggest you use controller filters instead.
This simplifies the routing to this:
Route::resource('posts', 'PostsController');
And in your post controller's constructor, you can configure the filter:
public function __construct()
{
$this->beforeFilter('auth', array('except' => array('index', 'show')));
}

Resources