I am trying to modify the Laravel Auth registration system in that I'd like to require that a token parameter be provided in order for the user to be able to access the registration page (ie http://website.dev/register/{tokenhere}). Below is the pertinent code:
From my routes\web.php file:
Route::get('/register/{token}', function() {
//
})->middleware('token');
From my \App\Http\Middleware\CheckToken.php file:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckToken
{
public function handle($request, Closure $next)
{
if($request->token != 'test') { #just hard coding something here for testing purposes
return redirect('home');
}
return $next($request);
}
}
I also added 'token' => \App\Http\Middleware\CheckToken::class to the $routeMiddleware array in \App\Http\Kernel.php
However, I go to http://website.dev/register and I'm able to access the page, despite not providing a token parameter. I can also see that if I provide the 'test' parameter that the middleware is looking for (http://website.dev/register/test), I get a blank page.
Hoping someone can point me in the right direction. I'm quite new to MVC and Laravel. Thanks for your time!
You can just create custom route, like /register/{token} and handle this token in the controller. Maybe even set in middleware group if you want.
Related
I am begginer in Laravel. I am use Laravel 5.8 in my project.
I need to do something so that a specific route can be viewed by a user with a php adult = 1 session.
I have route:
Route::get('/', 'FrontendController#index')->name('index');
Route::get('/sample1', 'FrontendController#sample1')->name('sample1');
The SAMPLE1 view is for users with php adult = 1 session.
If the user does not have such a session - it must be automatically redirected to # index
How can you do this?
You can achieve this by creating a custom middleware, take a look at the documentation here:
https://laravel.com/docs/5.8/middleware
Instead of using session, you can maintain a user is adult or not on the users table, which means you can access this info via authenticated user (which is available throughout the whole app).
For e.g. in your app, use php artisan make:auth and this will scaffold out everything you need to for a register/login system. Before you run the migration, add a new field to the create_users_table migration, e.g. $table->boolean('adult')->default(false);
Then once the migration is ran, you can create a new middleware using: php artisan make:middleware CheckAdult with something like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckAdult
{
public function handle($request, Closure $next)
{
if (!auth()->check() || !auth()->user()->adult) {
return redirect('/');
}
return $next($request);
}
}
The above middleware will redirect anyone who is not logged in or have adult = 0 back to index page, otherwise continue with their request.
Then register the middleware and use it in the routes; as per the documentation.
you can use auth and middleware to achieve this. the simple logic would be something like this: $id = Auth::user()->adult; in your controller to check for users. ofcorse adult is a field in your table.
//on top of your controller place this
public function __construct()
{
$this->middleware('auth');
}
//control logic to check user
if($adult==1){
//perform unique task
}else{
return redirect('/')->with('message','You are not permitted')
}
I want to implement localization on my website using Laravel 5.5.
However, I am not sure what the standard practice when using localization should be. I have used the LocalizationController module from the Laravel documentation. My goal is to have the localization option selected via a dropdown. Then the user's selection should be remember.
Do I store their selection in a database for future use?
Or, is this something to keep in a cookie?
Side note:
(I want to avoid having their selection in the url. I'll either pass the data in a request or get method.)
For registered and logged-in users i recommend to store the users language in the database. Everytime a user logs in the application should set the language for the current user. Maybe you take a closer look on middleware. Build a language middleware, register it as new middlewaregroup and assign it to every route (-group) you need. A middleware could look like this:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class LanguageMiddleware
{
public function handle($request, Closure $next)
{
if(Auth::check()){
// user is logged in
App::setLocale(Auth::user()->language);
return $next($request);
}
App::setLocale(config('app.locale'));
return $next($request);
}
}
Now register the new middleware in app/Http/Kernel.php as new middleware-group under protected $middlwareGroups:
// other middleware-groups
'language' => [
\App\Http\Middleware\LanguageMiddleware::class
]
Finally assign middelware-group to route (-group):
Route::group(['middleware' => ['language']], function(){
// Routes...
});
Unfortunately there is no build-in function to show a dropdown-language-select. But you can simply build a blade-partial which you can integrate in your navbar or where-ever you want to show/use it. You could ask new users during registration for their preferred language.
Guests/unregistered users could use the dropdown. By default they should see the default language.
Hopefully this helps you.
I am using a session separately other than the default authentication sessions. If an user try to access my secured page, he should have the session set. If anyone without that session try to access means, they will be redirected to error page. I am using Laravel 5.3
The user can view the below two pages only if the session variable named 'secured_user' is set. Otherwise they will be redirect to the error page
Route::get('/secured-page1', 'ValidationController#CheckSecuredLogin_1');
Route::get('/secured-page2', 'ValidationController#CheckSecuredLogin_2');
The best option would be a policy.
You can create certain constrains and couple it with your models. Policies are especially suitable for changing your logic later on.
See here: Create Policy
Within you PagesPolicy, you can add this function:
public function before(User $user, $ability)
{
if ($user->isSuperAdmin()) {
return true;
}
}
public function seeSecurePage(User $user)
{
// Your custom Code and session handling
if(session("secured_user")) return true;
return false;
}
and in your controller.
$user->can("seeSecurePage","Pages");
If "can" fails, it will automatically redirect to error 403.
P.S.: Another possibility are Gates
You should use Laravel Middlewares to achieve this, I think middlewares are made for the work you need:
First create a new middleware by running the artisan command:
php artisan make:middleware CheckSesison
Then the CheckSession would look like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckSession
{
public function handle($request, Closure $next)
{
if ($session_value != 'YOUR_DESIRED_VALUE') {
return redirect('home');
}
return $next($request);
}
}
Now in your routes file you can use laravel's route middleware() method to implement it like this:
Route::get('/secured-page1', 'ValidationController#CheckSecuredLogin_1')
->middleware(CheckSession::class);
Hope this helps!
In addition to the awnser above, you could also use middleware that's used on the routes and even group them if required. It is a simple, quick and clean solution. Inside the middelware you simple check if the session you require is there and depending on the result you take any action necessary.
Laravel middleware docs
In Laravel 5, if basic auth fails for a user then the default message that is returned is an "Invalid Credentials" error string. I am trying to return a custom JSON error when this situation occurs.
I can edit the returned response in vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php
however I have not seen where you can change the behavior of this message outside of the vendor directory. Is there a way?
Looks like there were some ways to do this through Laravel 4: Laravel 4 Basic Auth custom error
Figured it out, looks like I had to create custom middleware to handle this.
Note that this solution didn't work when calling my API from my browser, only when calling it from a tool like Postman. For some reason when calling it from my browser I always got the error before seeing the basic auth prompt.
In my controller I changed the middleware to my newly created one:
$this->middleware('custom');
In Kernel I added the location for it:
protected $routeMiddleware = [
'auth.basic.once' => \App\Http\Middleware\Custom::class,
]
Then I created the middleware. I used Stateless Basic Auth since I'm creating an API:
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
use Illuminate\Http\Request as HttpRequest;
use App\Entities\CustomErrorResponse
class Custom
{
public function __construct(CustomErrorResponse $customErrorResponse) {
$this->customErrorResponse = $customErrorResponse
}
public function handle($request, Closure $next)
{
$response = Auth::onceBasic();
if (!$response) {
return $next($request);
}
return $this->customErrorResponse->send();
}
}
I'm using the jwt-auth package for Laravel. It's working great, but it seems that a user has to be authenticated or not.
For instance some routes do not require authentication, but if the token is present it should still authenticate the user. The parameters I display to user from API can vary based on the type of users access. So admins will get some additional parameters.
Right now it will always just throw token absent. But it should go through as normal and "IF" token is present, process it.
Not sure if I need to create a custom middleware for this.
class JWTAuthIfPresent
{
public function handle($request, Closure $next)
{
if (JWTAuth::getToken()) {
JWTAuth::parseToken()->authenticate();
}
return $next($request);
}
}
This seems to work, but not sure if there is a better way or something already in the existing package.
EDIT:
Also this will not deal with any token issues, like token= or some invalid or expired token. If set it should still process the token normally.
Ok, I was able to figure this out by simple extending the existing auth.
namespace App\Http\Middleware;
use JWTAuth;
use Closure;
use \Tymon\JWTAuth\Middleware\GetUserFromToken;
class JWTAuthIfPresent extends GetUserFromToken
{
public function handle($request, Closure $next)
{
if (JWTAuth::getToken()) {
return parent::handle($request, $next);
}
return $next($request);
}
}