#laravel auth role
Explore tagged Tumblr posts
Text
Inventory Management System Development
Inventory management is essential for businesses that deal with physical goods. An efficient inventory system helps track stock levels, manage orders, reduce waste, and improve overall operational efficiency. In this blog post, we’ll explore the key components and programming approach for building an Inventory Management System (IMS).
Core Features of an Inventory Management System
Product Catalog: Add, edit, delete, and categorize products.
Stock Tracking: Monitor stock levels in real-time.
Purchase & Sales Records: Track incoming and outgoing items.
Supplier & Customer Management: Manage business relationships.
Reports & Analytics: Generate sales, inventory, and purchase reports.
Alerts: Notify when stock is low or out of stock.
Tech Stack Suggestions
Frontend: React.js, Vue.js, or Angular
Backend: Node.js, Django, Laravel, or Spring Boot
Database: MySQL, PostgreSQL, or MongoDB
Authentication: JWT, OAuth, or Firebase Auth
Deployment: Docker + AWS/GCP/Heroku
Basic Database Structure
Products Table: - product_id (PK) - name - category - quantity - price - supplier_id (FK) Suppliers Table: - supplier_id (PK) - name - contact_info Sales Table: - sale_id (PK) - product_id (FK) - quantity_sold - date Purchases Table: - purchase_id (PK) - product_id (FK) - quantity_purchased - date
Sample API Endpoints (Node.js Example)
GET /products – List all products
POST /products – Add a new product
PUT /products/:id – Update product details
DELETE /products/:id – Remove a product
GET /inventory/report – Generate inventory report
Frontend Functionality Tips
Use modals for adding/editing items
Display stock levels using color indicators (e.g., red for low stock)
Enable filtering/searching by product category or supplier
Use charts for visual stock and sales analytics
Bonus Features to Consider
Barcode Scanning: Integrate barcode scanning for quick item lookup
Role-Based Access: Allow different permissions for admin, staff, and viewer
Mobile Access: Build a mobile-responsive UI or companion app
Data Export: Export inventory reports to Excel/PDF
Conclusion
Building an inventory management system can significantly benefit any business that handles products or stock. By designing a system with clean UI, efficient backend logic, and accurate data handling, you can help companies stay organized and save time. Start simple, scale gradually, and always prioritize usability and security in your system design.
0 notes
Text
Answers To The Important Laravel Security Questions
Introduction

Laravel is a powerful PHP framework known for its elegant syntax and robust features, making it a popular choice for web developers. However, like any web development framework, security is a critical concern. Ensuring that your Laravel applications are secure is essential to protect sensitive data and maintain user trust. Security is the most common concern for many businesses. This is well justified because of the growing concern about an increase in cyberattacks. In this article, we address vital security questions related to Laravel. It provides insights and tips on Laravel security best practices to help safeguard the applications.
Significance of Application Security

Application security is a critical aspect of Laravel development (and any software development) that ensures the protection of data and systems. It protects users from various threats and vulnerabilities. Here are a few key reasons why application security needs to be a high priority:
Data Breaches: Securing applications helps prevent unauthorized access to sensitive data, such as personal information, financial details, and confidential business data.
Reputation Management: Users are more likely to trust and engage with applications that prioritize security. A single security breach can severely damage a company’s reputation and erode user trust.
Prevents Financial Loss: Data breaches can result in significant financial losses due to legal fees, fines, and remediation costs. Security incidents can lead to loss of business, decreased customer confidence, and long-term damage to brand equity.
Data Integrity: Application security helps ensure that data is not tampered with or altered by unauthorized entities.
Common Threats: Laravel security measures protect against various cyber threats, including SQL injection, Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), and more.
Advanced Threats: Security practices also help defend against more sophisticated attacks, such as zero-day exploits and Advanced Persistent Threats (APTs).
Application security cannot be overstated. It is essential for protecting sensitive data and maintaining user trust. It also helps prevent financial losses, ensure application integrity, and mitigate cyber risks.
It plays a big role in enhancing development processes, supporting business continuity, and facilitating compliance with legal requirements. Prioritizing security is crucial for the success and longevity of any business operating in this digital age.
Here are a few relevant facts and statistics:
The application security market is expected to generate $6.97 Billion in 2024.
According to Statista's forecast, the size of the security market in 2028 will be $11.83 billion.
Application breaches account for 25% of all breaches.
Over 75% of applications will have at least one flaw.
As per a report by IBM, the costliest data breach was $4.25 Million.
An average ransomware attack costs $4.54 million.
Vital Laravel Security Questions

How Does Laravel Handle Authentication?
Laravel offers an out-of-the-box comprehensive authentication system that simplifies the implementation of user login and registration. The Auth facade provides an easy way to manage authentication, including features such as:
User registration and login
Password reset functionality
Authentication guards
User roles and permissions
Use Strong Password Policies
Two-factor authentication (2FA)
Secure Password Storage
How Can You Prevent SQL Injection in Laravel?
Laravel uses Eloquent ORM and the query builder, which automatically protects against SQL injection. By using parameter binding, Laravel ensures that user input is safely escaped before executing SQL queries.
Always prefer Eloquent ORM for database interactions, as it inherently protects against SQL injection. When using raw SQL queries, always use parameter binding to ensure inputs are correctly escaped.
How Does Laravel Protect Against Cross-Site Scripting (XSS)?
Laravel provides built-in protection against XSS by automatically escaping output. This means that any data retrieved from the database and displayed in views is escaped to prevent script injection. Always escape output using Laravel’s {{ }} syntax for variables.
How Can You Prevent Cross-Site Request Forgery (CSRF) in Laravel?
Laravel automatically generates a CSRF token for each active user session. This token is embedded in forms and must be included in any request that modifies data. Laravel then verifies the token to ensure the request is legitimate. Ensure all forms include the CSRF token.
How Can You Secure Laravel Routes and Controllers?
Laravel middleware provides a mechanism for filtering HTTP requests entering your application. Use authentication and authorization middleware to protect routes. Apply appropriate access controls to routes to ensure only authorized users can access certain parts of the application. Controllers handle the business logic of your application and should also be secured. Always validate user inputs in controllers to prevent invalid data from being processed. Laravel’s authorization policies provide a way to manage user permissions for accessing specific actions.
How Can You Secure Laravel’s File Uploads?
Ensure that only allowed file types and sizes are uploaded with the help of validation techniques. Store uploaded files outside the public directory to prevent direct access.
How Can You Implement a Secure Password Reset in Laravel?
Laravel provides a robust password reset feature out of the box, including generating secure tokens and sending password reset emails. It uses a secure token generation mechanism, ensuring that tokens are unique and hard to guess. Limiting the number of password reset requests from a single IP address prevents brute-force attacks.
How Can You Secure Laravel APIs?
Secure your APIs with tokens using Laravel Passport or Laravel Sanctum. Implement rate limiting on API endpoints to prevent abuse. Encrypt data in transit using HTTPS and ensure that sensitive data is never transmitted in plain text.
How Can You Keep Laravel Dependencies Secure?
Only use packages from trusted sources and review their security practices before including them in your project. Use tools like snyk or npm audit to scan your dependencies for known vulnerabilities.
How Can You Implement Logging and Monitoring in Laravel?
Logging and monitoring are essential for detecting and responding to security incidents. They provide insights into application activity and help identify potential security issues. Laravel provides a robust logging system based on Monolog. Configure logging to capture important events and errors. Review logs regularly for suspicious activity and respond promptly to any potential security threats.
Most common security threats faced by Laravel applications?
Cross-Site Scripting (XSS): Attackers inject malicious scripts into web pages viewed by other users.
SQL Injection: Malicious SQL statements are insert into an entry field for execution.
Cross-Site Request Forgery (CSRF): Unauthorized commands are transmit from a user that the web application trusts.
Unauthorized Access: Improper authentication and authorization checks can allow users to access restricted areas.
Data Leakage: Sensitive information is exposed due to improper handling of data.
What are some common misconfigurations that can lead to security vulnerabilities in Laravel applications?
Debug Mode: Never run your application in debug mode in a production environment. Debug mode can expose sensitive information about your application's configuration.
Environment Variables: Ensure that sensitive information in the .env file is not expose and is securely manage.
Server Configurations: Ensure the server is configure correctly to prevent directory listing and other exposures. Use .htaccess or server configurations to secure directories.
Some advanced security features provided by Laravel 11?
Argon2id Support: Enhanced password hashing with support for Argon2id, providing better resistance against side-channel attacks.
Native Two-Factor Authentication (2FA): Built-in support for adding a layer of security to user accounts.
Automatic HTTPS Enforcement: Easier enforcement of HTTPS across all routes, ensuring data encryption during transmission.
What role does Laravel Telescope play in application security?
Real-Time Monitoring: Telescope provides real-time monitoring and logging of security-related events such as failed login attempts, CSRF token mismatches, and more.
Alerting: Enhanced alerting and notification features to keep developers informed of potential security issues, allowing for swift action.
Secure Your Laravel Application
Securing a Laravel application involves a multifaceted approach that includes secure authentication and protection against common vulnerabilities. No one can help better with secure Laravel development, than an official Laravel partner.
Acquaint Softtech is one such software development outsourcing company in India. We have over 10 years of experience delivering cutting-edge solutions.
Security requires ongoing attention and diligence. Always stay informed about Laravel's security features and adhere to best practices. Make the most of the available resources to reduce the risk. Hire remote developers from Acquaint Softtech and gain an upper edge.
A secure application protects your users. At the same time, it enhances the credibility and reliability of your work as a developer. Make a smart business decision to choose between outsourcing and **IT staff augmentation.**
FAQ
What are the most common security threats to Laravel applications?
Cross-Site Scripting (XSS), SQL Injection, Cross-Site Request Forgery (CSRF), unauthorized access, and data leakage.
How does Laravel prevent Cross-Site Scripting (XSS) attacks?
Laravel's Blade templating engine automatically escapes output to prevent malicious scripts from being execute.
How does Laravel mitigate SQL Injection?
Mitigating SQL Injection: Eloquent ORM and Query Builder use PDO parameter binding to safely handle user inputs, preventing direct insertion into SQL queries.
What measures does Laravel take to prevent Cross-Site Request Forgery (CSRF)?
Laravel generates a CSRF token for each user session, which is verified by middleware for all state-changing requests to ensure they are legitimate.
What are the best practices for authentication and authorization in Laravel?
Use Laravel’s built-in authentication system and implement policies and gates to effectively manage user permissions.
0 notes
Text
Fix Broken Access Control in Laravel: A Guide for Developers
Broken Access Control is one of the most critical vulnerabilities listed in the OWASP Top 10. This vulnerability occurs when users can access resources or perform actions they’re not authorized to, potentially compromising sensitive data or functionality. Laravel, as a widely used PHP framework, is not immune to such risks. This blog dives into how broken access control issues manifest in Laravel applications and provides a coding example to mitigate them effectively.

