App types cannot be changed. If your app needs products, permissions, or features that are unavailable to its current type you must create a new app with a different type instead.
We recommend this setup to be done by someone with an admin role in the Business Manager containing your WhatsApp Business Accounts. This avoids permission errors.
Register a Facebook app on the Facebook Developers website using your personal profile (don’t worry, the app will belong to the Business Manager in the end). Your app type needs to be Business or None to use the WhatsApp Business Management API. Find more information on App Types in the App Development documentation.
Find your app ID. Go to developers.facebook.com/apps, locate the app you have registered, and click on the app. A new screen opens up. Copy the App ID displayed on top of the page:
Now go to https://developers.facebook.com/apps/{app-id}/settings/advanced to import the app into your Business Manager —replace {app-id} with the ID you got in Step 2. The Business Manager you use should contain your WhatsApp Business Accounts.
Check for additional instructions in the app configuration, especially those related to GDPR that might apply to your specific case.
For more information about registering as a developer, creating your app, app roles, app modes, please see the App Development documentation.
App Review
When you initially register your app it will be set to Development mode. Apps in Development mode are automatically approved for all login permissions, features, and product-specific features for testing purposes. However, these permissions are limited —the app can only use those permissions to access data of users with roles in your app, like admins and developers.
In order to switch your Facebook app from Development mode to Live mode, it must go through App Review. If you want higher rate limits or would like to access a WhatsApp Business Account not in your Business Manager, you need to go through App Review.
Implementing the API
To make API calls to this API’s endpoints, you will need to do the following:
Acquire an access token through a System User or Facebook Login.
Be able to make API calls using the tool of your choice.
1. Acquire an Access Token Using a System User or Facebook Login
1.1 Deciding how to set up your system
Both Graph API and Marketing API calls require an access token to be passed as a parameter in each API call. This token can be acquired multiple ways, the following being the most common:
Create a System User in your Business Manager and acquire a non-expiring token to be used for backend system integrations. This works for cases such as “a system from company X generates a weekly report on message volume from a certain WhatsApp Business Account without human intervention”.
Use Facebook Login to acquire a user access token and request specific permissions. This is recommended when actions will be performed on behalf of a user, for example, “user X creates a new message template using a tool built by company Y”.
At current time, these APIs are available only to selected Meta partners, if you are one of their Partners you can request those permissions from the key account manager, you are communicating with.
WhatsApp Business App
WhatsApp Business is free to download and was built with the small business owner in mind. The app makes it easy to personally connect with your customers, highlight your products and services, and answer their questions throughout their shopping experience. Create a catalog to showcase your products and services and use special tools to automate, sort and quickly respond to messages.
WhatsApp can also help medium and large businesses provide customer support and deliver important notifications to customers.
Redirect users to check_redirect_to_app.php. check_redirect_to_app.php will try to redirect to MyCustomScheme://MyCustomHost automatically. In case it will not find such a app, it will coninue to show check_redirect_to_app.php content.
You can use Middleware to restrict access to public. You can simply generate token and pass it into headers, or use basic authentication with username and password and check it in your middleware. For that purpose you can use Laravel Airlock.
Is Laravel API secure? Laravel Passport is an OAuth 2.0 server implementation for API authentication using Laravel. Since tokens are generally used in API authentication, Laravel Passport provides an easy and secure way to implement token authorization on an OAuth 2.0 server.
Options: -h, –help Display help for the given command. When no command is given display help for the list command -q, –quiet Do not output any message -V, –version Display this application version –ansi|–no-ansi Force (or disable –no-ansi) ANSI output -n, –no-interaction Do not ask any interactive question –env[=ENV] The environment the command should run under -v|vv|vvv, –verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands: clear-compiled Remove the compiled class file db Start a new database CLI session down Put the application into maintenance / demo mode env Display the current framework environment help Display help for a command inspire Display an inspiring quote list List commands migrate Run the database migrations optimize Cache the framework bootstrap files serve Serve the application on the PHP development server test Run the application tests tinker Interact with your application up Bring the application out of maintenance mode auth auth:clear-resets Flush expired password reset tokens cache cache:clear Flush the application cache cache:forget Remove an item from the cache cache:table Create a migration for the cache database table config config:cache Create a cache file for faster configuration loading config:clear Remove the configuration cache file db db:seed Seed the database with records db:wipe Drop all tables, views, and types event event:cache Discover and cache the application’s events and listeners event:clear Clear all cached events and listeners event:generate Generate the missing events and listeners based on registration event:list List the application’s events and listeners key key:generate Set the application key make make:cast Create a new custom Eloquent cast class make:channel Create a new channel class make:command Create a new Artisan command make:component Create a new view component class make:controller Create a new controller class make:event Create a new event class make:exception Create a new custom exception class make:factory Create a new model factory make:job Create a new job class make:listener Create a new event listener class make:mail Create a new email class make:middleware Create a new middleware class make:migration Create a new migration file make:model Create a new Eloquent model class make:notification Create a new notification class make:observer Create a new observer class make:policy Create a new policy class make:provider Create a new service provider class make:request Create a new form request class make:resource Create a new resource make:rule Create a new validation rule make:seeder Create a new seeder class make:test Create a new test class migrate migrate:fresh Drop all tables and re-run all migrations migrate:install Create the migration repository migrate:refresh Reset and re-run all migrations migrate:reset Rollback all database migrations migrate:rollback Rollback the last database migration migrate:status Show the status of each migration model model:prune Prune models that are no longer needed notifications notifications:table Create a migration for the notifications table optimize optimize:clear Remove the cached bootstrap files package package:discover Rebuild the cached package manifest passport passport:client Create a client for issuing access tokens passport:hash Hash all of the existing secrets in the clients table passport:install Run the commands necessary to prepare Passport for use passport:keys Create the encryption keys for API authentication passport:purge Purge revoked and / or expired tokens and authentication codes permission permission:cache-reset Reset the permission cache permission:create-permission Create a permission permission:create-role Create a role permission:setup-teams Setup the teams feature by generating the associated migration. permission:show Show a table of roles and permissions per guard queue queue:batches-table Create a migration for the batches database table queue:clear Delete all of the jobs from the specified queue queue:failed List all of the failed queue jobs queue:failed-table Create a migration for the failed queue jobs database table queue:flush Flush all of the failed queue jobs queue:forget Delete a failed queue job queue:listen Listen to a given queue queue:monitor Monitor the size of the specified queues queue:prune-batches Prune stale entries from the batches database queue:prune-failed Prune stale entries from the failed jobs table queue:restart Restart queue worker daemons after their current job queue:retry Retry a failed queue job queue:retry-batch Retry the failed jobs for a batch queue:table Create a migration for the queue jobs database table queue:work Start processing jobs on the queue as a daemon route route:cache Create a route cache file for faster route registration route:clear Remove the route cache file route:list List all registered routes sail sail:install Install Laravel Sail’s default Docker Compose file sail:publish Publish the Laravel Sail Docker files schedule schedule:list List the scheduled commands schedule:run Run the scheduled commands schedule:test Run a scheduled command schedule:work Start the schedule worker schema schema:dump Dump the given database schema session session:table Create a migration for the session database table storage storage:link Create the symbolic links configured for the application stub stub:publish Publish all stubs that are available for customization vendor vendor:publish Publish any publishable assets from vendor packages view view:cache Compile all of the application’s Blade templates view:clear Clear all compiled view files
# 1. Entry: Minute when the process will be started [0-60]
# 2. Entry: Hour when the process will be started [0-23]
# 3. Entry: Day of the month when the process will be started [1-28/29/30/31]
# 4. Entry: Month of the year when the process will be started [1-12]
# 5. Entry: Weekday when the process will be started [0-6] [0 is Sunday]
#
# all x min = */x
So according to this your 5 8 * * 0 would run 8:05 every Sunday.
Position 1 for minutes, allowed values are 1-60
position 2 for hours, allowed values are 1-24
position 3 for day of month ,allowed values are 1-31
position 4 for month ,allowed values are 1-12
position 5 for day of week ,allowed values are 1-7 or and the day starts at Monday.
crontab -e for edit or add cron/scheduled job
crontab -l for show list
<?php
namespace App\Http\Middleware;
use Closure;
class VerifyAPIAccess
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (
!(App::environment('local'))
&& (
!$request->header('access-token')
|| $request->header('access-token') !== env('APP_API_TOKEN')
)
) {
return response()->json(['Message' => 'You do not access to this api.'], 403);
}
return $next($request);
}
}
and then added to my route
Route::group([
'middleware' => [
VerifyAPIAccess::class,
'throttle:60,1'
]
], function () {
// list some routes
});
you could also restrict access by adding throttling which would stop someone from hammering your API, with token or not.
There are probably many approaches. A simple but effective one would be sessions. You can save the user in a session. This way you can also count his Api accesses. As soon as they are larger than allowed, you can block their requests. You also write the block in the session. But pay attention to the session duration. It must be long enough.
But the user with bad intentions can get a new session. To avoid this, you can also put his IP on an internal blacklist for a day.
Note: But an open api is always a point of attack.
Things tried:
Using passport to protect my routes and then use passport’s CreateFreshApiToken middleware. Protection works fine, unauthorized users are not able to access the routes, however I don’t get laravel_token in my cookies and therefore I can’t get access to that route if I’m not logged in.
Use passport’s client credentials grant access. Works fine and the way I want it to work but doesn’t really make sense because if I hardcode the client_secret – anyone can access it and then use it to access protected routes. If I make a proxy-like solution, to call a controller method, which would issue a valid token and thus not exposing client_secret to front-end but then anyone could just call that route which issues the token and it would be pointless once again.
You cannot stop people from trying to access of publicly visible API. You need to secure the API and only respond to those with the proper access privileges.
I stumbled upon the same problem today and did some debugging. When registering the /login route, Fortify applies the Illuminate\Routing\Middleware\ThrottleRequests:login middleware to it. This means, for every request to that route, the ThrottleRequests middleware will call the RateLimiter instance for that specified key. Apparently, Fortify doesn’t register a RateLimiter for the login key.
Due to the missing key in the $limiters property of the RateLimiter instance, the ThrottleRequests middleware uses its default fallback, which doesn’t handle the edge case “there SHOULD be a rate limiter for that key, but there isn’t.” really well. The $maxAttempts variable is set to 0 and will result in flaky rate limiting behaviour.
I feel like this is a bug in Fortify, because rate limiting is also happening in the \Laravel\Fortify\Actions\EnsureLoginIsNotThrottled action, which is invoked in the \Laravel\Fortify\Http\Controllers\AuthenticatedSessionController controller. I didn’t check this on a fresh Laravel installation, though, so I don’t want to jump to conclusions here.
Anyway, long story short: As a workaround, you can simply register a rate limiter for the “login” key in some of your providers, e. g. AppServiceProvider or AuthServiceProvider:
public function boot()
{
RateLimiter::for("login", function () {
Limit::perMinute(5);
});
}
Edit: I just realized that the rate limiter for the “login” key is indeed provided by Fortify within the FortifyServiceProvider class. If you happen to have a problem similar to the one discussed above, make sure that you added the FortifyServiceProvider class to your providers array in the config/app.php.