HTTP Routing
1. Basic route
All application routes are defined in App\Providers\RouteServiceProvider
Class loaded app/Http/routes.php
File. The most basic Laravel route receives a URI and a closure:
Route::get('foo', function () { return 'Hello World'; }); Route::post('foo', function () { // });
By default, routes.php
The file contains a single route and a routing group. All routes contained in this routing group use middleware groups web
This middleware group provides session status and CSRF protection functions for routing. Generally, we will define all routes in this routing group.
Effective routing method
We can register a route to respond to any HTTP request:
Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); Route::patch($uri, $callback); Route::delete($uri, $callback); Route::options($uri, $callback);
Sometimes you need to register a route to respond to multiple HTTP requests - this can be done through match
Method. Or, you can even use any
Method registers a route to respond to all HTTP requests:
Route::match(['get', 'post'], '/', function () { // }); Route::any('foo', function () { // });
2. Routing parameters
Required parameter
Sometimes we need to capture URI fragments in the route. For example, to capture a user ID from a URL, you need to define routing parameters in the following way:
Route::get('user/{id}', function ($id) { return 'User '.$id; });
You can define multiple route parameters in the route as needed:
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { // });
Route parameters are always wrapped in curly braces. These parameters will be passed to the route closure when the route is executed.
Note: Route parameters cannot include -
Character, can be used if necessary _
replace.
Optional parameters
Sometimes you may need to specify optional routing parameters. This can be done by adding a ?
Mark. In this case, you need to specify default values for the corresponding variables:
Route::get('user/{name?}', function ($name = null) { return $name; }); Route::get('user/{name?}', function ($name = 'John') { return $name; });
Regular constraint
You can use the where
Method to constrain the format of routing parameters. where
Method receives a parameter name and a regular expression to define how the parameter is constrained:
Route::get('user/{name}', function ($name) { // })->where('name', '[A-Za-z]+'); Route::get('user/{id}', function ($id) { // })->where('id', '[0-9]+'); Route::get('user/{id}/{name}', function ($id, $name) { // })->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
Global constraints
If you want the routing parameters to be constrained by a given regular expression in the global scope, you can use pattern
method. stay RouteServiceProvider
Class boot
Define the constraint mode in the method:
/** *Define routing model binding, mode filter, etc * * @param \Illuminate\Routing\Router $router * @return void * @translator https://xueyuanjun.com */ public function boot(Router $router){ $router->pattern('id', '[0-9]+'); parent::boot($router); }
Once the mode is defined, it will be automatically applied to all routes containing the parameter name:
Route :: get ( 'user/{id}' , function ( $id ) {
} ) ;
3. Named Routes
Named routes facilitate the generation of URLs or redirects. The implementation is also very simple. Use array keys when defining routes as
Specify route name:
Route::get('user/profile', ['as' => 'profile', function () { // }]);
In addition, you can specify a routing name for controller actions:
Route::get('user/profile', [ 'as' => 'profile', 'uses' => ' UserController@showProfile ' ]);
In addition to specifying the route name in the route array definition, you can also use the name
Method chain:
Route::get('user/profile', ' UserController@showProfile ')->name('profile');
Routing group&named route
If you are using a routing group, you can specify it in the attribute array of the routing group as
Keyword to set a common routing name prefix for routes in the group:
Route::group(['as' => 'admin::'], function () { Route::get('dashboard', ['as' => 'dashboard', function () { //The route is named "admin:: dashboard" }]); });
Generate URLs for named routes
If you name a given route, you can use the route
The function generates the corresponding URL for the named route:
$url = route('profile'); $redirect = redirect()->route('profile');
If the named route defines a parameter, it can be passed as the second parameter to route
Function. The given route parameters will be automatically inserted into the URL:
Route::get('user/{id}/profile', ['as' => 'profile', function ($id) { // }]); $url = route('profile', ['id' => 1]);
4. Routing group
Routing groups allow us to share routing attributes, such as middleware and namespace, among multiple routes, so that we do not have to define attributes for each route separately. The shared attribute is passed as the first parameter to the Route::group
method.
Next, we will demonstrate routing groups through several simple application examples.
middleware
To assign middleware to all routes defined in the routing group, you can use it in the group attribute array middleware
。 Middleware will be executed in the order defined in the array:
Route::group(['middleware' => 'auth'], function () { Route::get('/', function () { //Use Auth middleware }); Route::get('user/profile', function () { //Use Auth middleware }); });
Namespace
Another common example is that routing groups assign the same PHP namespace to multiple controllers under it, which can be used in the group attribute array namespace
To specify the common namespace of all controllers in the group:
Route::group(['namespace' => 'Admin'], function(){ //The controller is under the "App Http Controllers Admin" namespace Route::group(['namespace' => 'User'], function(){ //The controller is under the namespace "App Http Controllers Admin User" }); });
By default, RouteServiceProvider
introduce routes.php
And specify the default namespace of all controller classes under it App\Http\Controllers
Therefore, we only need to specify the namespace when defining App\Http\Controllers
The following part is enough.
Subdomain routing
The routing group can also be used for the routing wildcard of the sub domain name. The sub domain name can be assigned to the routing parameters like the URI, which allows capturing the part of the sub domain name for routing or controller. The sub domain name can be used for routing or controller through the domain
To specify:
Route::group(['domain' => '{account}.myapp.com'], function () { Route::get('user/{id}', function ($account, $id) { // }); });
Routing prefix
group properties prefix
It can be used to add a given URI prefix for each route in the group. For example, you can add all route URIs admin
Prefix:
Route::group(['prefix' => 'admin'], function () { Route::get('users', function () { //Match "/admin/users" URL }); });
You can also use prefix
Parameters Specify public routing parameters for routing groups:
Route::group(['prefix' => 'accounts/{account_id}'], function () { Route::get('detail', function ($account_id) { //Match accounts/{account_id}/detail URL }); });
5. CSRF attack
brief introduction
Cross site request forgery is a malicious vulnerability that exploits credit websites by masquerading the requests of authorized users. Laravel makes it easy to prevent applications from being attacked by cross site request forgery.
Larvel automatically generates a CSRF "token" for each valid user session managed by the application. The token is used to verify whether the authorized user and the initiator are the same person. To generate a hidden input field containing a CSRF token, you can use the help function csrf_field
To achieve:
<? php echo csrf_field(); ?>
auxiliary function csrf_field
The following HTML will be generated:
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?> ">
Of course, you can also use the methods provided by the Blade template engine:
{!! csrf_field() !!}
You don't need to write your own code to verify the CSRF token requested by POST, PUT or DELETE, because Larvel has its own HTTP middleware VerifyCsrfToken
Will do this for us: token
Value and stored in Session token
Make comparison to verify.
Exclude specified URL from CSRF protection
Sometimes we need to exclude some URLs from CSRF protection. For example, if you use Stripe to process payment and use their webhook system, then you need to exclude webhook processor routing from Laravel's CSRF protection.
To achieve this, you need to VerifyCsrfToken
Add the URL to be excluded to $except
Properties:
<? php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; class VerifyCsrfToken extends BaseVerifier { /** *URLs excluded from CSRF validation * * @var array */ protected $except = [ 'stripe/*', ]; }
X-CSRF-Token
In addition to verifying the CSRF token as a POST parameter, you can also set the X-CSRF-Token
The request header is used for verification, VerifyCsrfToken
Middleware will check X-CSRF-TOKEN
In the request header, first create a meta tag and save the token to the meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then add the token to all request headers in the js library (such as jQuery), which provides a simple and convenient way for AJAX based applications to avoid CSRF attacks:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
X-XSRF-Token
Laravel also saved the CSRF token to a file named XSRF-TOKEN
In the cookie, you can use the cookie value to set X-XSRF-TOKEN
Request header. Some JavaScript frameworks, such as Angular, will automatically set this value for you. Basically, you don't need to set this value manually.
6. Routing model binding
Larave routing model binding provides convenience for injecting class instances to routes. For example, you can inject the entire User class instance matching the given ID into routes instead of directly injecting user IDs. Implicit binding
Laravel will automatically resolve Eloquent model type declarations defined in route or controller actions (variable names match route fragments), such as:
Route::get('api/users/{user}', function (App\User $user) { return $user->email; });
In this example, because the type declares the Eloquent model App\User
, corresponding variable name $user
Will match the {user}
In this way, Larvel will automatically inject the user model instance corresponding to the ID passed in the request URI.
If the corresponding model instance cannot be found in the database, an HTTP 404 response will be automatically generated.
Custom Key Name
If you want to use other fields in the data table for implicit model binding, you can override the getRouteKeyName
method:
/** * Get the route key for the model. * * @return string */ public function getRouteKeyName() { return 'slug'; }
Explicit binding
To register an explicit binding, you need to use the model
Method to specify a binding class for the given parameter. belong RouteServiceProvider::boot
Define model binding in method:
Bind parameters to model
public function boot(Router $router) { parent::boot($router); $router->model('user', 'App\User'); }
Next, define a containing {user}
Route of parameters:
$router->get('profile/{user}', function(App\User $user) { // });
Because we have already bound {user}
Parameters to App\User
Model, the User instance will be injected into the route. Therefore, if the request URL is profile/1
A User instance with user ID 1 will be injected.
If the matched model instance does not exist in the database, an HTTP 404 response will be automatically generated and returned.
Custom parsing logic
If you want to use custom parsing logic, you need to use Route::bind
Method, passing to bind
The closure of the method will get the value in the URI request parameter and return the class instance you want to inject in the route:
$router->bind('user', function($value) { return App\User::where('name', $value)->first(); });
Customize Not Found
If you want to specify your own "Not Found" behavior, pass the closure encapsulating this behavior as the third parameter to model
method:
$router->model('user', 'App\User', function() { throw new NotFoundHttpException; });
7. Form method forgery
HTML forms do not support PUT, PATCH or DELETE request methods. Therefore, when PUT, PATCH or DELETE routes, you need to add a hidden _method
Field to the form, and its value is used as the HTTP request method of the form:
<form action="/foo/bar" method="POST"> <input type="hidden" name="_method" value="PUT"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> </form>
You can also use auxiliary functions method_field
To achieve this goal:
<? php echo method_field('PUT'); ?>
Of course, it also supports the Blade template engine:
{{ method_field('PUT') }}