Before diving into the technical details, take advantage of our tool to test website security free to detect security flaws, including broken access control, on your website.
What is Broken Access Control?
Broken Access Control arises when the application fails to enforce proper restrictions on users attempting to access restricted resources. This may lead to:
Unauthorized access to sensitive data.
Modification or deletion of data.
Privilege escalation.
Example Scenario: A regular user manipulates a URL to access an admin-only page and gains unauthorized access to critical functionalities.
Laravel and Broken Access Control
Laravel provides built-in mechanisms like middleware and policies to control access. However, misconfigurations or coding oversights can lead to vulnerabilities.
Here’s an example of a common misconfiguration:
php // Vulnerable Code Example Route::get('/admin', function () { return view('admin.dashboard'); });
In this case, any user who knows the /admin URL can access the admin dashboard, as no access control checks are in place.
How to Fix It?
Use Laravel's middleware to enforce authentication and authorization checks. Here’s an improved version of the above route:
php // Secure Code Example Route::get('/admin', function () { return view('admin.dashboard'); })->middleware(['auth', 'can:admin-access']);
auth Middleware: Ensures the user is authenticated.
can:admin-access Middleware: Confirms that the user has the appropriate role or permission.
Real-World Testing with Our Tool
To ensure your Laravel application is secure, test it using our free Website Security Scanner Tool. Below is a screenshot of the tool's interface, where you can input your website URL for a comprehensive security check.

Vulnerability Assessment Report
When you run a security check using our tool, you receive a detailed Website Vulnerability Assessment Report. This report highlights the issues found and recommends actionable steps to secure your site. Here's a sample screenshot of the report:

Preventive Tips for Laravel Developers
Always Use Middleware: Enforce authentication and authorization rules at the route level.
Leverage Policies and Gates: Use Laravel's policies and gates to define granular access controls.
Secure Sensitive URLs: Avoid exposing critical URLs unnecessarily.
Regularly Test Your Application: Use tools like our Website Security Checker to detect and fix vulnerabilities.
Conclusion
Broken access control vulnerabilities can have severe consequences, but Laravel's robust tools make it easier to implement and enforce security best practices. By securing your application and regularly testing it with tools like ours, you can protect your users and data effectively.
Want to ensure your Laravel application is fully secure? Test your site now with our Free Website Security Checker and fix vulnerabilities before they become a threat!
#cyber security#cybersecurity#data security#pentesting#security#laravel#access control solutions#access control system
1 note
·
View note
Text
Best Laravel Packages for Auth and Users
Discover the top Laravel packages for authentication and user management. Enhance your web applications with powerful, secure, and customizable solutions for user roles, permissions, multi-auth, social login, and more. Learn how to simplify authentication tasks and improve user experience with these must-have Laravel packages. You Can Learn How to Calculate the Sum of Multiple Columns Using Eloquent
1. Spatie Laravel Permission
Spatie Laravel Permission is a powerful package for managing user roles and permissions in Laravel applications. It simplifies assigning roles and permissions to users or other entities, providing a flexible way to control access to various parts of your application.
Key Features:
Roles and Permissions: You can assign one or more roles to a user and assign specific permissions to these roles.
Middleware: It provides middleware to restrict access to routes based on roles or permissions.
Database Storage: Permissions and roles are stored in the database, allowing easy updates without redeployment.
Blade Directives: You can use directives like @role, @hasrole, and @can to check roles and permissions within Blade views.
Multiple Guards: It supports multiple guards, making it useful for applications with different user types (like admins and regular users).
Caching: It caches the permissions to avoid repeated database queries.
Read More

0 notes
Text
Hezecom: Laravel Project and Admin Maker
Hezecom: Laravel Project and Admin Maker
[ad_1]

With Laravel framework, projects can be completed within minimal time-frame, but projects can even be completed faster with the new Hezecom Project and Admin Maker. With just few clicks your application will be ready for deployment with admin template, front-end template and codes are generated automatically with advanced roles and permission management.



