Laravel学习笔记基础系列--(八)Laravel CSRF数据保护
作者:温新
时间:2021-06-25
Laravel中CSRF保护
CSRF即跨站请求伪造。简单地说,CSRF就是伪装授权用户来发起恶意攻击。
CSRF带来的危害:伪装授权用户发送邮件、发送消息、盗取账号等。
Laravel表单中防止CSRF
Laravel中所有请求方式为PUT
、POST
、DELETE
的路由所对应的表单都需要使用CSRF保护。Laravel视图中通过@csrf
指令生成包含CSRF令牌的隐藏输入字段。
@csrf生成隐藏字段后,web
中间件组VerifyCsrfToekn
中间件会验证请求输入的toekn
值和session
中存储的token
是否一致若不一致,则抛出异常。
下面在demo/index.blade.php
中添加一form表单,并提交。
路由文件:route.php
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 表单界面</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'demo'</span>, <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'DemoController@index'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 添加数据</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">post</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'store'</span>,<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'DemoController@store'</span>)<span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">name</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'store'</span>);</span>
控制器文件:DemoController.php
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">namespace</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">App\Http\Controllers</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Http\Request</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Support\Facades\View</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">DemoController</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">extends</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Controller</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">index</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">view</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'demo.index'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">store</span>(<span style="box-sizing: border-box;color: rgb(0, 0, 0)">Request</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$request</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">dd</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$request</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">all</span>());</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>
视图文件:demo/index.blade.php
<span style="box-sizing: border-box;padding-right: 0.1px"><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)"><</span><span style="box-sizing: border-box;color: rgb(17, 119, 0)">form</span> <span style="box-sizing: border-box;color: rgb(0, 0, 204)">action</span>=<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"{{ route('store') }}"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 204)">method</span>=<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"post"</span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> 用户名:<span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)"><</span><span style="box-sizing: border-box;color: rgb(17, 119, 0)">input</span> <span style="box-sizing: border-box;color: rgb(0, 0, 204)">type</span>=<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"text"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 204)">name</span>=<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"username"</span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)"><</span><span style="box-sizing: border-box;color: rgb(17, 119, 0)">input</span> <span style="box-sizing: border-box;color: rgb(0, 0, 204)">type</span>=<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"submit"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 204)">value</span>=<span style="box-sizing: border-box;color: rgb(170, 17, 17)">"提交"</span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)"></</span><span style="box-sizing: border-box;color: rgb(17, 119, 0)">form</span><span class="cm-tag cm-bracket" style="box-sizing: border-box;color: rgb(17, 119, 0)">></span></span>
现在访问demo
路由,会发现报了419
错误,419错误就是因为没有添加csrf验证保护。现在来为表单添加csrf
保护,然后在提交,就会打印出来提交的数据。
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">form</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">action</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"{{ route('store') }}"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">method</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"post"</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">@csrf</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">用户名:</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">input</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">type</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"text"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">name</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"username"</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">input</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">type</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"submit"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">value</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"提交"</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"></</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">form</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span>
指定路由不做CSRF验证
put、post、delete
的每一个表单请求都需要使用csrf
验证。如有些并不需要使用验证的路由该怎么办?此时可以在middleware/VerifyCsrfToken.php
中间件中的except
属性中添加不需要验证的路由。
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">form</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">action</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"{{ route('store') }}"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">method</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"post"</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">用户名:</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">input</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">type</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"text"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">name</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"username"</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(152, 26, 26)"><</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">input</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">type</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"submit"</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">value</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(170, 17, 17)">"提交"</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"></</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">form</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">></span></span>
排序指定路由的csrf验证,这样又可以提交数据到store
方法了。
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// middleware/VerifyCsrfToken.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">protected</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$except</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> [</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">'store'</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">]</span>
我是温新
每天进步一点点,就一点点
请登录后再评论