I need to add basic auth to my sanctum api - laravel

I'm using laravel sanctum and I add to middleware to my route:
Route::group(['middleware' => 'auth:sanctum'], function () {
Route::post('/sms-log',[SmsLogController::class, 'store'] );
});
But insomnia wants me to sign in:
insomnia_ss
when I remove middleware from API route working as expected. so how can I add basic auth?

In insomnia add a header so you don't get redirected to the login route, instead you get a "message":" Not authenticated."
Accept: application/json

Related

Laravel Sanctum returns 404 instead of 401 unauthenticated

I am using laravel/sanctum package for authenticating my api. I have followed all the steps from the documentation but I get 404 not found when using an invalid token for hitting a guarded route instead of 401.
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::post("/upload", [AuthController::class, "uploadFile"]);
Route::post('/me', [AuthController::class, 'me']);
});
few steps to follow
clear cache
test.ca/api/upload - make sure you have 'api' in url (from where you are calling)
add 'Accept application/json' in your request header.

How to verify a token with Laravel Passport?

I want to validate a token using Laravel Passport. My API's consumer will pass the token via the Authorization header as a Bearer token and I want that Laravel Passport returns me if is a valid token.
I don't want to use a middleware, my API will be in another Laravel Project, but I want this project to call the Laravel Passport server just for check if a token is valid, how can I check the token?
I'm issuing the tokens right, just left verify them, but I don't know how:(
This is how you can verify tokens without the middleware:
Auth::guard('api')->check();
You can create your own middleware. Inside that middleware's handle, pick the Bearer token and call your Passport server, depending on the response returned call next if true, or abort if false. Something like this:
public function handle($request, Closure $next)
{
try {
$passportEndpoint = 'your_passport_endpoint_here';
$client = Http::withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => $request->header('Authorization')
]);
$response = $client->get($passportEndpoint);
if ($response->status() === 200) {
$body = $response->object();
//do some stuff with response here, like setting the global logged in user
return $next($request);
}
}
catch (RequestException $exception) {
}
return abort(401, 'You are not authenticated to this service');
}
If you don't want to use the Passport middleware in the project where you want to validate the tokens, you would have to create an endpoint in the Laravel Passport server that can accept the token, perform the usual Passport validation and return a response to your service.
It would be an implementation of the Token Introspection spec: https://www.rfc-editor.org/rfc/rfc7662 - though you have to implement it yourself, as I think that Laravel Passport doesn't support it out-of-the-box.
Also, when verifying JSON Web Tokens (if this is the type of tokens that you use), remember that verifying the signature is not enough. Have a look at this best practices article to know how to properly work with JWTs.

Laravel API request middleware unathenthicated

I need your help with my Laravel API HTTP Request. I am trying to get a response from my api. But it sends back "Error: "Request failed with status code 401" and the AuthenthicationException shows "Unauthenticated." . I have not found any solutions. I need your help... Thanks.
const response = (await rootApi.get(`/openSesame/targets/${id}`)).data;
My 'Api\TargetController
public function detail($id)
{
$spintaxInput = SpintaxInput::find($id);
if (!$spintaxInput) {
return response()->json(['error' => "Not found."], 404);
}
return response()->json($spintaxInput, 200);
}
My api routes
Route::group(['middleware' => ['auth:web']], function () {
Route::group(['prefix' => 'openSesame'], function () {
Route::get('/targets/{id}', 'Api\TargetController#detail');
});
});
you should use Sanctum to API authenticate
Passport would be the way to go here.
check Passport
Now, to help you with this:
To be able to authenticate when you're going to make a request to the api, make sure to use the header: Authentication and the token followed by Bearer
A token example should be like this one:
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiZThmNjZiMTU0Yjg4OGM2YmI2ODg0ZDM2ZDU3NGYxY2FiODFjODgyMmI0MDc5NDVkMTNjM2I2MDdiMDc0MGNkNTI1MzgxZDU2NWJkNWUwZTciLCJpYXQiOjE1ODY3MDY1MzgsIm5iZiI6MTU4NjcwNjUzOCwiZXhwIjoxNjE4MjQyNTM4LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.Brf48KrE3smifCIo61_8alvU8Yi5atsMtLz5t7-drQ7xnpG0Lga9q7Wh8RDJaYLtxHltdMLRVfp2HtstVQO6XY8qE0GNqS2pfjwFGDJTChWDSbINzjRyX9rO9FdTbE95TPlh84e_PRQ7iWMDO_DQkB67YvuYieXJjWAzF5UBGjK9ZMSjjzHahHV-iCE4Si_i0DHP6bLDTksZd51jiYV7ptGr41lZCwnL09fNjtWtLYTl79OoxIzcEPZMUQ_l7QcoJPJUYa0-lvHAta9hbkzZHdskIOB9C6afel4VxPFEVI0RmP5glJBJFKu0A_0N80iJf7yhXqofk5muF-bFWv9_092os2h3-zt0bDjTb7jeSAY8CkgxRQ3oLtRQN9MBgxRdUechycdimbKpU6hhpGfJfsofHtJiRGAbh5Eddlq5AGjdZkRW6zu9CjFUFiivZHOO_JI3HmU39jXUQx8218Czb9_Z-iG02K0Bvtk0eilvZl3k6FjvDka3beb0Zg99Da5MKeYSMKXqn4U-mndQPPtsidWCwh4foskzv6mRvWhsGh8xN0zByCTIhML-ogqrIGNcDUsrgpi2E4eue4PZ9DfYIa740kYKnJLzpNC6_ilQPesb3MjqLLx9DBcUkuWH7fwKKA_OaxhIv2WiELUECjWuIIDMpNGuK_Kes0RbqedPvlg
When using API's, you will need to use that header in each request. Otherwise you will get a 401. The 401 means that you're not logged in.
You should use passport, like said.
And for auth middleware, replace it to:
middleware('auth:api')