Plugins
View On WordPress
#admin template#facebook login#generator#google login#Laravel#laravel admin#laravel code#permission#project maker#responsive#roles#social auth#social login#twitter login
0 notes
Text
Laravel 7: Usuarios y Roles
laravel new proyecto_roles
Crear el recurso de autentificación Auth:
php artisan make:auth
Crear el modelo Role con su respectiva migración (parámetro -m):
php artisan make:model Role -m
Editar la clase CreateRolesTable en la carpeta de migrations:
public function up() { Schema::create('roles', function (Blueprint $table) { $table->increments('id'); $tabl…
View On WordPress
1 note
·
View note
Text
Create Multi Auth using Guards in Laravel Application
Create Multi Auth using Guards in Laravel Application
How to create #Laravel multiple authentications for multi-role users? This is one of the most requested topics on this channel. In this tutorial, you will learn step … laravel
View On WordPress
0 notes
Text
Laravel VII: Abbreviated | Web Development - Yudiz Solutions Pvt. Ltd.
Overview:
Hello there. As we all know the Laracon Online 2020, the largest online Laravel conference, took place on 26 February 2020. Our developer happened to attend a Laracon Online Viewing Party and according to his experience we are going to share with you the highlights. We’re going to focus on Laravel 7 here. Yes, it’s here and stick till the end to know all about it.

So as most of you might know Taylor Otwell was one of the speakers at the event. He gave us a complete walkthrough for Laravel VII and we are going to cover most of it here.
What is Laravel Airlock?
Airlock is a lightweight Token Generation and verification tool (Provides Authentication) mostly for SPAs (Single Page Applications), where users can generate multiple API tokens and like passport, we can set the roles for particular auth token.
AirLock will work with Laravel 6.x, but everyone recommends using it with Laravel 7.x and you also need to use Laravel UI 2.x for UI files.
We can set allowed domain in config file, so if a request comes from that particular server then and only then that request gets served. So we can say airlock is a similar kind of structure like a passport but it’s for SPA.
For better understanding,we can compare AirLock mechanism with Node/Angular project where frontend API will use AuthToken. Authtoken is similar kind of personal access token which we are used in the passport for mobile authentication
Key features of AirLock:
EncryptCookies
AddQueuedCookiesToResponse
StartSession
VerifyCsrfToken
Laravel Custom Casts:
In Laravel VII, we can create our own casting for an eloquent model, there are two methods, “get()” and “set()”
“get()” method is used to convert raw data into casted data.
“set()” method is used to convert casted data into raw data value.
For example, if we need to decode data when we receive it and encode data when we save details, we can use these methods like this:
Syntax for “get()” method:
public function get($model, $key, $value, $attributes) {
return json_decode($value, true);
}
Syntax for “set()” method:
public function set($model, $key, $value, $attributes) {
return json_encode($value, true);
}
For eloquent we need to define detail as:
protected $casts = [
'column_name' => Json::class,
];
So now every time we fetch data of a column, we get JSON decoded data and when the data is saved to the column it will get encoded.
HTTP Client:
HTTP Client is used for making an HTTP request from one website to another website or web application. For HTTP client you have to install guzzlehttp/guzzle package into your project. We can make any request along with header through the HTTP Client, also we get the details of response and other params directly, like if we want the main body of the response, then just write down $response->body() this will return the body. If we need to check the status of the response then just need to call $response->status().
Likewise, we can use the following details:
$response->body();
$response->json();
$response->status();
$response->ok();
$response->successful();
$response->serverError();
$response->clientError();
$response->header($header);
$response->headers();
And for the routes we have to write details like:
$response = Http::withHeaders([
'accept' => 'application/json',
])->post('http://domain.com/users/list', [
'name' => 'User',
]);
So now onwards we can fire the API from the web routes along with the Headers. We can also pass the Bearer Token by just adding:
$response = Http::withToken('token')->post('http://www.domain.com', ['name' => 'User']);
Fluent String Operations:
We can all agree how useful string operations are as they help us manipulate strings easily and without much hassle. Thanks to Laravel VII, some new and useful string operations were added in this version. String operations such as trim(), replace(‘x’, ‘y’), after(), before(), words() and many more now will be available in Laravel VII.
CORS Support:
Laravel VII also came with the fresh first-party package “CORS” along with options, so now no need to create custom middleware for the same, just configure the config files and use CORS services.
Stub Customization:
This is one of the best updates of Laravel. This will help us to boost up the speed of development. For example, whenever we create a new Model, we will write protected $guarded = [*] in all the models, it becomes a bit time consuming if you see it on a larger picture. So now, we can create our own stub for these kinds of changes, So, if we added protected $guarded = [*] into stub then whenever we create a new model, this line will be added automatically. For example, in all tables we need one default column $table->string(‘custom_id’), in all the migrates, so we will publish the stub and customize it.
Route Model Binding:
This is one of the most interesting features of Laravel 7. In the older version, we can bind any model to route, for example:
Route::get('user/{user}', function(User $user) {
dd($user);
});
// domain.com/user/1
Here we’ll get the user’s personal details like we applied dependency injection of the User model. In Laravel 7, there is support for Implicit Model Binding, such as if I want to get the user’s details based on the user’s name then I’ll get details by adding simple “:” after model’s name.
Route::get('user/{user:username}', function(User $user){
return $user;
});
// domain.com/user/kmjadeja
We can also add custom keys and scoping for the Route Model Binding, it’s a very useful thing which can help us to generate SEO friendly URLs.
Custom Keys and Scope:
Sometimes, we need to bind multiple models to the single route and second binding param is dependent on the first building param like we need to get product details that are available under one specific category.
For example, we get all the lists of all the mobile devices which are available under the android category, So now we can do this with simple Route Model Binding
Route::get('category/{category:type}/device/{device:type}',
function (Category $category, Device $device) {
return $device;
});
// domain.com/category/mobile/device/android
One more simple example:
Route::get('user/{user}/posts/{post:slug}',
function (User $user, Post $post) {
return $post;
});
// domain.com/user/1/posts/upcoming-events
Laravel Query Cast:
· Query cast is used to “cast” a column while executing the query.
· Let’s take an example : In the database we save user’s ID, System IP, create_at and updated_at details when user LoggedIn to the system. Now we want to know the last login date of particular user in that case my code will be:
$users = User::select([
'users.*',
'last_logged_in_at' => UserLog::selectRaw('MAX(created_at)')
->whereColumn('user_id', 'users.id')
])->where('id', 1)->withCasts([
'last_logged_in_at' => 'date'
])->get();
So here we get the user’s last loggedIn details in “data”, not in the timestamp, we cast the user’s create_at column to date.
Improve email template design:
In Laravel 7 they have simply improved the email template, made the email template simpler and finer.
Queue Configuration:
Currently, if any queue or job is throwing an exception, each time the job will get executed and throw the exception. In Laravel 7, we can set maxExceptions for jobs. If we set the value equal to 3, in that case, if the job gets the exception more than 3 times, the queue stops automatically. #noExtraExecution
Speed improvements for route-cache:
Laravel 7 have 2x speed improvement for routes, it is mostly used with 800+ routes (big projects), php artisan route:cache is used to cache the routes.
Conclusion:
So that’s all for this blog but that’s not all for Laravel 7 and our discussion on it. Stick with us for the next blog regarding some of the features along with their demo codes. Till then, get started with the master document. You can read the master document here.
Hope, you have liked & enjoyed this blog. If you like this blog then follow us for more such interesting articles on the latest technologies.
0 notes
Text
Vanguard - Advanced PHP Login and User Management
New Post has been published on https://intramate.com/php-scripts/vanguard-advanced-php-login-and-user-management/
Vanguard - Advanced PHP Login and User Management
LIVE PREVIEWGet it now for only $35
Vanguard is PHP application, written in Laravel PHP framework, that allows website owners to quickly add and enable authentication, authorization and user management to their website. It is designed following latest security and code standards and it is ready for high availability websites. Although it is written in Laravel, it can be used to provide secure login, authentication, authorization and complete user management for any PHP powered website. Vanguard also comes with fully documented JSON API which allows you to easily authenticate users from your mobile (or any other) application.
It comes with almost three hundred automated tests (functional and unit), that cover all vital parts of the application and the API and ensures it’s maintainability and stability.
Version 5.0.1
Features
Secure user registration and login
Social Authentication using Facebook, Twitter and Google+
Password reset
Two-Factor Authentication
Remember Me feature on login
Login with email or username
Google reCAPTCHA on registration
Authentication Throttling (lock user account after few incorrect login attempts)
Interactive Dashboard
Unlimited number of user roles
Powerful admin panel
Unlimited number of permissions
Manage permissions from admin interface
Assign permission to roles
Easily check if user has permission to perform some action
JSON API to build any kind of applications around Vanguard
Super easy installation using installation wizard
User Activity Log
Avatar upload with crop feature
Built using Bootstrap 4
Active Sessions Management (see and manage all your active sessions)
Admins can impersonate users
Full unicode support
Client side and server side form validation
Fully customisable from settings section
Complete and detailed documentation
Fully object oriented and commented PHP and JavaScript code.
Localization support – Translate the application to any language (English, Serbian and German translations included)
Runs on PHP 7.2.5+
Flexible Plugin System
Security
CSRF Protection – all forms include CSRF token
Session Protection – highly secure Laravel session mechanism
Highly secure one-way password hashing
Server Requirements
PHP >= 7.2.5
BCMath PHP Extension
OpenSSL PHP Extension
PDO PHP Extension
Mbstring PHP Extension
Tokenizer PHP Extension
Ctype PHP Extension
XML PHP Extension
JSON PHP Extension
GD PHP Extension
Fileinfo PHP Extension
Demo and Documentation
Demo link: https://demo.vanguardapp.io
Admin Credentials
Username: admin
Password: admin123
Documentation and Support: https://milos.support-hub.io/
Discount Notifications
Subscribe to receive notifications about discounts and updates: https://vanguardapp.io/#subscribe
Changelog
Check the docs for upgrade guide.
April 8, 2020 – Version 5.0.1
Fixed installation wizard
April 5, 2020 – Version 5.0.0
Fixed custom login redirect issue Upgraded to Laravel 7 Switched to Laravel Sanctum for API authentication Replaced API transformers with Laravel's API Resources Changed API response format
September 16, 2019 – Version 4.0.1
Fixed password reset email issue Fixed avatar upload issue Updated registration and email verification flow
September 13, 2019 – Version 4.0.0
Added Plugin Support Upgraded to Laravel 6
April 1, 2019 – Version 3.2.1
Fix installation issue
March 30, 2019 – Version 3.2.0
Upgraded to Laravel 5.8 Replaced deprecated Larvel str_ and array_ helper functions
October 30, 2018 – Version 3.1.0
Upgraded to Laravel 5.7 Fixed issue with API when country_id field is null Fixed Notifications Settings update bug Improved Two-Factor Authentication by adding one more step for phone verification Added Impersonate feature
June 14, 2018 – Version 3.0.1
Minor bug-fix release to address a few mostly UI related bugs. List of changed files available inside the upgrade guide.
May 17, 2018 – Version 3.0.0
Complete frontend re-write with Bootstrap 4 Remove additional step for Twitter authentication since Twitter can provide an email now Update sizes of the avatars retreived during social authentication
March 13, 2018 – Version 2.2.0
Upgrade to Laravel 5.6 Fix issue with Authy secret key and config caching Fix issues with registration history chart Fix installation issue on PHP 7.2
December 19, 2017 – Version 2.1.1
Added ability to configure dates format across the app Added automatic session invalidation and log out of the user if he is banned by the administrator Added device info on session list page Updated dashboard chart to display data in last 365 days (instead of for current year) Extracted model factories to different files (important for testing purposes only) Fixed autoload include issue for existing websites
November 08, 2017 – Version 2.1.0
Upgrade Laravel to version 5.5 Fix glitch on User Acivity search
September 14, 2017 – Version 2.0.2
Fix avatar update issue when admin is updating avatar for some other user Disable API authentication for banned and unconfirmed users Fix country update issue which occures on some MySQL versions
August 25, 2017 – Version 2.0.1
Fix installation issues from previous version Update documentation
August 23, 2017 – Version 2.0.0
Add fully tested JSON API Fix some minor glitches related to translation
May 1, 2017 – Version 1.3.3
Fix incompatibility issues between laravel-jsvalidation package and Laravel Framework version 5.4.19+ Fix issue where country is set to null after user logs in
April 12, 2017 – Version 1.3.2
Removed zizaco/entrust package and replaced with Vanguard's native mechanism for handling roles and permissions $user->can() method now use Laravel's default authorization mechanism. For checking if user has permission defined by Vanguard, you should use $user->hasPermission('...').
March 06, 2017 – Version 1.3.1
Fixed installation issue Fixed issue with FORCE_SSL
February 18, 2017 – Version 1.3.0
Laravel 5.4 upgrade IMPORTANT: Fixed potential security issue with user avatar upload Fixed issue to don't allow banned users to log in via social networks Expanded and updated automated tests to cover all bugs and issues from above
September 30, 2016 – Version 1.2.1
Fixed bug when creating/updating users from admin panel without selected country Fixed small typos on delete user confirmation popup
September 27, 2016 – Version 1.2.0
Updated to Laravel 5.3 InnoDB is now forced storage engine for MySQL database Slightly improved design E-Mail templates updated (now using Laravel 5.3 Notifications feature) Fixed default country value Fixed n+1 problem for activity page (added missing eager loading) Fixed translation glitches Added IIS configuration file PHP 5.6.4 is now minimum PHP version required (Laravel 5.3 requirement) PHP XML extension is now requirement (Laravel 5.3 requirement) Updated and extended documentation Dropped support for HHVM, since Laravel 5.3 does not support it
March 30, 2016 – Version 1.1.2
Add missing middleware to redirect user to install page if Vanguard is not installed
March 29, 2016 – Version 1.1.1
Added German translation files Add translation for few missed strings Fix some small bugs
March 15, 2016 – Version 1.1.0
Add localization support Use social network profile image as default avatar after social auth Fix problems with pagination while browsing search results for users and activities Handle missing email from non-twitter social provider
February 18, 2016 – Version 1.0.4
Updated documentation Added option to allow redirect to custom page after login Disable access to login page for authenticated users
February 4, 2016 – Version 1.0.3
Updated documentation Fixed css glitches Added more tests
January 25, 2016 – Version 1.0.2
New design for error pages Updated installer to require Fileinfo extension
January 22, 2016 – Version 1.0.1
Add missing configuration placeholder file
January 21, 2016 – Version 1.0.0
First release
LIVE PREVIEWGet it now for only $35
0 notes
Text
Mint Invoice SaaS Version (Miscellaneous)
Introduction
Mint Invoice is “web-based”, “open source”, “paid” invoicing script which can be used to create, send invoices and get paid for your invoices online directly by your customers. Moreover, you can send quotations to your customer, covert it to invoice, once your customer accepts the quotation. You can keep track of all your invoices, quotations as well as account transactions. The interface of Mint Invoice is inspired from “Paypal” which provides simple, elegant way to create Invoices. With quotations, transactions and such other feature, “Mint Invoice” is a complete invoicing application one can use to improve business. It is designed as SPA (Single Page Application) with minimum page refresh & supports Full REST API, which allows you to integrate the application with any other application.
With SaaS Version of “Mint Invoice”, you can host entire script in your server and offer all the above functionalities to your customers. Your customer need not to install the script in their computer thus saving a lot of time of your customer by reducing installation and maintenance. Your centralized script will serve individual instances for every customer, making this script “on-demand” as and whenever required by accessing “anywhere & everywhere” from “any devices” whether it is laptop, desktop, tablet or mobile.
The script is designed with Most Popular PHP framework Laravel 5.6 & simplest Javascript framework Vue.js as Single Page Application. The script comes with one click installer that can be deployed in local or live server. It includes unencrypted, unminified vesion of all development files that you can customize as per your use within the license terms.
The script supports REST Api & uses JSON based authentication token. The script is well documented and help documents are available at http://support.scriptmint.com
This script will be updated regularily with latest version of framework & plugins. Please share your feedback, feature request which will be surely implemented in upcoming versions.
The code is well commented and written with love by www.scriptmint.com. Here is the example:
What are the pre-requisites to install this script?
Here are list of pre-requisites which is required to install this script:
PHP 7.1.3
OpenSSL PHP Extension
PDO PHP Extension
Mbstring PHP Extension
Tokenizer PHP Extension
XML PHP Extension
Mcrypt PHP Extension
The script supports REST api with example documentation, Here is screenshot of API documentation:
What does it include?
Here are list which is included in this script:
Built with Laravel 5.6.21
Vue.js 2.5.16
Responsive Bootstrap 4.1.0
REST Api
Speed-up development with Laravel Mix-Webpack
Browser Sync
Support Sass
JSON based authentication, Uses tymon/jwt-auth
Single Page Application (SPA), Uses Vue Router
Vuex for data flow
Pagination
Datepicker
What modules are available with Laravue Starter Kit?
Here are list of pre defined components which is available in this script:
Autosize Textarea
Date Range Picker
File Upload Input
File Upload Progress
HTML Editor
Upload Image
Here are list of modules which is available in this script:
User Authentication
Social oAuth
Reset Password
User Registration
User Activation
Account Approval
Two Factor Authentication
Screen Lock
Login Throttle
Reset Password Token Lifetime
Login Lifetime
Password Strength Meter
User List
User Profile
Change Password
User Avatar
Sample Todo Module
Private Message
Database Backup
IP Filter
Maintenance Mode
Multilingual
RTL Support
Date/Time Format & Timezone
Activity Log
Email Log
Custom Email Templates
User Roles & Permissions
Multiple Mail Drivers
Nexmo SMS Api
Invoicing
Paypal & Stripe Payment Gateway
Quotation
Coupon
Reports
FAQ’s
What license information is required during installation?
The script requires “Access Code” to be entered during installation. You need to login with your envato account to https://auth.scriptmint.com to get the access code and add domains where you willing to install the application. More information about “Access Code” can be accessed here http://support.scriptmint.com/support/solutions/articles/42000022689-where-can-i-get-access-code-required-during-installation-
Does this script include all source code with unminified version?
Yes, this includes everything, including composer.json, package.json, webpack.mix.js, different plugins and all in it.
Where can I access documentation?
All the documentation is available at http://support.scriptmint.com which you can access online. In case you face any issue, please raise a ticket at http://support.scriptmint.com. Estimated response time is 48 working hours.
Does author provides installation support?
No, author doesn’t provide installation support in any environment (live or local). You can read the support documentation which is available online.
Will I get support for further development if I have any queries?
Yes, you will get answer of all your queries and issues (if any). Please note that author is not going to teach you coding skill but author is providing a starter kit which you can use to learn, develope Laravel + Vue.js project. It is recommened to have basic knowledge of any PHP framework along with Javascript. Also note, that support is only available to the customers, who have purchased the script from www.codecanyon.net. You need to provide your Envato Username & Purchase code in order to get author support.
Does author provides customization?
Yes, author is available for customization but with extra charge of $15 per hour.
Can I use this script for multiple instance?
No, if you have purchased regular license then you can only use this script only for 1 instance. If anytime, it is found that you have used multiple instance of this script, your support will be blocked immediately.
Documentation related to this script is available at http://support.scriptmint.com/support/solutions/folders/42000076991
If you have any query, please raise a ticket at http://support.scriptmint.com
from CodeCanyon new items https://ift.tt/2xdsUGR via IFTTT https://goo.gl/zxKHwc
0 notes
Text
Laravel Multi Auth – Lara 5.8, 5.7, 5.6 Multiple Authentication
Laravel Multi Auth – Lara 5.8, 5.7, 5.6 Multiple Authentication
Multi Laravel Authentication (auth) – Today we will show you how to create a multi auth system in laravel 5.8. Mulitple auth system means that many users can log in one application according to their role.
Multiple authentication is very important in large applications 5.6, 5.7, 5.8. Authentication is the process of recognizing user credentials.
In this multi-auth laravel system, we will create a…
View On WordPress
#laravel multi auth#laravel multi auth 5.8#laravel multi auth admin and user#laravel multi auth api#laravel multi auth github#laravel multi auth guard#laravel multi auth logout#laravel multi auth package#laravel multi auth using guard#laravel multi authentication
0 notes
Photo

New Post has been published on http://programmingbiters.com/save-laravel-app-settings-in-database/
Save laravel app settings in database
I this post I am going to share one feature which most of the application have these days to change certain settings using UI, it can be implemented in many ways but one way I find doing is to store settings in the database and provide an auto-generated form to change the settings.
What are we building?
We will be building a setting management system which will be easily customizable and you can use it in any app you want to give the option to change the settings on the fly using a form UI.
Source Code
We will create a config file where we can define all the options you want to give the user as settings. Then we will create a route which will show the defined option from the config file in a form, upon hitting save settings we will update it in the database.
Next, we will be adding a helper function
setting($key, $default = null)
to access the stored settings.
Create Laravel App
Let’s start by creating a brand new application in laravel 5.5.
composer create-project --prefer-dist laravel/laravel db-settings
Once it’s installed we need auth scaffolded, run
php artisan make:auth
to generate scaffolding, before migrating make sure you have configured database. add your credentials in .env file.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=dbsetting DB_USERNAME=root DB_PASSWORD=secret
Now run the
php artisan migrate
it will create the tables for migration and give you auth routes setup. Go ahead and register a new user and login.
Settings model and migration
To store settings in the database we need a table with 3 fields:
name: unique name string used as a key for settings val: value of the setting, it will be a text column type: date type will be used to cast the value to
string
,
integer
or
boolean
etc.
Run
php artisan make:model Setting -mc
to create the migration and controller for same. Edit the settings migration file in database/migrations and add above columns:
public function up() Schema::create('settings', function (Blueprint $table) $table->increments('id'); $table->string('name'); $table->text('val'); $table->char('type', 20)->default('string'); $table->timestamps(); );
That’s it for migration, let’s move on to the settings config file, we will get back to
Setting
model to implement all the functionality later.
Create setting_fields in Config
We have our laravel installation, let’s create a config file
config/setting_fields.php
and add the following array.
return [ 'app' => [ 'title' => 'General', 'desc' => 'All the general settings for application.', 'icon' => 'glyphicon glyphicon-sunglasses', 'elements' => [ [ 'type' => 'text', // input fields type 'data' => 'string', // data type, string, int, boolean 'name' => 'app_name', // unique name for field 'label' => 'App Name', // you know what label it is 'rules' => 'required|min:2|max:50', // validation rule of laravel 'class' => 'w-auto px-2', // any class for input 'value' => 'CoolApp' // default value if you want ] ] ], 'email' => [ 'title' => 'Email', 'desc' => 'Email settings for app', 'icon' => 'glyphicon glyphicon-envelope', 'elements' => [ [ 'type' => 'email', ... ], [ ... ], [ ... ] ] ], ]
If you see the above array we have defined our settings into sections, first top-level element in the array is
app
, and under this, we have its meta information like
title
and
description
, the main part is the elements array, it defines all the input fields needed as form input elements.
Setting Model
This is the backbone of settings, we will add some methods on this model which will give a similar API as laravel config does, for example, you will be able to call
Setting::set('key', 'value')
to set a value in settings and
Setting::get('key')
to get a setting value.
use IlluminateSupportCollection; use IlluminateDatabaseEloquentModel; class Setting extends Model int */ private static function castValue($val, $castTo) switch ($castTo) case 'int': case 'integer': return intval($val); break; case 'bool': case 'boolean': return boolval($val); break; default: return $val; /** * Get all the settings * * @return mixed */ public static function getAllSettings() return self::all();
That’s lots of code, everything is self-explanatory, you can see I am getting all the settings stored in the database, and from
getDefinedSettingFields()
method accessing
setting_fields
config as a collection object, Next am plucking
default value
validation rules
,
casting type
, values for form input field.
Settings Route
We can now move on to setting the route for our settings page, let’s add it
routes/web.php
.
Route::get('/home', 'HomeController@index')->name('home'); Route::group(['middleware' => 'auth'], function () Route::get('/settings', 'SettingController@index')->name('settings'); Route::post('/settings', 'SettingController@store')->name('settings.store'); );
Settings Controller
The Controller will have two methods, index and store. run
php artisan make:controller SettingController
to create it, now open and add this.
public function index() return view('setting.index'); public function store(Request $request) $rules = Setting::getValidationRules(); $data = $this->validate($request, $rules); $validSettings = array_keys($rules); foreach ($data as $key => $val) if (in_array($key, $validSettings)) Setting::add($key, $val, Setting::getDataType($key)); return redirect()->back()->with('status', 'Settings has been saved.');
Index method is pretty simple, it just returns a view, store method handles actual database persistence logic, It gets the validation rules from config by
Setting::getValidationRules()
, then it just loops over the request data and adds it in setting if a setting is defined in config file.
Our
Setting::add($key)
method first checks if setting with the name already exists, if yes it simply updates it otherwise it creates a new setting with given key.
Settings View
Now we can focus on rendering all the fields defined in
config/setting_fields.php
I will use a bootstrap panel for each section, and inside this panels body we will loop over all the fields from
elements
array.
Create a new view
resources/views/setting/index.blade.php
and add following markup:
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> @if (session('status')) <div class="alert alert-success"> session('status') </div> @endif <form method="post" action=" route('settings.store') " class="form-horizontal" role="form"> !! csrf_field() !! @if(count(config('setting_fields', [])) ) @foreach(config('setting_fields') as $section => $fields) <div class="panel panel-info"> <div class="panel-heading"> <i class=" array_get($fields, 'icon', 'glyphicon glyphicon-flash') "></i> $fields['title'] </div> <div class="panel-body"> <p class="text-muted"> $fields['desc'] </p> </div> <div class="panel-body"> <div class="row"> <div class="col-md-7 col-md-offset-2"> @foreach($fields['elements'] as $field) @includeIf('setting.fields.' . $field['type'] ) @endforeach </div> </div> </div> </div> <!-- end panel for $fields['title'] --> @endforeach @endif <div class="row m-b-md"> <div class="col-md-12"> <button class="btn-primary btn"> Save Settings </button> </div> </div> </form> </div> </div> </div> @endsection
Everything is basic HTML in a loop, but notice this part:
@foreach($fields['elements'] as $field) @includeIf('setting.fields.' . $field['type'] ) @endforeach
I have extracted all the fields type in there own partials, it keeps your views clean and maintainable, we could have used if and else handle this rendering but keeping it in separate view partials make it a lot easier to organize. And you can add as many types as you want, you just need to define an element in config with ‘type’ => ‘datepicker’ or anything and create a partial in
resources/views/setting/fields/datepicker.blade.php
to handle all the rendering in this file.
Now lets see how a fileds type view partials looks like:
Input type text view
<div class="form-group $errors->has($field['name']) ? ' has-error' : '' "> <label for=" $field['name'] "> $field['label'] </label> <input type=" $field['type'] " name=" $field['name'] " value=" old($field['name'], setting($field['name'])) " class="form-control array_get( $field, 'class') " id=" $field['name'] " placeholder=" $field['label'] "> @if ($errors->has($field['name'])) <small class="help-block"> $errors->first($field['name']) </small> @endif </div>
And as you know input type
email
,
number
,
date
etc are very similar, just change the type property on the element will give us the input type, for example, to allow input type email we just need to create a partial call
resources/views/setting/fields/email.blade.php
and inside it just add following:
Input Email view
@include('setting.fields._text')
And the same thing is for
number
,
date
etc.
Input Select view
Create another partial inside
fields/select.blade.php
and add following:
<div class="form-group $errors->has($field['name']) ? ' has-error' : '' "> <label for=" $field['name'] "> $field['label'] </label> <select name=" $field['name'] " class="form-control array_get( $field, 'class') " id=" $field['name'] "> @foreach(array_get($field, 'options', []) as $val => $label) <option @if( old($field['name'], setting($field['name'])) == $val ) selected @endif value=" $val "> $label </option> @endforeach </select> @if ($errors->has($field['name'])) <small class="help-block"> $errors->first($field['name']) </small> @endif </div>
As you can see its pretty easy to customize it, for example, if you want to change it to work with another frontend framework like
Bulma
,
Foundation
or
Tailwind CSS
you just need to change the markup and classes in fields partials.
Setting helper function
You might have noticed I have used
setting($key)
helper function to get the stored value for that key in the database. Let’s add this helper function in our composer autoload.
Open the composer.json and in autoload object add files array you want to autoload.
... "psr-4": "App": "app/" , "files": [ "app/Utils/helpers.php" ]
Next, create our helpers file in
app/Utils/helpers.php
and add this function:
if (! function_exists('setting')) function setting($key, $default = null) if (is_null($key)) return new AppSettingSetting(); if (is_array($key)) return AppSettingSetting::set($key[0], $key[1]); $value = AppSettingSetting::get($key); return is_null($value) ? value($default) : $value;
With that we have completed our settings management system, let’s serve the app and see, you should see the following screen with all the settings you defined, before hitting Save Settings you must migrate the database to create settings table.
Make some changes and hit Save Settings, check the database your settings will be saved, now you can access them anywhere in your application by calling
Setting::get('setting_name')
or our helper function
setting('setting_name')
.
But there is a problem, We are listing all settings and calling
setting('setting_name')
multiple times which is making one query to the database for each call 🙁 that’s a lot of queries to get the settings.
Let’s add caching in the Setting model to avoid multiple queries to the database. Modify the
getAllSettings()
method and add some more to handle the cache flushing etc.
/** * Get all the settings * * @return mixed */ public static function getAllSettings() return Cache::rememberForever('settings.all', function() return self::all(); ); /** * Flush the cache */ public static function flushCache() Cache::forget('settings.all'); /** * The "booting" method of the model. * * @return void */ protected static function boot() parent::boot(); static::updated(function () self::flushCache(); ); static::created(function() self::flushCache(); );
We are caching all settings from the database and returning it, then we hooked into model events,
created
,
deleted
and
updated
to flush the cache on any change so our settings will have updated value. It has solved multiple query issue.
I have used key ‘settings.all’, you should pic a unique key prefixed with some model ID for your app if your app offers settings based on user, team etc.
As always I have posted the complete source code for you on GitHub, have fun, implementing settings will be now a piece of cake, just change the definition in the config/setting_fields.php file and your settings page will reflect new fields 😎
Source Code
Related
0 notes
Text
User Authorization in Laravel 5.4 with Spatie Laravel-Permission
What We'll Build
When building an application, we often need to set up an access control list (ACL). An ACL specifies the level of permission granted to a user of an application. For example a user John may have the permission to read and write to a resource while another user Smith may have the permission only to read the resource.
In this tutorial, I will teach you how to add access control to a Laravel app using Laravel-permission package. For this tutorial we will build a simple blog application where users can be assigned different levels of permission. Our user admin page will look like this:
Why Use Laravel-Permission
The Laravel-Permission package is built on top of Laravel's authorization features introduced in the 5.1.1 release. Although there are other packages that claim to offer similar functionalities, none of them have the same level of activity and maintenance as the laravel-permission package.
Development Environment and Installation
You can get Laravel up and running by first downloading the installer
composer global require "laravel/installer"
Then add $HOME/.composer/vendor/bin to your $PATH so the laravel executable can be located by your system. Now you can install the latest stable version of Laravel by running
laravel new
To install the laravel-permission package run
composer require spatie/laravel-permission
Next include the package to our list of service providers, in config/app.php add Spatie\Permission\PermissionServiceProvider::class so our file looks like this
'providers' => [ ... Spatie\Permission\PermissionServiceProvider::class, ];
Next publish the migration file for this package with the command
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
Database Setup and Migrations
Next create the database and update the .env file to include the database information. For example, for this tutorial the database information section of the .env looks like this:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=acl4 DB_USERNAME=root DB_PASSWORD=
To build the tables, run
php artisan migrate
Please note that in Laravel 5.4 the default character set is changed to utf8mb4, therefore if you are running MariaDB or MYSQL version lower than 5.7.7 you may get this error when trying to run migration files
[Illuminate\Database\QueryException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email)) [PDOException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
To fix this error edit the app\Providers\AppServiceProvider.php file, setting the default string length in the boot method
use Illuminate\Support\Facades\Schema; public function boot() { Schema::defaultStringLength(191); }
After that run the migration again. If it works as normal you would find the following tables in your database:
migrations: This keeps track of migration process that have ran
users: This holds the users data of the application
password_resets: Holds token information when users request a new password
permissions: This holds the various permissions needed in the application
roles: This holds the roles in our application
role_has_permission: This is a pivot table that holds relationship information between the permissions table and the role table
user_has_roles: Also a pivot table, holds relationship information between the roles and the users table.
user_has_permissions: Also a pivot table, holds relationship information between the users table and the permissions table.
Publish the configuration file for this package by running
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
The config file allows us to set the location of the Eloquent model of the permission and role class. You can also manually set the table names that should be used to retrieve your roles and permissions. Next we need to add the HasRoles trait to the User model:
use Illuminate\Foundation\Auth\User as Authenticatable; use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; // ... }
Laravel Collective HTML Form builder
Next install Laravel Collective HTML Form builder as this will be useful further on when we are creating our forms:
composer require laravelcollective/html
Then add your new provider to the providers array of config/app.php:
'providers' => [ ... Collective\Html\HtmlServiceProvider::class, ];
Finally, add two class aliases to the aliases array of config/app.php:
'aliases' => [ // ... 'Form' => Collective\Html\FormFacade::class, 'Html' => Collective\Html\HtmlFacade::class, // ... ],
That's all the installation and configuration needed. A role can be created like a regular Eloquent model, like this:
use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; $role = Role::create(['name' => 'writer']); $permission = Permission::create(['name' => 'edit articles']);
You can also get the permissions associated to a user like this:
$permissions = $user->permissions;
And using the pluck method, pluck() you can get the role names associated with a user like this:
$roles = $user->roles()->pluck('name');
Other methods available to us include:
givePermissionTo(): Allows us to give persmission to a user or role
revokePermissionTo(): Revoke permission from a user or role
hasPermissionTo(): Check if a user or role has a given permission
assignRole(): Assigns role to a user
removeRole(): Removes role from a user
hasRole(): Checks if a user has a role
hasAnyRole(Role::all()): Checks if a user has any of a given list of roles
hasAllRoles(Role::all()): Checks if a user has all of a given list of role
The methods assignRole, hasRole, hasAnyRole, hasAllRoles and removeRole can accept a string, a Spatie\Permission\Models\Role-object or an \Illuminate\Support\Collection object. The givePermissionTo and revokePermissionTo methods can accept a string or a Spatie\Permission\Models\Permission object.
Laravel-Permission also allows to use Blade directives to verify if the logged in user has all or any of a given list of roles:
@role('writer') I'm a writer! @else I'm not a writer... @endrole @hasrole('writer') I'm a writer! @else I'm not a writer... @endhasrole @hasanyrole(Role::all()) I have one or more of these roles! @else I have none of these roles... @endhasanyrole @hasallroles(Role::all()) I have all of these roles! @else I don't have all of these roles... @endhasallroles
The Blade directives above depends on the users role. Sometimes we need to check directly in our view if a user has a certain permission. You can do that using Laravel's native @can directive:
@can('Edit Post') I have permission to edit @endcan
Controllers, Authentication and Views
You will need a total of four controllers for this application. Let's use resource controllers, as this automatically adds stub methods for us. Our controllers will be called
PostController
UserController
RoleController
PermissionController
Before working on these controllers let's create our authentication system. With one command Laravel provides a quick way to scaffold all of the routes and views needed for authentication.
php artisan make:auth
After running this command you would notice two new links for user login and registration in the home page.
This command also creates a HomeController (you can delete this as it won't be needed), a resources/views/layouts/app.blade.php file which contains markup that would be shared by all our views and an app/Http/Controllers/Auth directory which contains the controllers for registration and login. Switch into this directory and open the RegisterController.phpfile. Remove the bcrypt function in the create method, so the the method looks like this
protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => $data['password'], ]); }
Instead let's define a mutator in app\User.php which would encrypt all our password fields. In app\User.php add this method:
public function setPasswordAttribute($password) { $this->attributes['password'] = bcrypt($password); }
This would provide the same functionality as before but now you don't need to write the bcrypt function when dealing with the password field in subsequent controllers.
Also in the RegisterController.phpfile. Change the $redirectTo property to:
protected $redirectTo = '/';
Do the same thing in the LoginController.phpfile.
Since the HomeController has been deleted our users are now redirected to the home page which would contain a list of our blog posts.
Next let's edit the resources/views/layouts/app.blade.php file to include: an extra drop-down 'Admin' link to view all users and an errors file which checks if our form produced any error. The 'Admin' link would only be viewed by users with the 'Admin' Role. We would also create a custom styles.css which would have extra styling for our resources/views/posts/index.blade.php view. The styling is just a paragraph in the teaser of our index view, the file should be located in public/css/styles.css
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSRF Token --> <meta name="csrf-token" content=""> <title></title> <!-- Styles --> <link href="http://ift.tt/1uaQUM0" rel="stylesheet"> <link href="http://ift.tt/1uaQUM0" rel="stylesheet"> <link rel="stylesheet" href="http://ift.tt/2cYLUyN; integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Scripts --> <script> window.Laravel = {!! json_encode([ 'csrfToken' => csrf_token(), ]) !!}; </script> <script src="http://ift.tt/2qqGPlI;></script> </head> <body> <div id="app"> <nav class="navbar navbar-default navbar-static-top"> <div class="container"> <div class="navbar-header"> <!-- Collapsed Hamburger --> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse"> <span class="sr-only">Toggle Navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!-- Branding Image --> <a class="navbar-brand" href="http://ift.tt/1uaQUM0"> </a> </div> <div class="collapse navbar-collapse" id="app-navbar-collapse"> <!-- Left Side Of Navbar --> <ul class="nav navbar-nav"> <li><a href="http://ift.tt/1uaQUM0">Home</a></li> @if (!Auth::guest()) <li><a href="http://ift.tt/1uaQUM0">New Article</a></li> @endif </ul> <!-- Right Side Of Navbar --> <ul class="nav navbar-nav navbar-right"> <!-- Authentication Links --> @if (Auth::guest()) <li><a href="http://ift.tt/1uaQUM0">Login</a></li> <li><a href="http://ift.tt/1uaQUM0">Register</a></li> @else <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li> @role('Admin') <a href="#"><i class="fa fa-btn fa-unlock"></i>Admin</a> @endrole <a href="http://ift.tt/1uaQUM0" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> Logout </a> <form id="logout-form" action="" method="POST" style="display: none;"> </form> </li> </ul> </li> @endif </ul> </div> </div> </nav> @if(Session::has('flash_message')) <div class="container"> <div class="alert alert-success"><em> {!! session('flash_message') !!}</em> </div> </div> @endif <div class="row"> <div class="col-md-8 col-md-offset-2"> @include ('errors.list') </div> </div> @yield('content') </div> <!-- Scripts --> <script src=""></script> </body> </html>
The error file is:
@if (count($errors) > 0) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li></li> @endforeach </ul> </div> @endif
and the styles.css file is simply:
p.teaser { text-indent: 30px; }
Post Controller
First, let's create the migration and model files for the PostController
php artisan make:model Post -m
This command generates a migration file in app/database/migrations for generating a new MySQL table named posts in our database and a model file Post.phpin the app directory. Let's edit the migration file to include title and body fields of our post. Add a title and body field so the migration file looks like this:
<?php //database\migrations\xxxx_xx_xx_xxxxxx_create_posts_table.php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->text('body'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } }
After saving the file, run migration again
php artisan migrate
You can now check the database for the post table and columns.
Next make the title and body field of the Post model mass assignable
namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected $fillable = [ 'title', 'body' ]; }
Now let's generate our resource controller.
php artisan make:controller PostController --resource
This will create our controller with all the stub methods needed. Edit this file to look like this
<?php // app/Http/Controllers/PostController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; use Auth; use Session; class PostController extends Controller { public function __construct() { $this->middleware(['auth', 'clearance'])->except('index', 'show'); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $posts = Post::orderby('id', 'desc')->paginate(5); //show only 5 items at a time in descending order return view('posts.index', compact('posts')); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { return view('posts.create'); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { //Validating title and body field $this->validate($request, [ 'title'=>'required|max:100', 'body' =>'required', ]); $title = $request['title']; $body = $request['body']; $post = Post::create($request->only('title', 'body')); //Display a successful message upon save return redirect()->route('posts.index') ->with('flash_message', 'Article, '. $post->title.' created'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { $post = Post::findOrFail($id); //Find post of id = $id return view ('posts.show', compact('post')); } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $post = Post::findOrFail($id); return view('posts.edit', compact('post')); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $this->validate($request, [ 'title'=>'required|max:100', 'body'=>'required', ]); $post = Post::findOrFail($id); $post->title = $request->input('title'); $post->body = $request->input('body'); $post->save(); return redirect()->route('posts.show', $post->id)->with('flash_message', 'Article, '. $post->title.' updated'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $post = Post::findOrFail($id); $post->delete(); return redirect()->route('posts.index') ->with('flash_message', 'Article successfully deleted'); } }
Here the Post class was imported from our model and the Auth class which was generated with the make:auth command earlier. These were imported so that you would be able to make Eloquent queries on the Post table and so as to be able to have access to authentication information of our users. In the constructor two middlewares were called, one is auth which restricts access to the PostController methods to authenticated users the other is a custom middleware is yet to be created. This would be responsible for our Permissions and Roles system. Next, index and show are passed into the except method to allow all users to be able to view posts.
The index() method lists all the available posts. It queries the post table for all posts and passes this information to the view. Paginate() allows us to limit the number of posts in a page, in this case five.
The create() method simply returns the posts/create view which would contain a form for creating new posts. The store() method saves the information input from the posts/create view. The information is first validated and after it is saved, a flash message is passed to the view posts/index.
Our show() method of the PostController allows us to display a single post. This method takes the post id as an argument and passes it to the method Post::find(). The result of the query is then sent to our posts/show view.
The edit() method, similar to the create() method simply returns the posts/edit view which would contain a form for creating editing posts. The update() method takes the information from the posts/edit view and updates the record. The destroy() method let's us delete a post.
Now that you have the PostController you need to set up the routes. Edit your app/routes/web.php file to look like this:
<?php Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/', 'PostController@index')->name('home'); Route::resource('users', 'UserController'); Route::resource('roles', 'RoleController'); Route::resource('permissions', 'PermissionController'); Route::resource('posts', 'PostController');
The / route is the route to our home page, here it was renamed to home The Auth route was generated when you ran the make:auth command. It handles authentication related routes. The other four routes are for resources that would be created later.
Post Views
Only four views are needed for our PostController. Create the files \resources\views\posts\index.blade.php, \resources\views\posts\create.blade.php, \resources\views\posts\show.blade.php, \resources\views\posts\edit.blade.php
Edit the index.blade.phpfile to look like this
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-10 col-md-offset-1"> <div class="panel panel-default"> <div class="panel-heading"><h3>Posts</h3></div> <div class="panel-heading">Page of </div> @foreach ($posts as $post) <div class="panel-body"> <li style="list-style-type:disc"> <a href="http://ift.tt/1uaQUM0"><b></b><br> <p class="teaser"> </p> </a> </li> </div> @endforeach </div> <div class="text-center"> {!! $posts->links() !!} </div> </div> </div> </div> @endsection
Notice that this file extends views\layouts\app.php file, which was generated earlier by the make:auth command.
The create.blade.php file looks like this
@extends('layouts.app') @section('title', '| Create New Post') @section('content') <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1>Create New Post</h1> <hr> <div class="form-group"> <br> <br> </div> </div> </div> @endsection
The show view looks like this:
@extends('layouts.app') @section('title', '| View Post') @section('content') <div class="container"> <h1></h1> <hr> <p class="lead"> </p> <hr> {!! Form::open(['method' => 'DELETE', 'route' => ['posts.destroy', $post->id] ]) !!} <a href="http://ift.tt/1uaQUM0" class="btn btn-primary">Back</a> @can('Edit Post') <a href="http://ift.tt/1uaQUM0" class="btn btn-info" role="button">Edit</a> @endcan @can('Delete Post') {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!} @endcan {!! Form::close() !!} </div> @endsection
Here the can directive checks if a user has the permission to Edit or Delete Posts, if so the Edit and Delete button will be displayed. If the user does not have these permissions, only the Back button would be displayed.
The edit view just displays a edit form that will be used to update records:
@extends('layouts.app') @section('title', '| Edit Post') @section('content') <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1>Edit Post</h1> <hr> <div class="form-group"> <br> <br> </div> </div> </div> @endsection
If you visit the home page you would see this
User Controller
The UserController will handle displaying all users, creating of new users, editing users, assigning roles to users and deleting users. As before generate the controller by running
php artisan make:controller UserController --resource
Then replace the content of this file with:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\User; use Auth; //Importing laravel-permission models use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; //Enables us to output flash messaging use Session; class UserController extends Controller { public function __construct() { $this->middleware(['auth', 'isAdmin']); //isAdmin middleware lets only users with a //specific permission permission to access these resources } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { //Get all users and pass it to the view $users = User::all(); return view('users.index')->with('users', $users); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { //Get all roles and pass it to the view $roles = Role::get(); return view('users.create', ['roles'=>$roles]); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { //Validate name, email and password fields $this->validate($request, [ 'name'=>'required|max:120', 'email'=>'required|email|unique:users', 'password'=>'required|min:6|confirmed' ]); $user = User::create($request->only('email', 'name', 'password')); //Retrieving only the email and password data $roles = $request['roles']; //Retrieving the roles field //Checking if a role was selected if (isset($roles)) { foreach ($roles as $role) { $role_r = Role::where('id', '=', $role)->firstOrFail(); $user->assignRole($role_r); //Assigning role to user } } //Redirect to the users.index view and display message return redirect()->route('users.index') ->with('flash_message', 'User successfully added.'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { return redirect('users'); } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $user = User::findOrFail($id); //Get user with specified id $roles = Role::get(); //Get all roles return view('users.edit', compact('user', 'roles')); //pass user and roles data to view } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $user = User::findOrFail($id); //Get role specified by id //Validate name, email and password fields $this->validate($request, [ 'name'=>'required|max:120', 'email'=>'required|email|unique:users,email,'.$id, 'password'=>'required|min:6|confirmed' ]); $input = $request->only(['name', 'email', 'password']); //Retreive the name, email and password fields $roles = $request['roles']; //Retreive all roles $user->fill($input)->save(); if (isset($roles)) { $user->roles()->sync($roles); //If one or more role is selected associate user to roles } else { $user->roles()->detach(); //If no role is selected remove exisiting role associated to a user } return redirect()->route('users.index') ->with('flash_message', 'User successfully edited.'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { //Find a user with a given id and delete $user = User::findOrFail($id); $user->delete(); return redirect()->route('users.index') ->with('flash_message', 'User successfully deleted.'); } }
Here the User class, the Role class, the Permission class and the Auth class are imported. In the constructor the auth middleware is called to make sure only authenticated users have access to the User resource. A custom middleware isAdmin is also called. This checks if the authenticated user has administrator privileges. This middleware will be created later.
The index() method gets all users from the Users table and passes it to the index view which will display all users in a table. The create() method first gets all the Roles from the Roles table and passes it to the create view. This is so that Roles can be added when creating a User.
The store() method saves the input from the create view, after validating the input, looping through the Roles that was passed in the form and assigning these Roles to the User. The show()method just redirects back to the users page as for this demonstration, we wont need to show each user individually.
The edit() method gets the user corresponding to the id passed, then gets all roles and passes it to the edit view. The update() method validates data from the edit view and saves the updated name and password fields. It gets all roles from the roles table and while looping through them, removes any role assign to the user. It then takes the role data inputted from the form, matches them with the values in the databases and assigns these roles to the user.
The destroy() method allows us to delete a user along with it's corresponding role.
User Views
Three views are needed here: index, create and edit views. The index view would contain a table that lists all our users and their roles.
@extends('layouts.app') @section('title', '| Users') @section('content') <div class="col-lg-10 col-lg-offset-1"> <h1><i class="fa fa-users"></i> User Administration <a href="http://ift.tt/1uaQUM0" class="btn btn-default pull-right">Roles</a> <a href="http://ift.tt/1uaQUM0" class="btn btn-default pull-right">Permissions</a></h1> <hr> <div class="table-responsive"> <table class="table table-bordered table-striped"> <thead> <tr> <th>Name</th> <th>Email</th> <th>Date/Time Added</th> <th>User Roles</th> <th>Operations</th> </tr> </thead> <tbody> @foreach ($users as $user) <tr> <td></td> <td></td> <td></td> <td></td> <td> <a href="http://ift.tt/1uaQUM0" class="btn btn-info pull-left" style="margin-right: 3px;">Edit</a> {!! Form::open(['method' => 'DELETE', 'route' => ['users.destroy', $user->id] ]) !!} {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!} {!! Form::close() !!} </td> </tr> @endforeach </tbody> </table> </div> <a href="http://ift.tt/1uaQUM0" class="btn btn-success">Add User</a> </div> @endsection
The create view is just a form that allows us to create new users and assign roles to them.
@extends('layouts.app') @section('title', '| Add User') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><i class='fa fa-user-plus'></i> Add User</h1> <hr> <div class="form-group"> </div> <div class="form-group"> </div> <div class='form-group'> @foreach ($roles as $role) <br> @endforeach </div> <div class="form-group"> <br> </div> <div class="form-group"> <br> </div> </div> @endsection
The edit view is a form that allows us to edit users and their roles. Using Laravel's form model binding the form is automatically populated with the previous values.
@extends('layouts.app') @section('title', '| Edit User') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><i class='fa fa-user-plus'></i> Edit </h1> <hr> <div class="form-group"> </div> <div class="form-group"> </div> <h5><b>Give Role</b></h5> <div class='form-group'> @foreach ($roles as $role) <br> @endforeach </div> <div class="form-group"> <br> </div> <div class="form-group"> <br> </div> </div> @endsection
Permission Controller
Now let's tackle the PermissionControllerCreate the file and paste the following code:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Auth; //Importing laravel-permission models use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; use Session; class PermissionController extends Controller { public function __construct() { $this->middleware(['auth', 'isAdmin']); //isAdmin middleware lets only users with a //specific permission permission to access these resources } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $permissions = Permission::all(); //Get all permissions return view('permissions.index')->with('permissions', $permissions); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { $roles = Role::get(); //Get all roles return view('permissions.create')->with('roles', $roles); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $this->validate($request, [ 'name'=>'required|max:40', ]); $name = $request['name']; $permission = new Permission(); $permission->name = $name; $roles = $request['roles']; $permission->save(); if (!empty($request['roles'])) { //If one or more role is selected foreach ($roles as $role) { $r = Role::where('id', '=', $role)->firstOrFail(); //Match input role to db record $permission = Permission::where('name', '=', $name)->first(); //Match input //permission to db record $r->givePermissionTo($permission); } } return redirect()->route('permissions.index') ->with('flash_message', 'Permission'. $permission->name.' added!'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { return redirect('permissions'); } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $permission = Permission::findOrFail($id); return view('permissions.edit', compact('permission')); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $permission = Permission::findOrFail($id); $this->validate($request, [ 'name'=>'required|max:40', ]); $input = $request->all(); $permission->fill($input)->save(); return redirect()->route('permissions.index') ->with('flash_message', 'Permission'. $permission->name.' updated!'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $permission = Permission::findOrFail($id); //Make it impossible to delete this specific permission if ($permission->name == "Administer roles & permissions") { return redirect()->route('permissions.index') ->with('flash_message', 'Cannot delete this Permission!'); } $permission->delete(); return redirect()->route('permissions.index') ->with('flash_message', 'Permission deleted!'); } }
In the store() method, we are making it possible for a role to be selected as a permission is created. After validating and saving the permission name field, a check is done if a role was selected if it was, a permission is assigned to the selected role.
Permission View
Three views are needed here as well. The index view would list in a table all the available permissions, the create view is a form which would be used to create a new permission and the edit view is a form that let's us edit existing permission.
@extends('layouts.app') @section('title', '| Permissions') @section('content') <div class="col-lg-10 col-lg-offset-1"> <h1><i class="fa fa-key"></i>Available Permissions <a href="http://ift.tt/1uaQUM0" class="btn btn-default pull-right">Users</a> <a href="http://ift.tt/1uaQUM0" class="btn btn-default pull-right">Roles</a></h1> <hr> <div class="table-responsive"> <table class="table table-bordered table-striped"> <thead> <tr> <th>Permissions</th> <th>Operation</th> </tr> </thead> <tbody> @foreach ($permissions as $permission) <tr> <td></td> <td> <a href="http://ift.tt/1uaQUM0" class="btn btn-info pull-left" style="margin-right: 3px;">Edit</a> {!! Form::open(['method' => 'DELETE', 'route' => ['permissions.destroy', $permission->id] ]) !!} {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!} {!! Form::close() !!} </td> </tr> @endforeach </tbody> </table> </div> <a href="http://ift.tt/1uaQUM0" class="btn btn-success">Add Permission</a> </div> @endsection
The following is the create view
@extends('layouts.app') @section('title', '| Create Permission') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><i class='fa fa-key'></i> Add Permission</h1> <br> <div class="form-group"> </div><br> @if(!$roles->isEmpty()) //If no roles exist yet <h4>Assign Permission to Roles</h4> @foreach ($roles as $role) <br> @endforeach @endif <br> </div> @endsection
And finally the edit view:
@extends('layouts.app') @section('title', '| Edit Permission') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><i class='fa fa-key'></i> Edit </h1> <br> <div class="form-group"> </div> <br> </div> @endsection
Role Controller
The RoleController is quite similar to the UserController. This controller will allow us to create roles and assign one or more permissions to a role. Create the file and paste the following code:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Auth; //Importing laravel-permission models use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; use Session; class RoleController extends Controller { public function __construct() { $this->middleware(['auth', 'isAdmin']);//isAdmin middleware lets only users with a //specific permission permission to access these resources } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $roles = Role::all();//Get all roles return view('roles.index')->with('roles', $roles); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { $permissions = Permission::all();//Get all permissions return view('roles.create', ['permissions'=>$permissions]); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { //Validate name and permissions field $this->validate($request, [ 'name'=>'required|unique:roles|max:10', 'permissions' =>'required', ] ); $name = $request['name']; $role = new Role(); $role->name = $name; $permissions = $request['permissions']; $role->save(); //Looping thru selected permissions foreach ($permissions as $permission) { $p = Permission::where('id', '=', $permission)->firstOrFail(); //Fetch the newly created role and assign permission $role = Role::where('name', '=', $name)->first(); $role->givePermissionTo($p); } return redirect()->route('roles.index') ->with('flash_message', 'Role'. $role->name.' added!'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { return redirect('roles'); } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $role = Role::findOrFail($id); $permissions = Permission::all(); return view('roles.edit', compact('role', 'permissions')); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $role = Role::findOrFail($id);//Get role with the given id //Validate name and permission fields $this->validate($request, [ 'name'=>'required|max:10|unique:roles,name,'.$id, 'permissions' =>'required', ]); $input = $request->except(['permissions']); $permissions = $request['permissions']; $role->fill($input)->save(); $p_all = Permission::all();//Get all permissions foreach ($p_all as $p) { $role->revokePermissionTo($p); //Remove all permissions associated with role } foreach ($permissions as $permission) { $p = Permission::where('id', '=', $permission)->firstOrFail(); //Get corresponding form //permission in db $role->givePermissionTo($p); //Assign permission to role } return redirect()->route('roles.index') ->with('flash_message', 'Role'. $role->name.' updated!'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $role = Role::findOrFail($id); $role->delete(); return redirect()->route('roles.index') ->with('flash_message', 'Role deleted!'); } }
Roles View
Three views are needed here as well. The index view to display available roles and associated permissions, the create view to add a new role and a view to edit an existing role. Create the index.blade.php file and paste the following:
@extends('layouts.app') @section('title', '| Roles') @section('content') <div class="col-lg-10 col-lg-offset-1"> <h1><i class="fa fa-key"></i> Roles <a href="http://ift.tt/1uaQUM0" class="btn btn-default pull-right">Users</a> <a href="http://ift.tt/1uaQUM0" class="btn btn-default pull-right">Permissions</a></h1> <hr> <div class="table-responsive"> <table class="table table-bordered table-striped"> <thead> <tr> <th>Role</th> <th>Permissions</th> <th>Operation</th> </tr> </thead> <tbody> @foreach ($roles as $role) <tr> <td></td> <td></td> <td> <a href="http://ift.tt/1uaQUM0" class="btn btn-info pull-left" style="margin-right: 3px;">Edit</a> {!! Form::open(['method' => 'DELETE', 'route' => ['roles.destroy', $role->id] ]) !!} {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!} {!! Form::close() !!} </td> </tr> @endforeach </tbody> </table> </div> <a href="http://ift.tt/1uaQUM0" class="btn btn-success">Add Role</a> </div> @endsection
For the create view:
@extends('layouts.app') @section('title', '| Add Role') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><i class='fa fa-key'></i> Add Role</h1> <hr> <div class="form-group"> </div> <h5><b>Assign Permissions</b></h5> <div class='form-group'> @foreach ($permissions as $permission) <br> @endforeach </div> </div> @endsection
And for the edit view:
@extends('layouts.app') @section('title', '| Edit Role') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><i class='fa fa-key'></i> Edit Role: </h1> <hr> <div class="form-group"> </div> <h5><b>Assign Permissions</b></h5> @foreach ($permissions as $permission) <br> @endforeach <br> </div> @endsection
Middleware
To restrict access to the roles and permissions page, a middleware was included called isAdmin in our PermissionController and RoleController. This middleware counts how many users are in the Users table, and if there are more than one users, it checks if the current authenticated User has the permission to 'Administer roles & permissions'. To create a permission visit http://localhost:8000/permissions/create. Then go to http://localhost:8000/roles/create to create a role, to which you can now assign the permission you created. For example you can create a permission called 'Administer roles & permissions' and a 'Admin' role to which you would assign this permission. Create the AdminMiddleware in the directory app/Http/Middleware/ and enter the following code:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; use App\User; class AdminMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $user = User::all()->count(); if (!($user == 1)) { if (!Auth::user()->hasPermissionTo('Administer roles & permissions')) //If user does //not have this permission { abort('401'); } } return $next($request); } }
A middleware called clearance was also included in our PostController. This middleware would check if a user has the permissions Administer roles & permissions, Create Post, Edit Post and Delete Post.
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class ClearanceMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if (Auth::user()->hasPermissionTo('Administer roles & permissions')) //If user has this //permission { return $next($request); } if ($request->is('posts/create'))//If user is creating a post { if (!Auth::user()->hasPermissionTo('Create Post')) { abort('401'); } else { return $next($request); } } if ($request->is('posts/*/edit')) //If user is editing a post { if (!Auth::user()->hasPermissionTo('Edit Post')) { abort('401'); } else { return $next($request); } } if ($request->isMethod('Delete')) //If user is deleting a post { if (!Auth::user()->hasPermissionTo('Delete Post')) { abort('401'); } else { return $next($request); } } return $next($request); } }
Add AdminMiddleware::class and ClearanceMiddleware::class to the $routeMiddleware property of /app/Http/kernel.php like this:
protected $routeMiddleware = [ 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'isAdmin' => \App\Http\Middleware\AdminMiddleware::class, 'clearance' => \App\Http\Middleware\ClearanceMiddleware::class, ];
In both middelwares a 401 exception would be thrown if the conditions are not meet. Let's create a custom 401 error page:
@extends('layouts.app') @section('content') <div class='col-lg-4 col-lg-offset-4'> <h1><center>401<br> ACCESS DENIED</center></h1> </div> @endsection
Wrapping Up
First lets create an 'Admin' user and then create the necessary permissions and roles. Click on Register and create a user, then go to http://localhost:8000/permissions and create permissions to Create Post, Edit Post, Delete Post and Administer roles & permissions. After creating these permissions, your permissions page should look like this:
Next, you need to create roles to which you would add the Create, Edit and Delete Permissions. Click on Roles and create these roles:
Admin- A user assigned to this role would have all permissions
Owner- A user assigned to this role would have selected permissions assigned to it by Admin
Finally assign the Role of 'Admin' to the currently logged in User. Click on Users and then Edit. Check the Admin box under Give Role:
After assigning the 'Admin' role to our user, notice that you now have a new Admin link in the drop of the navigation, this links to our users page. Now create a new user and give it the more restrictive role of Owner. If you login as this user and try to visit the User, Role or Permission pages you get this as expected:
The Owner role does not have permission to Administer Roles & Users hence the exception is thrown.
To demonstrate how this works for posts, create a post by clicking on New Article. After creating the post, view the post and you would notice you have along with the Back button, an Edit and Delete button as shown below:
Now if you logout and view the post only the Back button will be available to us. This also works if you have a logged in user who does not have permissions to Edit or Delete Post.
Conclusion
The laravel-permission package makes it relatively easy to build a role and permission system. To recap we have considered installation of the laravel-permission package, laravel-permission blade directives, creating a custom middleware and implementing an access control list in a Laravel application. You can look at the final product on Github and if you have any questions or comments, don’t hesitate to post them below.
via Scotch.io http://ift.tt/2qogmXD
0 notes
Text
[Sprint#2.2-TYB] Sso... My Feature Has Finished
Yang telah saya lakukan:
2017-04-07 (금) Waktu yang telah dialokasikan: 5 jam
Hari ini, dibantu dengan Dzulham, saya mencoba menyelesaikan masalah yang terjadi pada testing di mana UnitPHP mengalami error ketika berjalan. Setelah mencoba-coba mencari sumber permasalahnnya, akhirnya ditemui hal tersebut terjadi ketika pemanggilan fungsi dari library SSO. Penyelesaian masalah untuk ini saat ini masih dengan cara kotor, yaitu dengan tidak memanggil fungsi SSO apabila environment-nya adalah testing.
Setelah masalah test selesai, saya bersemangat untuk melanjutkan penyelesaian fitur saya. Pertama yang saya lakukan adalah mengubah kode yang saya buat sebelumnya menjadi lebih elegan. Salah satu yang saya ubah adalah kode ketika user melakukan pertama kali login dan terdaftar secara otomatis ke database. Dari yang sebelumnya saya mencoba mengambil dari database, ketika tidak ada maka akan insert user baru ke dalam database, kemudian saya ubah menggunakan cara Laravel dengan method:
User::firstOrCreate();
Berikut implementasi lengkapnya:
$user = User::firstOrCreate( ['npm' => $npm], [ 'name' => ucwords(strtolower($name)), 'year' => '20'.substr($npm, 0, 2), 'contact' => 'Email: '.$email.', LINE: ...', 'role' => 1 ] );
Kode tersebut akan melakukan pencarian user dengan NPM yang terdapat pada variabel $npm, kemudian jika tidak ditemukan maka akan meng-insert user dengan NPM tersebut, dan memasukkan atribut-atribut lain yang dimasukkan sebagai array pada parameter kedua dari method firstOrCreate() Laravel.
Kemudian yang saya lakukan berikutnya adalah menambahkan middleware. Middleware adalah mekanisme yang melakukan filtering request HTTP ketika masuk ke dalam aplikasi. Middleware yang saya tambahkan adalah melakukan pengecekan apakah user telah login untuk bisa menggunakan aplikasi TemanLomba ini.
Untuk membuat middleware pada Laravel dapat dilakukan perintah artisan:
php artisan make:middleware CheckLogin
Perintah tersebut akan membuat berkas PHP untuk middleware yang ingin kita buat. Di dalam berkas tersebut, kita kemudian dapat implementasikan logic yang ingin kita buat. Misal, pada yang akan saya buat, yaitu user akan redirect ke landing page apabila mencoba mengakses fitur-fitur lain pada aplikasi TemanLomba. Berikut implementasi saya:
public function handle($request, Closure $next) { // Check if already login if ($request->session()->has('npm')) { return $next($request); // Return to landing page if not logged } else { return redirect('/')->with('error', 'Please login.'); } }
Kemudian masukkan class tersebut ke dalam class \App\Http\Kernel:
protected $routeMiddleware = [ 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'login' => \App\Http\Middleware\CheckLogin::class, ];
Setelah itu berikan middleware tersebut pada route, sebagai contoh, pada route dashboard sebagai berikut:
Route::get('dashboard','DashboardController@index')->middleware('login');
Akhirnya middleware selesai, dan user yang belum login tidak akan bisa masuk ke halaman yang tidak seharusnya bisa dimasuki.
Selanjutnya yang saya lakukan adalah melakukan handling exception. Pada library SSO, terkadang tanpa sebab muncul exception seperti ini:
Agar tidak muncul lagi, maka saya dapat melakukan exception handling dengan menggunakan try catch.
Exception tersebut muncul ketika dilakukan pemanggilan method pada class SSO. Dengan begitu, saya memasukkan semua pemanggilan method SSO pada try dan melakukan catch CAS_Exception (CAS_AuthenticationException adalah subclass dari CAS_Exception) seperti berikut:
try { SSO::authenticate(); ... } catch (CAS_Exception $e) { return redirect('login'); }
Exception ini biasanya hilang ketika halaman login dicoba diakses kembali sehingga untuk menyelesaikannya saya cukup melakukan redirect ke halaman tersebut kembali.
Dengan demikian, saya bisa memastikan bahwa fitur yang saya kerjakan telah selesai.
2017-04-07 (토) Waktu yang telah dialokasikan: 4 jam
Hari ini saya mencoba menyempurnakan fitur saya dengan integrasi frontend. Yang saya kerjakan adalah memberikan warning message kepada user untuk melengkapi profile-nya ketika ia baru pertama kali login (baru terdaftar ke sistem). Untuk melakukannya, ketika redirect, saya cukup melakukan method chaining dengan with() pada method redirect(). with() akan memberikan flash session yang hanya akan ada pada request berikutnya.
return redirect('profile/edit')->with('warning', 'Please complete your profile first before using TemanLomba.');
Setelah itu pada frontend-nya tinggal cetak pesan dalam variabel warning tersebut.
@if (session('warning')) <div class="alert alert-warning alert-dismissable"> <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> {{ session('warning') }} </div> @endif
Kemudian yang saya lakukan berikutnya adalah meng-handle apabila yang login bukan mahasiswa Fasilkom.
Setelah berdiskusi dengan Dzulham, kami memutuskan untuk melempar Error 403 - Forbidden ketika user tersebut mencoba login. Untuk melakukan ini saya perlu membuat frontend yang dituliskan di /resources/views/error/403.blade.php. Kemudian untuk memberikan error tersebut, cukup dengan perintah:
return abort(403, 'You are not a Computer Science student.<br />Click <a href="'.url('logout').'">here</a> to logout from SSO.');
Perintah tersebut akan memberikan error dengan kode 403 dan pesan “You are not a Computer Science student. Click here to logout from SSO.”. Dengan adanya blok baru tersebut, maka saya perlu menambahkan test terlebih dahulu.
Untuk meng-assert suatu error, pada phpunit, tidak dengan method. Hal tersebut dilakukan pada comment sebelum method test-nya. Berikut comment-nya:
/** * Test fungsi doLogin pada LoginController untuk mahasiswa Non-Fasilkom. * Seharusnya akan melemparkan error 403. * * @expectedException \Symfony\Component\HttpKernel\Exception\HttpException * @expectedExceptionMessage You are not a Computer Science student.<br />Click <a href="http://localhost:8000/logout">here</a> to logout from SSO. */
Terdapat dua cara yang dapat dilakukan untuk menangkap error-nya. Yaitu dengan kode atau dengan message.
Dengan kode dituliskan:
@expectedExceptionCode 403
dan dengan message dengan:
@expectedExceptionMessage <the message>
Namun entah mengapa saya tidak bisa dengan kode, akhirnya saya melakuannya dengan message.
Dengan begitu, selesai lah fitur saya.
2017-04-16 (일) Waktu yang telah dialokasikan: 6 jam
Dua minggu belakang saya tidak dapat mengalokasikan seminggu saya selama 18 jam. Hal tersebut karena saya bingung apa yang harus saya kerjakan lagi.
Kemudian pada hari ini kami sekelompok memutuskan untuk melakukan coding bersama.
Terdapat beberapa pekerjaan dari sprint 1 yang ternyata sebenarnya lupa tertuliskan pada backlog. Karena sifat agile yang adaptif terhadap perubahan, maka kami dengan inisiatif melakukan pekerjaan tersebut.
Pekerjaan yang saya lakukan adalah menampilkan skill-skill dari table join user_skill pada halaman profile.
Pada desain database kami, satu user bisa memiliki banyak skill dan satu skill bisa dimiliki oleh banyak user. Dengan begitu, hal tersebut merupakan relasi many-to-many. Dengan menggunakan eloquent dari Laravel dengan mudahnya kita dapat mengambilnya dari database tanpa perlu melakukan perintah join-join lagi.
Untuk relasi many-to-many, dapat ditambahkan belongsToMany() pada model-nya. Saya menambahkan fungsi skills, untuk mengambil semua skill yang dimiliki user, pada model User.
public function skills() { return $this->belongsToMany('App\Skill', 'user_skills', 'user_id', 'skill_id'); }
Fungsi tersebut akan bisa mengembalikan semua skill yang dimiliki user. Untuk method belongsToMany(), terdapat beberapa parameter yang dapat dimasukkan. Parameter pertama adalah model dari skill-nya, parameter kedua menunjukkan nama join table kedua relasi pada database. Parameter ketiga adalah nama foreign key dari user ke join table tersebut. Parameter keempat adalah nama foreign key dari skill ke join table tersebut.
Kemudian untuk mengambil semua skill yang dimiliki, pada controller dapat dilakukan pemanggilan fungsi tersebut lalu di-chain dengan method get().
$user = User::where('npm', $npm)->first(); $user->skills = $user->skills()->get();
Selain itu, kami juga mencoba menggunakan CSS framework lain yaitu Semantic UI. Untuk memasang Semantic UI, dapat diunduh pada semantic-ui.com dan masukkan pada folder public/semantic/dist/.
Pada frontend, tambahkan pada head:
<link href="{{ asset('semantic/dist/semantic.min.css')}}" rel="stylesheet">
dan tambahkan file javascript-nya (biasanya sebelum </body>):
<script src="{{ asset('semantic/dist/semantic.min.js') }}"></script>
Kendala:
Fitur ternyata dapat diselesaikan dengan sangat cepat. Sehingga, ketika telah selesai, saya menjadi bingung harus mengerjakan apa. Hal tersebut membuat alokasi waktu tidak maksimal.
Selain itu, secara teknis sudah lancar.
0 notes
Text
Knap - Advanced PHP Login and User Management
Knap – Advanced PHP Login and User Management
[ad_1]

Knap is an advanced User Management software written in Laravel 5.4 (PHP Framework) that allows the admin to manage users.
The Server Requirement to run the application.
PHP >= 7.1
OpenSSL PHP Extension
PDO PHP Extension
Mbstring PHP Extension
GD PHP Extension
Fileinfo PHP Extension
Demo
Demo: Click Here
Email: [email protected] Password: 123456
Upcoming Features – coming soon
Backup
View On WordPress
#activity log#custom fields#google recaptcha#Laravel#login#Multi-Lingual#permissions#php#registration#roles#secure#sessions management#social auth#system#user management
0 notes
Text
Fitur -- Login using OAuth UI
Halo-halo... Apa kabar semuanya? Post kali ini akan lebih ke teknis nih, semoga penjelasannya cukup jelas yaa... :”)
Jadi sistem yang kami buat ini kan adalah pemira ui (pemilihan raya universitas indonesia) yang artinya pengguna dari sistem ini pun adalah masyarakat ui. Masyarakat ui biasanya mempunyai akun juita. Nah akun juita ini digunakan untuk masuk ke dalam sistem kami.
Berikut tampilan awal ketika ingin login ke dalam sistem kami
Untuk menggunakan OAuth, pertama kamu harus menambahkan kode berikut pada file composer.json yang ada didalam project laravel kamu ya..
"require " : {
...
"prakashdivyy/laravel-oauth2-ui": "*",
...
}
Setelah itu lakukan composer update. Jika sudah kamu harus menambahkan kode berikut ke dalam providers array didalam config/app.php
'providers' => [
...
PrakashDivy\Laravel\OAuth2\UI\UIServiceProvider::class,
..
]
Selanjutnya tambahkan aliases, masih didalam config/app.php
'aliases' => [
...
'UI' => PrakashDivy\Laravel\OAuth2\UI\Facades\UI::class,
..
]
Terakhir untuk setupnya kamu dapat jalankan kode berikut
php artisan vendor:publish
Setelah settingannya selesai maka aku akan menjelaskan contoh penggunaanya pada project kami
sebelum lanjut ke koding terlalu dalam saya akan jelaskan sedikit yaa, setelah kita berhasil login kita akan mendapatkan sebuah token, jika tidak ada token maka kita dinyatakan belum login atau sudah logout.
Nah ini langsung ke kodenya yaa..
Pertama kita bikin controllernya dlu ya, misalkan namanya LoginController.php
<?php
namespace App\Http\Controllers;
use Validator; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; use PrakashDivy\Laravel\OAuth2\UI\Facades\UI; use App\Admin;
class LoginController extends Controller { public function index() { return view('login'); //Menampilkan view form login seperti gambar diatas }
public function store(Request $request) {
$username = $request['username']; $password = $request['password']; $accessToken = UI::getAccessToken('password',[ 'username' => $username, 'password' => $password ]); //Jika berhasil login maka kita mendapat token
$admin=Admin::where('name', 'ilike', $username)->count();
if($admin == 1){ $request->session()->put('token',$accessToken); return redirect()->to('show'); } else { echo "Admin tidak ditemukan"; }
if(!$request->session()->has('token')) { return abort(400, 'Authorization code not available'); }
}
public function logout (Request $request) { if($request->session()->has('token')) {
$request->session()->flush(); //Untuk logout dari sistem maka kita dapat menghapus token yang ada if(!$request->session()->has('token')) { return redirect()->to('/'); }
}
}
}
Setelah controllernya sudah selesai, maka kita dapat membuat routenya
Route::get('/', 'LoginController@index'); Route::post('/login','LoginController@store'); Route::get('/logout', 'LoginController@logout');
Setelah route selesai maka kita dapat membuat viewnya. Untuk viewnya dibebaskan kepada kalian. Intinya hanya membuat form biasa saja seperti dibawah ini
<div class="row center"> <form class="form" role="form" method="POST" action="{{ url('/login') }}"> {{csrf_field()}} <div class="input-field col s12"> <input type="text" class="validate" name="username"> <label for="username">Username</label> </div> <div class="input-field col s12"> <input type="password" class="validate" name="password"> <label for="password">Password</label> </div> <button type="submit" class="btn btn-flat red accent-3 waves-effect white-text right" name="submit">Login</button> </form> </div>
Nah sekian proses implementasi login menggunakan OAuth UI. Semoga bermanfaat :)
0 notes