I want to separate my cakephp application in users authentications... I have created authentication key of 50 digits as boolean. that is 10111... in this way.. Now I wanna separate my application accordingly. Suppose for blog post. I want to access to view post if users first authentication digit is 1, If my post is private then I need to authenticate it using digit 2. For any other status of my post suppose private I wanna again check an action of digit. What should I do with this scope.? Is it better way to go with...
Second I want to have common function. I have just taken example of simple controller post I wanna do it for most of my models and controllers. How can I make single inbuilt function for all.
You'll need to create all these rules in your AppControllers Authorize() method, assuming you are using the AuthComponent and Controller as your auth method.
Related
I am so confused about how to implement and how to follow SRP (single responsibility principle ) in a Laravel controller.
Suppose we have a controller which we have to do these things:
e.g
public function StorePost() {
// check user login()
//check number of current user Post count =>which must be less than 10
//store post
//send an email to user which your post has saved
//return =>api:json /web : redirect
}
I know that I can implement some DB queries in the repository but I don't know how to implement others of my logic code to achieve SRP
Also, I know there is a Heyman package to achieve these but I want to implement it by myself.
SRP in this context basically means each class and method should only be responsible for a single behaviour/feature. A rule of thumb is a class or method should change for one reason only, if it changes for multiple reasons, it needs to be broken down into smaller parts.
Your storePost method should not bother with checking the user login, that should be handled elsewhere before invoking storePost. storePost shouldnt change if the auth mechanism changes like switching from api token to json web token or something else. Laravel does this in the middleware level with the auth middleware.
Checking the users post count, this can be checked in the validation stage. storePost shouldn't change if we add more validation logic. In Laravel you can use FormValidation for this
For storing the post, the controller doesn't need to know how to call the DB, you can use the active record style using the model class or maybe create a service or repository class if your use case requires that. storePost shouldn't change if we decide to change DB vendor like going NoSQL.
For sending email, again the controller doesnt need to know how to send the email like what the subject/body recipients are. storePost shouldnt change if we need to change the email layout. Laravel has Notification for that
For serialising the response to json, the controller doesnt need to know how to format the response. if we decide to update how our json looks, storePost shouldnt change. Laravel has API Resources for that
So, ultimately in this example, the responsibility of the controller method is basically to glue all these together. It basically does what you wrote down, it only responsible for maintaining the step by step behavior, everything else is delegated to someone else. if the behavior change, like adding new behavior e.g notify all follower, storePost will change.
Let's say there some users who have several posts. Every user has many posts, and every post belongs to one user.
To change post frontend uses URL like users/1/posts/3. The goal is to check, that post number 3 belongs to user number 1.
There are several ways to do it:
Check inside controller method or service(bad method IMHO)
Check inside custom request (authorize function)
Check inside middleware
I choose between the last 2, but have some doubts. The custom request should contain validation rules and do not be linked with authorization(SOLID), and I don't know if it's good to do it inside middleware.
I assume you want to check if user can modify the post.
For authorizing access https://laravel.com/docs/7.x/authorization#creating-policies is a way to go.
After defining policy you can reuse it in blade files, in controller and etc..
The policy defines rules for standard actions like create, read, update, delete.
For blades then you can:
#can('update', $post)
For methods in controllers:
$this->authorize('update', $post)
For anywhere else:
$user->can('update', $post)
You can use Policies in conjunction with custom Form Requests
I am new to Laravel coming from CakePHP where the form and save method for a form is one and the same function name. I saw in many Laravel tutorials that the from method (that displays the form) is different than the method to save form (that actually saves data). Why using 2 different method names?
For example what's wrong with:
pub function xyz(Request $request)
{
if($results->isMethod('post')){
... then save and return redirect
}
... the code for showing the form in case there is no POST.
then having 2 routes one for GET and one for POST on the same url?
It is because people like to filter out things at route level not in controller, Also it helps developer to apply middleware grouping for each route separately. so that they can apply roles and permission etc. easily at route level.
It will looks horrible if mix all things in controller.
Think about middleware and groups in your code.
It is because you don't wanna mix a lot of logic in the same method . The case you have simple is the simple scenario . But there will be case where you wanna pass initial data in the create form . You have to write logic for that also in the same method and while you store the data you need to do the validation and calculate other business logic . If you combine all those things in one method it will mix all the things in one method and code difficult to read
I am working on the admin side of a site that I am building and wanted to lock it down. I already figured out how to do my authentication, but I am looking for a way to call this authentication function on every request being made in this controller without having to call it at the beginning of each controller method. Is there a way to pass request through a filter, or something of the sort, in the constructor?
Ex.
public function __construct()
{
filter(authenticate(), 'login,signin');
}
Where the first parameter is the method being called, and the second parameter is the methods to exclude from the filter. Because you wouldn’t want to check for a logged in user if they are on the login page or if the signin method is being used since it is the one logging them in. Does anyone know if there is a way to do this? I think it would cut back on me repeating the call to authenticate before each locked down method.
Thanks!
Figured it out
Remapping looks to have done what I was looking for. Be sure to look into it! Great function :)
Have you considered using a MY_Controller?
In MY_Controller.php, create an Auth_Controller class (name it what you like) which will check if the user is logged in in the __construct() method. Then, ave all your "locked down" controllers extend Auth_Controller.
I am trying to code my first codeigniter project. I have a login controller which basically filters the data inputed and calls a model function that checks if the user is found in the database.
What I am trying to do is reuse this controller on the index page. So basically I want to be able to do user login on the index page or on the normal controller page (index.php/login/) without code duplication.
I'm sure there is an easy way to do this, but I'm not sure what the best solution is. Make it a library?
Thanks!
For this I would simply make the form in your view post to the login controller.
As a more generic way to share code and logic throughout your application, take a look at this article:
CodeIgniter Base Classes: Keeping it DRY
You basically give each of your controllers a "type". Being logged in could be a criteria of one of your base controllers, which saves you trying to directly access any of your controllers which is bad mojo.
You can try creating a form on the index page and submit it to index.php/login/. This way you won't need two entry points.
Just do the same as you have done for the login View, specify the same action attribute of the form to the index View, and it will be sent to the same login controller with no need to create the two login controllers. You might want to append a query string in the action attribute of the form to distinguish from which View the request has come.