Where is the middleware key for Laravel Sanctum defined? - php

To protect and authenticate all incoming routes in Laravel using Sanctum, we have to attache the sanctum authentication guard to our routes within routes/api.php route files:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
My question is about the middleware key auth:sanctum. Where is it defined/registered?

As document says
To protect routes so that all incoming requests must be authenticated,
you should attach the sanctum authentication guard to your protected
routes within your routes/web.php and routes/api.php route files.
if you see Laravel\Sanctum\SanctumServiceProvider in register method
public function register()
{
config([
'auth.guards.sanctum' => array_merge([
'driver' => 'sanctum',
'provider' => null,
], config('auth.guards.sanctum', [])),
]);
if (! app()->configurationIsCached()) {
$this->mergeConfigFrom(__DIR__.'/../config/sanctum.php', 'sanctum');
}
}
While registering they are setting sanctum guard.So sanctum is not middleware its guard
Ref:https://laravel.com/docs/8.x/sanctum#protecting-routes
Ref:https://github.com/laravel/sanctum/blob/2.x/src/SanctumServiceProvider.php

Related

Can you see my routes and config with sanctum

Using https://laravel.com/docs/9.x/sanctum , I'm try create API application.
Generating token is ok.
But when I try to restrict my endpoint to authorized users with middleware, any check permission didn't work, endpoint is accessible for all.
In controller I tested with debug auth('sanctum')->check() - and I became true for valid token and false else.
My routes/api.php
Route::post('login', [AuthController::class, 'login']);
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post('logout', [AuthController::class, 'logout']);
Route::group([
'prefix' => 'services/{service}',
'where' => [
'service' => implode('|', array_column(ServiceEnum::cases(), 'name'))
]],
function () {
Route::get('accounts/{account}/balance', [AccountController::class, 'getBalance']);
});
});
It was my fail.
I recreate a project with new fresh laravel (something was broken with installing laravel passport) and then solve a problem with empty auth user in constructor of controller:
public function __construct(Request $request)
{
$this->middleware(function ($request, $next) {
$this->user = auth()->user();
return $next($request);
});
}

How get access token after autorization laravel sanctum?

Hello i'm newbie in laravel. I use for authorization sanctum. But i want that some request can available for authorization user (i use laravel for only api, on front i use angular 2).
web.php:
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post('api/user-information', function(Request $request) {
return response()->json([ auth()->user()]);
});
// API route for logout user
Route::post('api/logout', [AuthController::class, 'logout']);
});
How can I get access token after success autorization user that i can send request for middleware routes. Because if i have request withous access token i always send null in 'api/user-information'. Please help me resolve this problem.
You could better make a new function in a controller, probably the AuthController. In this function you can validate fields
$validatedData = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
With the validated data you can use Auth::login($validatedData);
Source: https://laravel.com/docs/9.x/authentication#login-throttling
Welcome to Laravel! I am assuming you have login method that authenticates user. You can create a token in that method and pass it to your frontend.
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
return ['status'=>0,'message'=>'Invalid Credentials','data'=>[]];
}
$data = [
'user'=>$user,
'token'=>$user->createToken('MyToken')->plainTextToken
];
return ['status'=>1, 'message'=>'Login Successful!', 'data'=>$data];
}
If you just need to pass the token, you can simply return token in the response and then pass it in request header (Authorization) of your Angular applcation to access the API routes protected by Sanctum middleware auth:sanctum
return $user->createToken('MyToken')->plainTextToken;
Also since you are going to use Laravel for API, I would suggest you put all your routes in routes/api.php file.
The routes in routes/api.php are stateless and are assigned the api middleware group. The prefix '/api' is applied to all the routes defined in api.php
You can read more about it in Laravel Documentation
Issuing API Tokens
The Default Route Files

Auth user showing Null in outside of auth api passport

