Laravel 5 new auth: Get current user and how to implement roles? - php

I am currently experimenting with the new Laravel 5 and got the authentication to work (register/login).
To get the authenticated user in my controller I currently inject Guard into the controller action:
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
class ClientController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index(Guard $auth)
{
return view('client.index', ['user' => $auth->user()]);
}
...
First Question: Is this the recommended way?
Second Question: How would I go about implementing some kind of roles/permissions? Something like client.edit, client.add, ... Does Larval 5 offer some kind of convenience here?
How would I set the necessary role/permission for a route/controller action?
I am thinking that I might need to write my own middleware for that. Any suggestions on how to approach the problem?

After spending some more time on Laravel 5 I can an answer my own question:
Is injecting Guard the recommended way? No: If you need to access Auth in your view, you can do so already like this:
#if( Auth::check() )
Current user: {{ Auth::user()->name }}
#endif
This uses the Auth facade. A list of all available facades is in config/app.php under aliases:
What if I need Auth in my controller? Injecting an instance of Guard like shown in the question works, but you don't need to. You can use the Auth facade like we did in the template:
public function index()
{
if(\Auth::check() && \Auth::user()->name === 'Don') {
// Do something
}
return view('client.index');
}
Be aware that the \ is needed before the facade name since L5 is using namespaces.
I want to have permissions/roles using the new auth mechanism in L5: I implemented a lightweight permission module using the new middleware, it is called Laraguard. Check it out on Github and let me know what you think: https://github.com/cgrossde/Laraguard
UPDATE: For the sake of completeness I want to mention two more projects. They provide everything you need to save roles and permissions in the DB and work perfectly together with Laraguard or on their own:
https://github.com/caffeinated/shinobi
https://github.com/romanbican/roles

If you want make your own custom authentification, you need to keep the User model from Laravel 5 with all the dependency. After you will be able to login your user in your controller. Dont forget to put (use Auth;) after the namespace of your controller.

Related

Laravel policy autodetect

today i was creating USER profile page with is controlled in ProfileController it returning views to profile page, profile settings, etc.
so i decide to make some Policy rules to Edit profile and etc.
so i found i should use Middleware / Gates / Policy, based on Laravel Doc i chose Policy because profil page is public but only specific part of it can author edit so i needed #can
So my steps:
php artisan make:policy ProfilePolicy ( without model )
Registered policy to AuthServiceProvider in $policies property
writed methods like edit inside ProfilePolicy
then i started thinking how i define it to my Controller hmmm, documentation doesnt helps me :/
so i tryed blade #can('edit', $user) method and it worked, but HOW ?, how to define specific policy to one Controller ? ( not Model ), how to define multiple Policy to single Controller
i m lost how laravel Magic done this maybe because of Naming ? ProfileController => ProfilePolicy ?
In the controller you can write this
public function edit(Profile $profile) {
$this->authorize('edit', $profile)
}
Laravel does this:
Check the type of $profile, and it's a Profile::class
Check policies registered for that class (your step 2)
Looks for the edit method in that policy, if not found, return false meaning user is not authorized
Executes the edit() function that returns true/false
In blade the #can directive does exactly the same thing.
Policies are meant to be tied to Models, it's a convenient way to write rules to handle single models, but they can be triggered in many ways (like the authorize() method in controllers and #can directive in blade).

Creating user profile tables that are publicly accessible in Laravel 5.8

