Can somebody please tell the location of auth:api middleware?
As per the auth:api middleware, the api routes are protected by not null users.
I have a boolean field in user table called Is_Admin_Url_Accessible. I want to add a condition in the auth:api middleware for some routes to make user that only those user access such routes whoever are permitted to access the admin area.
I checked the class here but could not help.
\app\Http\Middleware\Authenticate.php
You can add a middleware that makes control user accessible, and you can set it as middleware to your route group like auth:api
Please run php artisan make:middleware UserAccessible on your terminal.
After run above artisan command, you will see generated a file named UserAccessible.php in the App/Http/Middleware folder.
UserAccessible.php Contents
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class UserAccessible
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = Auth::user();
if(!$user->accesible){
// redirect page or error.
}
return $next($request);
}
}
Then, you must define a route middleware via App/Http/Kernel.php
Kernel.php Contents
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
...
'user_accessible' => \App\Http\Middleware\UserAccessible::class
];
And finally, you can define route middleware to your route group;
api.php Contents
Route::group(['middleware' => ['auth:api', 'user_accessible']], function () {
// your protected routes.
});
I hope this solve your problem.
Related
I am usgin Laravel 9 test tool.
I dropped the database, recreated and imported using SQL statement.
With all the database set, I used the browser to log in with my user, and everything worded just fine.
Then I ran the php artisan test --filter HomeControllerTest and all the database was deleted! HOW COME?????
here is the test code:
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class HomeControllerTest extends TestCase
{
use RefreshDatabase;
public function test_home_view_requires_authentication()
{
// Log in as the created user and try to access the home page
$response = $this->postJson('/login', [
'email' => 'test#example.com',
'password' => 'password',
]);
$response->assertStatus(302);
$response->assertRedirect(route('home'));
$response = $this->get(route('home'));
$response->assertOk();
$response->assertViewIs('home');
$response->assertViewHasAll(['corretora', 'propostas']);
}
/**
* Test if home page can be accessed by a guest user.
*
* #return void
*/
public function test_home_view_requires_guest()
{
$response = $this->get(route('home'));
$response->assertStatus(302);
$response->assertRedirect(route('login'));
}
}
Why my database was deleted? i do have a backup, of course, but should test do it?
There was not an error. The use of the use RefreshDatabase; do the erasing.
I remove it and now is working good.
I want to restrict API access with an access-key how most of the APIs provide read access to anonymous users. In my use case my frontend isn't guarded with JWT or any token. I won't to prevent any random person post to my API.
I want to give my frontend read access to come endpoint while write access to other. besides frontend I will have other API connecting to my API with different access key which allows read to some end points and write to other.
I have this interceptor
import {
injectable,
Interceptor,
InvocationContext,
InvocationResult,
Provider,
ValueOrPromise
} from '#loopback/core';
/**
* This class will be bound to the application as an `Interceptor` during
* `boot`
*/
#injectable({tags: {key: AccessKeyRestrictionInterceptor.BINDING_KEY}})
export class AccessKeyRestrictionInterceptor implements Provider<Interceptor> {
static readonly BINDING_KEY = `interceptors.${AccessKeyRestrictionInterceptor.name}`;
/*
constructor() {}
*/
/**
* This method is used by LoopBack context to produce an interceptor function
* for the binding.
*
* #returns An interceptor function
*/
value() {
return this.intercept.bind(this);
}
/**
* The logic to intercept an invocation
* #param invocationCtx - Invocation context
* #param next - A function to invoke next interceptor or the target method
*/
async intercept(
invocationCtx: InvocationContext,
next: () => ValueOrPromise<InvocationResult>,
) {
try {
// Add pre-invocation logic here
console.log('invocationCtx.methodName ', invocationCtx.methodName)
console.log('invocationCtx.args[0] ', invocationCtx.args[0])
console.log('invocationCtx.target ', invocationCtx.target)
console.log('pre-invocation', invocationCtx)
const result = await next();
// Add post-invocation logic here
return result;
} catch (err) {
// Add error handling logic here
throw err;
}
}
}
and using it in my controller
#intercept('interceptors.accessKey')
#post('/only-with-access-key')
I want to add some metadata while calling interceptor something like #intercept('interceptors.accessKey', {metadata: { resource: 'Device', scopes: ['read'] }}).
I know Loopback 4 provides special interceptor #authorize but I don't belive I can use it without #authenticate('jwt'). My use case do not have room for authentication. How can I achieve this?
i created a filter authorization. when i want to login using token to access the home menu but i have a problem. when I access the home menu without using the token it still works. I am attaching a screenshot from my postman to access the home menu without a bearer token and to access the home menu using a bearer token.
this source code, Auth.php
namespace App\Filters;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Config\Services;
class Auth implements FilterInterface
{
/**
* Do whatever processing this filter needs to do.
* By default it should not return anything during
* normal execution. However, when an abnormal state
* is found, it should return an instance of
* CodeIgniter\HTTP\Response. If it does, script
* execution will end and that Response will be
* sent back to the client, allowing for error pages,
* redirects, etc.
*
* #param RequestInterface $request
* #param array|null $arguments
*
* #return mixed
*/
public function before(RequestInterface $request, $arguments = null)
{
$key = getenv('TOKEN_SECRET');
$header = $request->getServer('HTTP_AUTHORIZATION');
if (!$header) return Services::response()
->setJSON(['msg' => 'Token Required'])
->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
$token = explode(' ', $header)[1];
try {
JWT::decode($token, new Key($key, 'HS256'));
} catch (\Throwable $th) {
return Services::response()
->setJSON(['msg' => 'Token tidak valid'])
->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
}
}
/**
* Allows After filters to inspect and modify the response
* object as needed. This method does not allow any way
* to stop execution of other after filters, short of
* throwing an Exception or Error.
*
* #param RequestInterface $request
* #param ResponseInterface $response
* #param array|null $arguments
*
* #return mixed
*/
}
do friends here have a solution to overcome this problem?
without using bearer token using bearer token
I have created an API for my web application. Now I want to give access to the world but before giving access I want mechanism something like Facebook API, Twitter API, Google API who provides client ID and Secret Key. Currently, I am using JWT AuthController, user login with his credentials and return a token, I don't want the users to be login.
I want the user can access my API using client ID and secret key? Another thing is that and How I will create client ID's and secret keys for the users?
Is this can be achieved using JWT Auth?
Any help?
I have read the article and quite promising it is, but after few post it recommends to use oauth2, here you go:
https://laracasts.com/discuss/channels/lumen/api-authorization-via-public-and-secret-keys
quotes:
Just add in the class to your API config.
namespace App\Providers\Guard;
use Dingo\Api\Auth\Provider\Authorization; use
Dingo\Api\Routing\Route; use Illuminate\Http\Request; use
Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class GuardProvider extends Authorization {
/**
* Get the providers authorization method.
*
* #return string
*/
public function getAuthorizationMethod()
{
return 'X-Authorization';
}
/**
* Authenticate the request and return the authenticated user instance.
*
* #param \Illuminate\Http\Request $request
* #param \Dingo\Api\Routing\Route $route
*
* #return mixed
*/
public function authenticate(Request $request, Route $route)
{
$key = $request->header(env('API_AUTH_HEADER', 'X-Authorization'));
if (empty($key)) $key = $request->input(env('API_AUTH_HEADER', 'X-Authorization'));
if (empty($key)) throw new UnauthorizedHttpException('Guard', 'The supplied API KEY is missing or an invalid authorization header was sent');
$user = app('db')->select("SELECT * FROM users WHERE users.key = ?", [$key]);
if (!$user) throw new UnauthorizedHttpException('Guard', 'The supplied API KEY is not valid');
return $user;
}
}
i am using symfony 2 to build a web platform for my company. Recently, i have changed the validation rule inside my User entity by adding the following code:
/**
* #Assert\Regex(
* pattern="/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,127}$/",
* message="edit.personnal_info.udpate.message.password_info_regex",
* groups={"registration"}
* )
*/
protected $plainPassword;
After this change, all my old created users can't login anymore. Just new users, with valid password can get connected.
I don't want to change all old passwords. So, if there is a way to skip validation rules while login, it will be OK.
Ps: i'm using FOSUserBundle.
Solution if your issue is that old users used shorter passwords and you want to support them until next password change
Instead of adding this constrain to entity you could add it to your registration and change password forms
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('plainPassword', PasswordType::class, [
'constraints' => [
new Regex([
'pattern' => '/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,127}$/'
]),
new NotBlank()
]
]);
}
this way you can enforce new password policy for new users without breaking logic for old users.