Preventing cakePHP 2.1 auth componant from redirecting when using ajax - cakephp-2.1

1 application. I am using ajax to log in and authenticate a user. The problem i am having is with cakephp 2.1 auth component. when I manually log in the user the component redirects which i dont want to happen but rather return a success code back to my ajax request.
Is there a way to prevent this default behaviour?

AuthComponent is calling Controller::redirect(null, 403). You can catch these by overriding redirect() in your AppController:
/**
* Proxy for Controller::redirect() to handle AJAX redirects
*
* #param string $url
* #param int $status
* #param bool $exit
* #return void
*/
public function redirect($url, $status = null, $exit = true) {
// this statement catches not authenticated or not authorized ajax requests
// AuthComponent will call Controller::redirect(null, 403) in those cases.
// with this we're making sure that we return valid JSON responses in all cases
if($this->request->is('ajax') && $url == null && $status == 403) {
$this->response = new CakeResponse(array('code' => 'code'));
$this->response->send();
return $this->_stop();
}
return parent::redirect($url, $status, $exit);
}

Related

Laravel API REST for index() returns a json html string to the home page

I'm using Laravel api with a resource controller.
My api route
Route::apiResource('todos', TodoController::class)->middleware('auth:api');
Controller
public function index(TodoRequest $request): JsonResponse
{
$response = new Response();
// $withDeleted = $request->has('withDeleted') ? true : false;
$todos = $this->todoService->getAllTodosWithLists($request->query('withDeleted'));
$response->setMessage(ServerMessages::TODOS_RETRIEVE_SUCCESS);
return response()->json(
$response->build($todos),
$response->getCode($todos)
);
}
class TodoRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
* Must match with FrontEnd fields
*
* #return array
*/
public function rules(): array
{
return [
'content' => 'required'
];
}
/**
* Get custom messages for validator errors.
*
* #return array
*/
public function messages(): array
{
return ['required' => 'The :attribute must not be left blanked.'];
}
}
My problem is everytime I add the TodoRequest in my parameter's it always return a response redirecting back to the default Laravel homepage.
Note: I am passing a query parameter inside my $request i.e withDeleted and probably will add more filters. This app was originally made in Lumen which perfectly well, and I did some migration to the latest Laravel 9 framework.

Automatically refresh access token with laravel passport

When issuing access and refresh tokens I send them to the frontend with httpOnly = true. I made a middleware class which checks if the access token has expired and if the refresh token hasn't expired. If both are the case I call the oauth/token route with refresh_token as grant_type.
All of this works, however I'm not sure how to use the authenticated user inside the controllers. Right now I've set the middleware up that when there's a response it sends the new access and refresh token.
class RefreshAccessToken
{
/* #var AuthController $authController */
private $authController;
/**
* RefreshAccessToken constructor.
*
* #param AuthController $authController
*/
public function __construct(AuthController $authController)
{
$this->authController = $authController;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// User already has an access token
if ($request->hasCookie('access_token')) {
return $next($request);
}
// User doesn't have an access token and doesn't have a refresh token.
if (!$request->hasCookie('refresh_token')) {
return $next($request);
}
$response = $next($request);
$cookies = $this->authController->refreshToken($request);
return $response
->cookie($cookies['access_token'])
->cookie($cookies['refresh_token']);
}
}
Now inside a controller if I want to access the logged in user I always get null as a response:
public function logout()
{
dd(auth()->user());
}
}
Inside the controller's construct method:
$this->middleware('auth:api')->only('logout');
Does anyone know how to handle this use case?

Getting Auth Results in Laravel Custom Console Command

I am making a console command which I want to schedule. I have written the complete code which I wanted but the issue I am facing is that in custom console command when I write:
Auth::user();
It returns:
null
This command is not going to execute into my application due to which it is giving:
null
I get that but then I made a static function inside one of my model and returns the id from there to my console command handle function still it is giving me Null any idea on how can I get Auth record in my custom laravel console command. Any help would be great.
Edit:
Here is the static method I wrote to get the id.
public static function getAuhtCode(){
$code = Auth::user()->id;
return $code;
}
You can use loginUsingId method from session guard to manually authenticate a user thanks to an id.
/**
* Log the given user ID into the application.
*
* #param mixed $id
* #param bool $remember
* #return \Illuminate\Contracts\Auth\Authenticatable|false
*/
public function loginUsingId($id, $remember = false)
{
if (! is_null($user = $this->provider->retrieveById($id))) {
$this->login($user, $remember);
return $user;
}
return false;
}
For example
Auth::loginUsingId(1);
Auth::user(); //Will work

Returning to route after middleware triggered in Laravel

I am working in Laravel 7 and have a middleware that checks if the user has a current user agreement, if not it redirects to a form that offers the current agreement. When the offer is accepted I need to redirect back to where they were originally going. I think I need to put something in the session so that when my controller stores their acceptance it can redirect back to the original route.
class VerifyAgreement
{
public function handle($request, Closure $next, $agreement)
{
if(UserAgreement::outOfDate($agreement)){
return redirect()->route('agreement.offer', $agreement);
}
return $next($request);
}
}
I think I need to get the current request and pass it to the redirect so the User Agreement controller can capture it somehow and then redirect once the agreement is stored... I am not sure.
class AgreementController extends Controller
{
public function offer(Agreement $agreement)
{
return view('agreement.offer',['agreement' => $agreement]);
}
public function agree(Request $request)
{
$agreement_uuid = App\Agreement::findOrFail($request->agreement)->uuid;
UserAgreement::create(['user_uuid'=>auth()->user()->uuid, 'agreement_uuid'=>$agreement_uuid]);
//redirect something something something
}
}
As mentioned in the comments by #Ruben Danielyan, the Illuminate\Routing\Redirector has some methods that you may find useful
Redirector.php
/**
* Create a new redirect response to the previously intended location.
*
* #param string $default
* #param int $status
* #param array $headers
* #param bool|null $secure
* #return \Illuminate\Http\RedirectResponse
*/
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
/**
* Set the intended url.
*
* #param string $url
* #return void
*/
public function setIntendedUrl($url)
{
$this->session->put('url.intended', $url);
}

Redirect before login in laravel to avoid second login

I have php/laravel web application.
I use laravel auth to log in users. But when I have two open cards with login page they don't know that on one page user is logged in.
I read that I must redirect in middleware when user is logged on one page.
I try to do this in LoginController with override function, but it dosen't works.
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::check()){
return redirect()->intended('dashboard');
} else if (Auth::attempt($credentials)) {
return redirect()->intended('dashboard');
}
}
I just want to check before log into application that is user logged, but I don't know clearly where.
Ok I try to explain what is happening
When you open two login forms and ofc in your login forms you already have csrf token field with generated value and ofc it's a pattern BUT
let's assume your csrf_token value is 123 in both forms and when you login successfully laravel updates your session by adding your user_id to it so if your user_id is 1 then your token would change to 1231 (again it's a hashed value but come along with me) and when you submit your second form which has 123 token, as you can guess 123 is not equal to 1231 and it throws a TokenMissmatchException
In your case what you can do is to open App\Exceptions\Handler.php and add this to your handler method
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Throwable $exception
* #return \Symfony\Component\HttpFoundation\Response
*
* #throws \Throwable
*/
public function render($request, Throwable $exception)
{
// Checks if exception is instance of TokenMissmatchException && it throwed in the login page
if ($exception instanceof \Illuminate\Session\TokenMismatchException && $request->path() === 'login') {
$redirectPath = '/';
return redirect($redirectPath);
}
return parent::render($request, $exception);
}

Resources