I am having some trouble with my application when trying to create the user profiles. Here is the issue:
I am trying to create a view called userprofile.blade.php which will output any given users profile (based on id or username...doesn't really matter right now). Each profile page will show name, description, location, profile pic, and the given users posts. I used Laravel's Make:auth command to create the necessary authentication, customized the authentication forms, and then migrated all the columns I needed in my database.
My create and update methods work just fine (registering new users and updating their information). All the information is saved correctly in the database. However, I can only access it in my views with {{Auth::user()->}}. Whenever I try to use the Model in my Controller to access the data I need, it doesn't work. It seems to me as though I need to separate Laravel's default 'User' model with a custom model which I would call 'Account' or something along those lines.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\User;
use App\Recipe;
class UserController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth', ['except' => [
'index', 'show'
]]);
}
public function index(){
$user = User::find($id);
return view('user.userprofile')->with('user');
}
I only included the index method from my UserController to keep it simple. It breaks down and tells me that 'id' in $user = User::find($id); is an undefined variable. That tells me that it isn't accessing my database table.
My question is, should I create a new fresh model that isn't mixed up with authentication to handle all the user profile information? If so, how do I access my current database table 'users' from this new model?
Please let me know if I need to clarify things for you guys. I'm not very experienced and I understand if my question is fuzzy. Thanks so much for your time!! I really appreciate any help I can get!
Hello and welcome to developing with Laravel!
You're on the right track - you need to identify which user's profile you're viewing, retrieve it from the database, and pass it to the Blade view. You don't need a new model or anything, though! Just need to complete what you've started.
You should start by defining a route parameter in your route, that will capture the dynamic data you want from the URL. Let's use the numeric ID for now. If you want a URL that looks like example.com/user/439, your route should look something like Route::get('user/{id}', 'UserController#index');.
Once you have that, the id parameter will get passed to your controller's method. Define it as a method parameter, and it'll be usable: public function index($id) { ... }
I think you can take it from there. :)

How is Localization in Laravel implemented?

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.

Protect routes in Laravel 5.1

I am using Laravel 5.1 for my project. I am trying to secure Routes and make sure only logged in user can access certain routes. I am aware about middlewares but I am wondering if anyone post an example or a link explaining about middleware and how to protect a page using middleware.
Thanks
To build on the answer given by Joe Rose, you can also specify the middleware in your controller rather than in your routes.php file.
E.g you could have your routes set out like
Route::get('/example', 'ExampleController#index');
Route::post('/example/post', 'ExampleController#post');
Route::resource('blog', 'BlogController');
And then inside your controller reference it like so:
class ExampleController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
//....
If you're looking for more info, check out the link to the docs Joe gave, and also this blog post which explains what middleware is really well and how to create your own if you need to.
You are correct about using middleware. The included Auth middleware is what you should use, as long as you are also using the included Auth controller to authenticate users. You would write your route like this:
Route::get('/page', array(
'uses' => 'Controller#method',
'middleware'=>'auth'
));
(The above example is using a GET request, but it could other request types, like POST for example).
This will use the default behavior of the middleware which checks to see if the user is logged in (authenticated). You can also extend or overwrite the built-in functions to allow you to direct the application on where to send the user if they are or are not logged in, etc. Laravel's official documentation is a good starting point: link

Validation using Sentry2 in Laravel 4

I want to use Sentry2 in my Laravel 4 application but I'm not sure how to use it to validate user submitted data before I interact with it. In my own models, I would write a $rules array to contain the validation rules and write a static validates() method that I could call in the controller.
But with Sentry2, how do I do this? Do I have to extend the User model that Sentry2 provides and use that instead? Or is there a way that Sentry allows me to add validation rules with extending it?
If I do extend the Sentry2 User model, do I extend it like so:
/app/models/User.php
class User extends \Cartalyst\Sentry\Users\Eloquent\User {
private static $rules = array(...);
public static validates($input, static::$rules) {...};
}
I then need to create my own config file instead of using the one that Sentry provides. I do the following in artisan:
php artisan config:publish cartalyst\sentry
and update the config file like so:
/app/config/packages/cartalyst/sentry/config.php
'users' => array()
'model' => 'User',
;
Is this correct? If so, do I just call the model to validate user submitted data like I normally would? So, for example, in the UsersController I would check input by doing:
$validator = User::validate(Input::all());
I believe you are on the right way. Sentry doesn't really do any validation when you're saving data (except for checking for a password and a login field), and if you want to use validation from directly within the Eloquent model, you can extend the current Cartalyst user model, exactly as you have done in your code.
In the config file, you may have to take your namespaces in account. To check that Sentry really is using your model, try getting the currently logged in user (Sentry::getUser()) and var_dump it (dd(Sentry::getUser()) to see that Sentry is really using your class).
After you've got that setup, you can use your Eloquent model and validation as you normally would, with the addition of having all Sentry methods and properties.
If you want to keep the validation logic separate from you model, you can have a look at using validation as a service: http://culttt.com/2013/07/29/creating-laravel-4-validation-services/

Categories