I am developing an app where I am fetching user details with Laravel passport API get method with query string.
But when I put that route in auth API it shows "route login not found" and when I put outside auth API it shows Null when I call Auth::user().
Here is my route and my API with method:
Route::post('login', 'AuthController#login');
Route::post('register', 'AuthController#register');
Route::get('GetUserClaims', 'AuthController#GetUserClaims');
Route::group(['middleware' => 'auth:api'], function(){
//Route::get('details', 'AuthController#details');
//Route::get('GetUserClaims', 'AuthController#GetUserClaims');
});
http://xxx.xxx.xxx.xxx/public/api/GetUserClaims?userKey=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ijg3M2E4NTdhZmViMGVhMzAzNWQ5ZGU5NGZmNTUzMmI4NGUyMDZjZjE0MjRhYzQxZjI0YjUwYjdmZjc4OWZmYjM5YzhmNjBlZjRmYzM0OTQzIn0.eyJhdWQiOiIxIiwianRpIjoiODczYTg1N2FmZWIwZWEzMDM1ZDlkZTk0ZmY1NTMyYjg0ZTIwNmNmMTQyNGFjNDFmMjRiNTBiN2ZmNzg5ZmZiMzljOGY2MGVmNGZjMzQ5NDMiLCJpYXQiOjE1ODUwODU5NDksIm5iZiI6MTU4NTA4NTk0OSwiZXhwIjoxNjE2NjIxOTQ5LCJzdWIiOiI2Iiwic2NvcGVzIjpbXX0.VXKRTTpZxMGq4gR8kdu9qREBvhxSfPz4WureEYCpr-nh-qMFqkuR9Q10oa4AotmNmIABRFb_ijyrpt1AVJOpPU4b0R4lEnUWq746wh3etBg37fuSvDx8XDwF84NcOyU1GNnXDZ0KLbwr4YjrOqtuPNBAtkDEPHOKUYdxHvYOUSqt8YIx-L1p2ijHEvYDKroG8-B9mZs97HCtgSpwqTv7b5I0hEV4b1Ifkm24qDhoRMvaSYDFGcu52VWfwPjMEq6NPDYwwBx9Jpv_wv8-UA8BZPqECzE-D7xw46X4IhUNg9PyGxhtWbMvipz1E1OFzb_lBmgYTU5JVx0s0wmmcjqAq4jlfHNarUdBQGziJR4m3rLBGYNtLmqQ4kR1knrhaR-qQYaKiQNknxtb7c_HG724G_XSYkzFJZUalLFtQkDYpXSSP-QgzKFrQHblE6Led2AwPqt4S4svDOht5hqg29TejNbggIztj_fs9u2cwso1VvPjAM1LLG8chzVT5PM6YTihDGaVf4VEUaQmClgG64pEq2TmJISTLsplqlG1wn2BTdmCcO69VZYBvLJvjDlm942RGAYaNHD7Wt3RbJxMOH3RF8OGRP_H2IvIwtWz4x29dDUg8fMEKlA-nM1A8wsrK-YFkbwrY-IOzHl-4MdPopmXiFViB5RPMkQdCMd0ItWTjgA
public function GetUserClaims(Request $request)
{
if ( $request->has('userKey') ){
$user = Auth::user();
$token = $request->userKey;
var_dump($user);
//$token='Bearer '.$request->bearerToken();
//$request->header('Authorization',$token);
//return response()->json(['user' => auth()->user()], 200);
//return response()->json(['success' => $user], Response::HTTP_OK);
}
}
I think you can refer to the solution below to solved you issue.
Laravel 7 filters
The guide lead you about how to setup Laravel Authentication which include at Laravel package.
You don't have to build out from scratch by yourself

Laravel apply multiple middlewares on API routes

I have created a custom middleware to check if $request->wantsJson() then it should allow the route to call the function. The order would be
1. Check for JSON
2. Check Auth
How can I implement the middle wares in this order? I have tried the following but its not working
Route::group(['middleware' => ['auth:api', 'json']], function () {
Route::group(['prefix' => 'V1'], function () {
Route::post('logout', 'API\V1\AuthController#logout');
});
});
Did you register the middleware in App\Http\Kernel.php route middleware?
https://laravel.com/docs/master/middleware#assigning-middleware-to-routes
protected $routeMiddleware = [
// ...
'json' => \App\Http\Middleware\CheckForJson::class,
];
There is also an additional array for forcing the priority (order) of non-global middleware.
https://laravel.com/docs/master/middleware#sorting-middleware
protected $middlewarePriority = [
// ...
\App\Http\Middleware\CheckForJson::class,
];

How to check a token (CSRF) on controller?

There is some option on Laravel that we allow Laravel to create a token and test it on server side to pull up CSRF attacks.
I found this on Laravel website, But didn't say how to check from Controller that is an attack or from a native and real page.
How to check the token (CSRF) on controller?
Answer for Laravel 5
In Laravel 5 middleware replaces filters. This is also true for CSRF. The middleware is enabled by default and is handled in App\Http\Middleware\VerifyCsrfToken.
It can be disabled by removing App\Http\Middleware\VerifyCsrfToken in App\Http\Kernel. And if moved to $routeMiddleware...
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
'csrf' => 'App\Http\Middleware\VerifyCsrfToken',
];
... it can be used conditionally by adding it to a route:
Route::post('foo', ['middleware' => 'csrf', 'uses' => 'BarController#foo']);
Or in the controllers constructor:
public function __construct(){
$this->middleware('csrf');
}
Assuming you use laravel 4.x:
You don't need to check this in your controller. defining the before parameter tells laravel to check this automaticly.
Route::post('profile', array('before' => 'csrf', function(){
/* CSRF validated! */
}));
If you want to do something when the token is incorrect, you can change the filter in app/filters.php. This one:
Route::filter('csrf', function()
{
if (Session::token() != Input::get('_token'))
{
throw new Illuminate\Session\TokenMismatchException;
}
});

Categories