L03 遇到的知识记录(一)

1. dingo/api 安装的问题

原因: dingo/api 依赖的 dingo/blueprintphpunit 都依赖了 phpdocumentor/reflection-docblock,但是以来的版本不同,导致出现了冲突。
解决方法:因为 dingo/blueprint 的开发版本 dev-master解决了冲突,可以正常安装,所以在 composer.json中添加两句:

composer.json

. 
.  
.
    "config":  {  
                    "preferred-install":  "dist", 
                     "sort-packages":  true,  
                     "optimize-autoloader":  true 
                     },  
                     "minimum-stability"  :  "dev",  
                     "prefer-stable"  :  true  
            }

添加的内容:

  • "minimum-stability" : "dev" ———设定的最低稳定性的版本是 dev 也就是可以依赖开发版本的扩展包。
  • "prefer-stable" : true ——— Composer 优先使用更稳定的版本。

2. 回滚迁移

回滚上一次迁移

php artisan migrate:rollback

回滚所有迁移

php artisan migrate:reset

回滚所有迁移并且再执行一次

php artisan migrate:refresh
php artisan migrate:refresh --seed

3. 字符串填充

str_pad —— 使用另一个字符串填充字符串为指定长度。

For example:

$input = "Hello World!";    // strlen($input) = 12
// pad_string 没有指定, input 被空格字符填充,默认右侧填充
echo str_pad($input, 15);    // "Hello World!   "
// 左侧填充
echo str_pad($input, 15, '+++', STR_PAD_LEFT);    // +++Hello World!
// 两侧填充,先填充右边,再填充左边
echo str_pad($input, 15, '+++', STR_PAD_BOTH);    // +Hello World!++
echo str_pad($input, 14, '+++', STR_PAD_BOTH);    // +Hello World!+
// pad_length 为负数,小于或者等于 input 的长度时,不发生填充
echo str_pad($input, 11, '+++');    // Hello World!

4. RESTful 架构 && RESTful API

RESTful 是一种软件设计风格,由 Roy Thomas Fielding 在他的 论文中提出,全称为Representational State Transfer,直译为表现层状态转化RESTful API 是目前比较成熟的一套互联网应用程序的 API 设计理论。
资源(Resources)

资源是网络上的一种实体(一种具体信息)。比如一段文本、一张图片、一种服务。
URI(统一资源定位符)标识资源的所在。每种资源对应一个特定的 URI 。 URI 成了每个资源的地址或者独一无二的标识。
所谓“上网”,就是互联网上一系列的“资源”互动,调用它的 URI 。

表现层(Representation)

资源是一种实体,有多种表现形式。我们把资源的具体呈现形式,叫做他的表现层。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现。
URL 只代表资源的实体,不是它的表现形式。
具体的表现形式,应该在 HTTP 请求的头信息中用 Accept 和 Content-Type 字段指定。这两个字段才是对"表现层"的描述。

状态转化(State Transfer)

HTTP 协议是无状态协议,所有的状态都保存在服务器端。
"状态转化"是指客户端通过某种手段操作服务器,让服务器发生”状态转化“。这种转化过程发生在表现层之上,所以就是”表现层状态转化“。
客户端采取的方式,是 HTTP 协议。具体是 HTTP 协议中的四个表示操作方式的动词:GET、POST、PUT、DELETE 。

综述

什么是 RESTful 架构?
(1)每一个 URI 代表一种资源。
(2)客户端和服务器之间,传递这种资源的某种表现层。
(3)客户端通过四个 HTTP 动词,对服务器资源进行操作,实现”表现层状态转化“。

误区

错误的设计

  • URI 包含动词。资源是一种实体,动作应放在 HTTP 协议中。
  • URI 中加入版本号。版本号可以在 HTTP 请求投信息的 Accept 字段中进行区分。

参考文章:

4. 手机注册流程

注册流程

  1. 用户输入手机号请求图片验证码
  2. 服务器返回图片验证码
  3. 使用正确的图片验证码,请求短信验证码
  4. 服务器调用短信运营商接口,发送短信给用户手机
  5. 输入正确的短信验证码,请求注册接口
  6. 完成用户注册

资源

  • captchas:图片验证码
  • verificationCodes:短信验证码
  • users:用户

接口设计

  • POST api/captchas:创建图片验证码
  • POST api/verificationsCodes:发送短信验证码
  • POST api/users:用户注册

5. 节流处理防止攻击

攻击方式:验证码轰炸。恶意调用发送短信验证码接口,给一个用户手机或者多个用户手机频繁发送验证码短信。

为了防止攻击,需要采取节流机制。节流是对接口调用频率的限制,限制每个 ip 的调用次数

DingoApi 提供了调用频率限制的中间件api.throttle

routes/api.php

$api->version('v1', [
    'namepsace' => 'App\Http\Controller\Api'
], function($api) {
    $api->group([
        'middleware' => 'api.throttle',
        // sign 登录相关配置. 次数(limit)/分钟(expires)。expires 分钟调用 limit 次
        'limit' => config('api.rate_limits.sign.limit'),
        'expires' => config('api.rate_limits.sign.expires'),
    ], function($api) {
        .
        .
        .
    });
});

6. OAuth 2.0

Auth 2.0 的一种简单解释

OAuth 是一种授权机制。第三方想要获取系统的数据,先发出一个授权请求,数据的所有者告诉系统,同意并授权第三方应用进入系统,系统产生一个短期的进入令牌(token),用来代替密码。第三方应用凭借此令牌可以进入系统获取数据。

令牌和密码的差异

  • 令牌是短期的,到期会自动失效,用户无法自己修改。密码一般长期有效,用户可以修改,不修改就不发生变化。
  • 令牌可以被数据所有者撤销,会立即失效。
  • 令牌有权限范围,对于网络来说,只读令牌会比读写令牌更加安全。密码一般是完整权限。

