How to use API Routes in Laravel 5.3 - api

In Laravel 5.3 API routes were moved into the api.php file. But how can I call a route in api.php file? I tried to create a route like this:
Route::get('/test',function(){
return "ok";
});
I tried the following URLs but both returned the NotFoundHttpException exception:
http://localhost:8080/test/public/test
http://localhost:8080/test/public/api/test
How can I call this API route?

You call it by
http://localhost:8080/api/test
^^^
If you look in app/Providers/RouteServiceProvider.php you'd see that by default it sets the api prefix for API routes, which you can change of course if you want to.
protected function mapApiRoutes()
{
Route::group([
'middleware' => 'api',
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}

routes/api.php
Route::get('/test', function () {
return response('Test API', 200)
->header('Content-Type', 'application/json');
});
Mapping is defined in service provider App\Providers\RouteServiceProvider
protected function mapApiRoutes(){
Route::group([
'middleware' => ['api', 'auth:api'],
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}

Related

Simple API Call gets redirected

I'm creating a Nextcloud-App (using Nextcloud 20). I want a simple call to my external service. Due to CSP restrictions (set by default by netxcloud), I simply can't.
Everytime I request my URL, using window.OC.generateUrl('/apps/[MYAPP]/video/trim'); I get a redirect response (code 302), instead of a success (code 200). What did I miss?
I registered my route:
// [MYAPP]/appinfo/routes.php
return [
'routes' => [
['name' => 'video#trim', 'url' => '/trim', 'verb' => 'POST']
]
];
I've build my controller:
// [MYAPP]/lib/controller/VideoController.php
namespace OCA\[MYAPP]\Controller;
use OCP\IRequest;
use GuzzleHttp\Client;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
class VideoController extends Controller
{
/**
* #NoAdminRequired
*/
public function trim(string $title, string $content)
{
$client = new Client([
'base_uri' => 'http://localhost:3000/push',
'timeout' => 2.0,
]);
$response = $client->request('POST', ['json' => $content]);
return new DataResponse(['foo' => 'bar']);
}
}
I'm POSTing my request to it. In console I see a redirect to Location http://localhost:9000/apps/dashboard/.
// js
const opts = {}; // my payload
const url = window.OC.generateUrl('/apps/[MYAPP]/video/trim');
fetch(url, {method: 'post', body: JSON.stringify(opts)})
.catch((err) => console.error(err))
.then((response) => response.json())
.then((data) => console.log(data));
I finally found the problem in routes.php!
Since I'm generating the URL for /apps/[MYAPP]/video/trim, the url in routes.php should look like /video/trim instead of /trim.
// [MYAPP]/appinfo/routes.php
return [
'routes' => [
['name' => 'video#trim', 'url' => '/video/trim', 'verb' => 'POST']
]
];

Axios returning 404 on laravel api request

ive a write a code to send a get request to server using vue js.but it return 404 not found exception thought the route is created on laravel.
axios.get('/api/v1/companies')
.then(function (resp) {
app.companies = resp.data;
})
.catch(function (resp) {
console.log(resp);
alert("Could not load companies");
});
route file :
Route::group(['prefix' => '/v1', 'namespace' => 'Api\V1', 'as' => 'api.', 'middleware' => 'auth:api'], function () {
Route::resource('companies', 'CompaniesController', ['except' => ['create', 'edit']]);
});

Method Illuminate\Auth\RequestGuard::attempt does not exist

I am new to both laravel and lumen.
I was creating a login api with oauth2.0 in lumen 5.6, i have installed passport and generated token.
Below is my login controller function and it is working fine. It returns token.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Route;
//use Illuminate\Support\Facades\DB;
use App\User;
use Auth;
public function login(Request $request)
{
global $app;
$proxy = Request::create(
'/oauth/token',
'post',
[
'grant_type' => env('API_GRAND_TYPE'),
'client_id' => env('API_CLIENT_ID'),
'client_secret' => env('API_CLIENT_SECRET'),
'username' => $request->username,
'password' => $request->password,
]
);
return $app->dispatch($proxy);
}
Since i have to check user status apart from username and password, i need to check the user credential first. so i do like this.
public function login(Request $request)
{
$credentials = $request->only('username', 'password');
if (Auth::attempt($credentials)) {
return ['result' => 'ok'];
}
return ['result' => 'not ok'];
}
Here i am getting this error.
Method Illuminate\Auth\RequestGuard::attempt does not exist.
So i tried Auth::check instead of Auth::attempt.
Now there is no error but it always return false even though the credentials are valid.
I searched a lot for a solution but i didn't get.
The function guard is only available for routes with web middleware
public function login() {
if(Auth::guard('web')->attempt(['email' => $email, 'password' => $password], false, false)) {requests
// good
} else {
// invalid credentials, act accordingly
}
}
Changing default guard to "web" fixed my problem.
config/auth.php:
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
using jwt it's worked for me
1-Auth::attempt($credentials)
just replace line 1 to line 2
2-$token = Auth::guard('api')->attempt($credentials)

Unable to get to route behind auth middleware for two routes

My two routes 'admin.media.begin-destroy' and 'admin.media.destroy' fails when middleware => 'auth'.
When trying to access the route 'admin.media.begin-destroy' I will get presented with the login page from the authentication controller, and I cannot get away from that without trying to access another page.
on my development machine it works fine both with and without auth middleware
Here are my routes that are protected:
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function() {
Route::get('/', ['as' => 'admin.dashboard', 'uses' => 'Admin\DashboardController#index']);
Route::get('show/{show}/toggle',['as' => 'admin.show.toggle','uses'=>'Admin\ShowController#toggle']);
Route::resource('show', 'Admin\ShowController');
// The admin.media.begin-destroy and admin.media.destroy fails when middleware => 'auth'
Route::get('media/begin-destroy-ddd/{id}', ['as' => 'admin.media.begin-destroy', 'uses' => 'Admin\MediaController#beginDestroy']);
Route::resource('media', 'Admin\MediaController', ['only' => ['index', 'create', 'store', 'destroy']]);
Route::get('order', ['as'=> 'admin.order.index', 'uses' => 'Admin\OrderController#index']);
Route::get('order/list-for-modification', ['as' => 'admin.order.list-for-modification', 'uses' => 'Admin\OrderController#listModify']);
Route::get('order/{order}/begin-destroy', ['as' => 'admin.order.begin-destroy', 'uses' => 'Admin\OrderController#beginDestroy']);
Route::delete('order/{order}/destroy', ['as' => 'admin.order.destroy', 'uses' => 'Admin\OrderController#destroy']);
});
The controller method for 'admin.media.begin-destroy' and 'admin.media.destroy' are super simple:
public function beginDestroy($filename)
{
return view('admin.media.begin-destroy', compact('filename'));
}
/**
* Remove the specified resource from storage.
*
* #param int $filename
* #return Response
*/
public function destroy($filename)
{
Storage::disk('free-media')->delete($filename);
return redirect()->route('admin.media.index');
}
I am very puzzled why this doesn't work.
Edit!---
Trying to work me around the problem I
/ Moved the problematic routes into its own group with no middleware
Route::group(['prefix' => 'admin'], function() {
Route::get('media/begin-destroy/{id}', ['as' => 'admin.media.begin-destroy', 'uses' => 'Admin\MediaController#beginDestroy']);
Route::resource('media', 'Admin\MediaController', ['only' => ['index', 'create', 'store', 'destroy']]);
});
/ Added the middleware registration in the Admin\Mediacontroller Constructor, I cannot add beginDestroy, because it will fail for unknown reason
public function __construct()
{
$this->middleware('auth', ['except' => ['beginDestroy']]);
}
// In beginDestroy, I then check for the user, and the User is not logged in WTF
public function beginDestroy($filename)
{
if (Auth::check())
{
return view('admin.media.begin-destroy', compact('filename'));
}
// I end up here.
return "Un-authorized";
}
for this particular use case, it is OK for me to disable the check in beginDestroy, because in the actual destroy code, the auth works again, but what is happening ?
Changing the Route to have the filename passed using good old question mark made the difference!
This is really more of a workaround than an answer, and I still have no idea why it doesn't work the other way, anyway, here is my workaround that did the trick.
// This works
Route::get('media/begin-destroy',
['as' => 'admin.media.begin-destroy',
'uses' => 'Admin\MediaController#beginDestroy']);
// This does not work!
// For reason beyond me, the 'auth' middleware fails here
// and Auth::check() also fails
// (Yes ofcourse I updated the signature accordingly in beginDestroy)
Route::get('media/begin-destroy/{filename}',
['as' => 'admin.media.begin-destroy',
'uses' => 'Admin\MediaController#beginDestroy']);

Route filters loading function no matter what

The problem with this is that the function is loaded whether the user is logged in or not. I need the account function to only be loaded if the user is logged in. I had Auth::check() then redirect in the function itself but I was told there was a way to do that within the route.
Route:
Route::get('account', ['before' => 'auth', 'uses' => 'SiteController#account']);
Standard Auth Filter Laravel:
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
//return Redirect::guest('login');
}
}
});
Your last attempt should work. Just get rid of the leading slash:
Route::get('account', ['before' => 'auth', 'uses' => 'SiteController#account']);