Can't get auth user with laravel passport, keep getting "Unauthenticated" error

I can't get the information of the authenticated user in a Laravel passport app with JWT and vue.
I've installed laravel passport. Ive done everything in the documentation and added:
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
To consume it with js for a SPA app.
I've protected my routes with the auth:api middleware, but i keep getting:
{"Status":{"api_status":0,"Code":401,"Message":"Unauthenticated"}}
When i use postman to manually insert the CSRF-TOKEN in Authorization Bearer Token. It does give me the auth user.
Whatever i do, i keep getting null on Auth::user(); in my controllers and routes
Laravel V5.7
Node V10.15.3
Npm V.6.9.0
You need to send a POST request (using Postman/Insomnia) with the details of the user you want to log in as to /oauth/token in your app which will respond with an API token. You save this api token locally, and then add add it as a Header variable to your guzzle/axios/whatever function's http calls (every one of them!) to your API.
$http = new GuzzleHttp\Client;
$data = 'Whatever';
$response = $http->request('POST','api/user',[
'data' => $data,
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer xxxxxxxxxxxxThis is the long authentication string returned from the Postman requestxxxxxxxxxxxxxx'
]
]);
dd(json_decode((string) $response->getBody())); // To view the response
From: https://laravel.com/docs/5.5/passport#creating-a-password-grant-client

How to authenticate Vue.js / Axios request of an API route in Laravel

I'm in Laravel 5.6. I have all my API routes built out and properly responding to requests from my REST client (Paw). I'm trying to build a simple front end to access those routes.
I'm trying to use Laravel's out-of-the-box features as much as possible, so I'm using Axios to call those routes from a blade template using Vue.js. It works if I disable auth middleware on the test route, but I get 401 errors on the console when auth middleware is enabled for the route.
The problem seems obvious enough... The auth:api guard on my /api routes wants to see an oauth token in the header, but when I log in with the web page it does session authentication. I assume there's a simple way to resolve this without having to spoof an oauth token request in the web frontend, right? Do I need to somehow pass the session token in my request with Axios? And, if so, do I also need to change the auth:api guard in my api routes file?
I solved it! I'm a bit embarrassed because the answer was actually in the Laravel docs, but I will say I tried this before posting the question here and it wasn't working. Perhaps something else was broken at the time.
Per the Laravel docs:
All you need to do is add the CreateFreshApiToken middleware to your
web middleware group in your app/Http/Kernel.php file:
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
This Passport middleware will attach a laravel_token cookie to your
outgoing responses. This cookie contains an encrypted JWT that
Passport will use to authenticate API requests from your JavaScript
application. Now, you may make requests to your application's API
without explicitly passing an access token...
You will probably want to use Larvel Passport or a JWT auth mechanism for obtain the Authorization token.
Seeing as how you're using axios, add a request interceptor to attach the access token to every request once you successfully authenticate. A simple example:
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// assume your access token is stored in local storage
// (it should really be somewhere more secure but I digress for simplicity)
let token = localStorage.getItem('access_token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
to use the auth:api first you need api_token inside your users table
Schema::table('users', function ($table) {
$table->string('api_token', 80)->after('password')
->unique()
->nullable()
->default(null);
});
also you can create a user for testing as follows
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(60),
]);
in your layout use the following before #yield('content')
<script>
window.Laravel = <?php echo json_encode(['api_token' => (Auth::user())->api_token]); ?>
</script>
now you can use window.laravel.api_token inside your vue js to use it in headers
heres an example
var methods = new Vue({
el: '#tabs_lists',
data: {
config: {
headers: {
Authorization: 'Bearer ' + window.Laravel.api_token,
Accept: 'application/json'
}
},
data: []
},
methods: {
test: function (link) {
axios.get(link, this.config)
.then(response => (this.data = response.data)).catch(function (error) {
// handle error
console.log(error);
});
}
}
}
)

Resources