I'm trying to set up some page in Laravel that require a password to view.
A page is a model, called Page.
Each page has an associated password, stored in the Pages database table.
The schema
Schema::create('pages', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('client_id');
$table->string('url');
$table->text('content');
$table->string('password');
$table->timestamps();
});
I have a route, e.g. Route::get('/page/{url}', 'PageController@index')->middleware('gate'); which will show the 'page', it's just a blade/vue file with specific information injected into the template.
These pages allow the user to upload files via AJAX.
Currently, I created some middleware to actual authentication part.
Middleware
public function handle($request, Closure $next)
{
if(Cookie::get($request->route('url'))){
return $next($request);
}
session(['page' => $request->route('url')]);
return redirect()->route('gate',['page'=> $request->route('url')]);
}
PublicController.php
public function gate_check(Request $request)
{
//this part just ensures the correct page is loaded after being authed
$past = parse_url($request->session()->get('_previous')['url']);
if(array_key_exists('query', $past)){
$page = str_replace('page=', '',parse_url($request->session()->get('_previous')['url'])['query']);
$stored_password = Page::where('url', $page)->first()->password;
$password = $request->password;
if($password === $stored_password){
//if password matches, then redirect to that page
return redirect()->route('page', session('page'));
} else {
//else redirect them back to the login page to try again
return back();
}
} else {
//if there is no page information that use should go to, just send them to google instead
return redirect('https://google.com');
}
}
The idea of the middleware/auth method was to redirect the user to a login page if they weren't authed. This login page consists only of a password that you need to enter.
Once they enter it, I set a cookie so that they can bypass having to re-login again.
I now realise that is is insecure, or at least it seems that way as the expiry time of the cookie can be manipulated by the client/user - resulting in them being able to stay logged in forever.
Just wish to re-iterate that the method described above is working, but it is insecure. I also should re-iterate that these 'pages' allow users to upload files via ajax. And only should the user be allowed to upload if they're on that specific page e.g. by CSRF.
I need a secure way to password protect pages, which the expiry time of the 'session' can be customised. I'd also need a way to 'refresh' or 'extend' the active session without a page refresh using AJAX so that the user can stay on the upload page (in case uploads take a long time).
Standard user account with username/email & password is not applicable. Password only.
Wordpress has this feature built in - why is it so hard to do with Laravel for what seems so trivial?
How would you approach this?
This is how I would have done:
Standard user account with username/email & password is not applicable. Password only.
For non standard user account, you may yourself generate a guest id on every correct password entered and store it to session.
Schema::create('active_guests', function (Blueprint $table) {
$table->bigIncrements('guest_id'); # on your model specify this as primary key
$table->unsignedBigInteger('page_id'); # authorized for after validating password
$table->integer('expires_at'); # store it as unixtimestamp now()->addHours(5)->timestamp
$table->timestamps();
});
You can just query this way to check authentication
$page = Page::where('url', $page)->where('password', $password)->first();
if ($page) {
ActiveGuest::updateOrcreate(....);
Session::get('pages_authorized_for', [array_of_pages]);
// push the new page id and store it back to session as array
} else {
// incorrect password or page removed
}
Just wish to re-iterate that the method described above is working, but it is insecure. I also should re-iterate that these 'pages' allow users to upload files via ajax. And only should the user be allowed to upload if they're on that specific page e.g. by CSRF.
I need a secure way to password protect pages, which the expiry time of the 'session' can be customised. I'd also need a way to 'refresh' or 'extend' the active session without a page refresh using AJAX so that the user can stay on the upload page (in case uploads take a long time).
From your ajax you can just increment the expiry time on active_guests table.
For longer upload time to be extended you may add a last_activity as timestamp.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With