OAuth 2.0 运行流程

  1. 用户打开客户端(Client)后,客户端请求用户(Resource Owner)给予授权。
  2. 用户同意给客户端授权。
  3. 客户端获取上一步请求的授权,向认证服务器(Authorization Server)请求令牌(Access Token)。
  4. 认证服务器对客户端进行认证后,确认无误,同意发放令牌。
  5. 客户端使用令牌,向资源服务器(Resource Server)请求资源。
  6. 资源服务器确认令牌无误后,同意向客户端开放资源。

L03 遇到的知识记录(一)

7. 微信登录

微信公众平台测试账号,登录地址

测试 OAuth 流程
测试工具,微信 web 开发者工具

微信网页授权流程 :

  1. 获取授权码。

    请求地址:https://open.weixin.qq.com/connect/oauth2/...
    appid:测试账号的 appID (公众号的唯一标识)
    redirect_uri:用户同意授权后的回调地址,也就是你的网站地址。
    response_type:返回类型,填code,返回回调地址中会携带 code,它的值就是获取到的授权码。
    scope:应用授权作用域,填snsapi_userinfo
    state:随机参数,可以不填。
    #wechat_redirect:无论直接打开还是做页面302重定向时候,必须带此参数。
    替换后的请求地址:https://open.weixin.qq.com/connect/oauth2/...
    说明:code 作为换取 access_token 的凭据,每次用户授权使用的 code 都不一样,code 只能使用一次,5 分钟未使用会被自动过期。

  2. 通过 code 换取网页授权 access_token

    请求方法:https://api.weixin.qq.com/sns/oauth2/acces...
    appid:测试账号的appID 。 (公众号的唯一标识)
    serect:测试账号的appsecret
    code:上一步获取的 code 参数。
    grant_type: 填写 authorization_code

  3. 刷新 access_token(如果需要)

    请求方法:https://api.weixin.qq.com/sns/oauth2/refre...
    appid:测试账号的appID 。 (公众号的唯一标识)
    grant_type:填写refresh_token
    refresh_token:填写通过 access_token 获取到的 refresh_token 参数。

    说明:由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。

  4. 拉取用户信息(需要 scope 为 snsapi_userinfo)

    请求方法:https://api.weixin.qq.com/sns/userinfo?acc...
    access_token:网页接口调用凭证。此access_token与基础支持的access_token不同。
    openid:用户的唯一标识。 (这里指测试微信账号的微信号)
    lang:返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语。

8. JSON WEB TOKEN(JWT)

原文:JSON Web Token 入门教程

JWT 可以解决 session 数据跨域共享问题。服务器不保存保存 session 数据,所有的数据都保存在客户端,每次请求都发回给服务器。这样每个服务器都能读取到 session 数据。JWT 就是这种方案的一个代表。

JWT 原理
JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,以后,用户(客户端)与服务器通信的时候,都要带上这个 JSON 对象。服务器靠这个对象认证用户身份。为了防止 JSON 对象的数据被篡改,服务器在生成这个对象的时候,会加上签名。
服务器不保存任何 session 数据,也就是说JWT,服务器变成了无状态了,从而比较容易实现扩展。


JWT 的数据结构
JWT 实际上是一个很长的字符串,中间用"点"(.)分成三部分(HeaderPayloadSignature)。

  • Header:头部
  • Payload:负载
  • Signature:签名

实际的表示就是: Heade.Payload.Signature


Header
Header部分是一个 JSON 对象,描述 JWT 的元数据。

{
     "alg": "H256"
     "typ": "JWT"
}

alg属性表示签名的算法(algorithm),默认是 HMAC SHA256 (携程 HS256);
typ属性表示这个令牌的类型,JWT令牌统一携程JWT
这个JSON对象最后使用Base64URL算法转成字符串。


Payload
Payload部分也是一个 JSON对象,用来存放实际需要的传递的数据。JWT规定了 7 个官方字段,供选用。

  • iss(issure):签发人
  • exp(expiration time):过期时间
  • sub(subject):主题
  • aud(audience):受众
  • nbf(Not Before):生效时间
  • iat(Issued At):签发时间
  • jti(JWT ID):编号

除此之外,Payload允许你自定义私有字段。
注意:JWT默认不加密,不要把私密信息放在这个部分。
这个JSON对象也要使用 Base64URL算法转成字符串。


Signature
Signature部分是对前两个字段的签名,防止数据篡改。
首先,服务器需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用Header里面指定的签名算法(默认是 HMAC SHA256),按照下面公式产生签名。

HMACSHA256(
baase64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)

算出签名后,把HeaderPayloadSignature使用“点”(.)连接,拼成一个字符串,返回给用户。


JWT 的使用方式
客户端接收服务器返回的 JWT,可以存储在Cookie里面,也可以存储在 localStorage 。
此后,客户端每次和服务器进行通信,都要带上这个JWT。可以放在 Cookie里面自动发送,但是这样不能跨域。更好的做法是放在 HTTP 请求的头信息Authorization 字段里面。

Authorization: Bearer <token>

另一种做法是,跨域的时候,JWT放在 POST 请求的数据体里面。


JWT 的特点

  1. JWT 默认不加密,但是可以加密。生成原始 token 后,可以使用密钥再加密一次。
  2. JWT 不加密的情况下,不能将秘密数据写入 JWT。
  3. JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
  4. JWT 最大的缺点就是,服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改的权限。就是说,JWT 签发之后,在过期之前一直有效。除非服务器部署额外的逻辑。
  5. JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
  6. 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
本作品采用《CC 协议》,转载必须注明作者和本文链接

每天进步一点点

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 1

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!