jwt接口鉴权,访问频率

第一步 安装
composer create-project topthink/think exam

注意:切换到项目目录 cd exam

第二步: 安装多应用
composer require topthink/think-multi-app
第三步 配置域名
    通过phpstudy配置虚拟域名 exam.com
    隐藏入口文件
    开启debug调试模式 复制.example.env 文件为.env 并删除里面的mysql默认配置
第四步 创建api多应用、配置路由
php think build api

开启强制路由、配置首页路由

# api应用下route目录app.php

use think\facade\Route;

# 默认访问的首页
Route::get('/','index/index')->allowCrossDomain();
# 配置登录路由
Route::post('login','login/login')->allowCrossDomain();
第五步 开始开发登录接口

配置登录路由、
要考虑跨域问题、
要考虑异常问题
接口参数验证、独立验证器

报错 当前访问路由未定义或不匹配
解决思路:
路由是否定义
请求方式是否支持
路由访问是否正确

验证用户名密码:
数据库是否配置

接口安全

基于JWTtoken认证

demo:https://gitee.com/thans/jwt-auth/attach_files/306748/download

参考文档地址:https://www.kancloud.cn/sfzl/tp6-jwtauth/2481656
thinkphp的jwt(JSON Web Token)身份验证包。支持Header、Cookie、Param等多种传参方式。包含:验证、验证并且自动刷新等多种中间件。

支持Swoole
环境要求

php >= 7.0
thinkphp ^5.1.10 || ^6.0.0

安装

第一步:

 composer require thans/tp-jwt-auth

第二步:

php think jwt:create

此举将生成jwt.php和.env配置文件。不推荐直接修改jwt.php 同时,env中会随机生成secret。请不要随意更新secret,也请保障secret安全。

使用

对于需要验证的路由或者模块添加中间件:

 thans\jwt\middleware\JWTAuth::class
示例:
use thans\jwt\facade\JWTAuth;

$token = JWTAuth::builder(['uid' => 1]);//参数为用户认证的信息,请自行添加

JWTAuth::auth();//token验证

JWTAuth::refresh();//刷新token,会将旧token加入黑名单

$tokenStr = JWTAuth::token()->get(); //可以获取请求中的完整token字符串

$payload = JWTAuth::auth(); //可验证token, 并获取token中的payload部分
$uid = $payload['uid']->getValue(); //可以继而获取payload里自定义的字段,比如uid

token刷新说明:

token默认有效期为60秒,如果需要修改请修改env文件。 refresh_ttl为刷新token有效期参数,单位为分钟。默认有效期14天。 token过期后,旧token将会被加入黑名单。 如果需要自动刷新,请使用中间件 thans\jwt\middleware\JWTAuthAndRefresh::class, 自动刷新后会通过header返回,请保存好。(注意,此中间件过期后第一次访问正常,第二次进入黑名单。)

token传参方式如下:

可通过jwt.php配置文件内token_mode参数来调整参数接收方式及优先级 token_mode默认值为[‘header’, ‘cookie’, ‘param’];

在某些前后端分离的情况下可选择取消cookie接收方式来避免token冲突

  • 将token加入到url中作为参数。键名为token
  • 将token加入到cookie。键名为token
  • 将token加入header,如下:Authorization:bearer token值

以上三种方式,任选其一即可。推荐加入header中。
其他操作

  • 拉黑Token JWTAuth::invalidate($token);
  • 查询Token是否黑名单 JWTAuth::validate($token);

常见问题
⚠️:php中接收不到HTTP_AUTHORAZATION字段信息、解决办法
修改public/.htaccess文件,通过apache重写,处理HTTP请求中的Authorization字段

    RewriteCond  %{HTTP:Authorization} ^(.+)$
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

使用RSA256方式的时候,请使用文本形式。
参考文档:https://github.com/tymondesigns/jwt-auth

接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看:

Token授权机制:用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID),并将Token-UserId以键值对的形式存放在缓存服务器中。服务端接收到请求后进行Token验证,如果Token不存在,说明请求无效。Token是客户端访问服务端的凭证。

时间戳超时机制:用户每次请求都带上当前时间的时间戳timestamp,服务端接收到timestamp后跟当前时间进行比对,如果时间差大于一定时间(比如5分钟),则认为该请求失效。时间戳超时机制是防御DOS攻击的有效手段。

签名机制:将 Token 和 时间戳 加上其他请求参数再用MD5或SHA-1算法(可根据情况加点盐)加密,加密后的数据就是本次请求的签名sign,服务端接收到请求后以同样的算法得到签名,并跟当前的签名进行比对,如果不一样,说明参数被更改过,直接返回错误标识。签名机制保证了数据不会被篡改。

拒绝重复调用(非必须):客户端第一次访问时,将签名sign存放到缓存服务器中,超时时间设定为跟时间戳的超时时间一致,二者时间一致可以保证无论在timestamp限定时间内还是外 URL都只能访问一次。如果有人使用同一个URL再次访问,如果发现缓存服务器中已经存在了本次签名,则拒绝服务。如果在缓存中的签名失效的情况下,有人使用同一个URL再次访问,则会被时间戳超时机制拦截。这就是为什么要求时间戳的超时时间要设定为跟时间戳的超时时间一致。拒绝重复调用机制确保URL被别人截获了也无法使用(如抓取数据)。

整个流程如下:

1、客户端通过用户名密码登录服务器并获取Token

2、客户端生成时间戳timestamp,并将timestamp作为其中一个参数

3、客户端将所有的参数,包括Token和timestamp按照自己的算法进行排序加密得到签名sign

4、将token、timestamp和sign作为请求时必须携带的参数加在每个请求的URL后边(http://url/request?token=123×tamp=123&sign=123123123)

5、服务端写一个过滤器对token、timestamp和sign进行验证,只有在token有效、timestamp未超时、缓存服务器中不存在sign三种情况同时满足,本次请求才有效

在以上三中机制的保护下,

如果有人劫持了请求,并对请求中的参数进行了修改,签名就无法通过;

如果有人使用已经劫持的URL进行DOS攻击,服务器则会因为缓存服务器中已经存在签名或时间戳超时而拒绝服务,所以DOS攻击也是不可能的;

如果签名算法和用户名密码都暴露了,那齐天大圣来了估计也不好使吧。。。。

最后说一句,所有的安全措施都用上的话有时候难免太过复杂,在实际项目中需要根据自身情况作出裁剪,比如可以只使用签名机制就可以保证信息不会被篡改,或者定向提供服务的时候只用Token机制就可以了。如何裁剪,全看项目实际情况和对接口安全性的要求

接口限流

接口限流:限制接口的访问频率

限流,顾名思义,就是限制对 API 的调用频率。每一次 API 调用,都要花费服务器的资源,因此很多 API 不会对用户无限次地开放,请求达到某个次数后就不再允许访问了,或者一段时间内,最多只允许访问 API 指定次数。

目前,我们的接口是没有任何限流措施的,只要用户调用接口,服务器就会处理并返回数据。为了防止接口被恶意用户刷爆,我们来给接口限流

实战

请尝试:
ThinkPHP6 接口频繁访问限制

作用

通过本中间件可限定用户在一段时间内的访问次数,可用于保护接口防爬防爆破的目的。
接口频率限制
composer require topthink/think-throttle
注:限制接口访问频率限制,不是用户,也不是ip
命令,安装插件


composer require topthink/think-throttle

在应用route目录下的app.php内

use think\middleware\Throttle;

示例:

Route::group(function (){
    Route:resourece('goods',"Goods");
})->middleware(Throttle::class,['visit_rate'=>'3/m',]);

使用:

 

 


配置文件:

总结,三步走:1、命令安装 2、app.php用一下对应的类 3、将示例中间件,放到路由后面,大功告成!

posted @ 2022-02-08 20:29  南瓜不能吃  阅读(328)  评论(0)    收藏  举报