声明
此文原创,未经允许,禁止转载,可以分享。
最近在做一个项目,是一个APP的后端开发。我需要完成后端框架的建立、数据库设计、后端代码的编写。在这里讲一下APP与后端交互的安全性。
没有AUTH的验证
最简单的验证机制是通过session来存储认证信息的,但这个不便于客户端存储,而且有不能跨域请求认证的缺点。
大致流程:
用户登录(输入账户密码)
后端验证
验证通过则在session存储用户ID
每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。
Basic 认证方式
传统的认证方式就是构造一个字符串,这个字符串里面含有账户名和密码,比如:
$str = "username:password";
如果希望它不可读,可以对其进行base64编码:
$str = "username:password";$token = base64_encode($str);echo $token;
dXNlcm5hbWU6cGFzc3dvcmQ=
这样每次请求API的时候加上这个Token值,然后后端获取到这个Token值,对其进行:
$str = base64_decode($token); $auth = explode(':', $str); var_dump($auth);
然后使用auth
到数据库中进行查询来验证有效性。
但缺点很明显:
被窃取的可能性:每次使用这个token值进行请求,意味着每次请求都在泄露用户的密码。
增加数据库工作量:每次请求都要去数据库查询是否有效,效率明显下降。
对于传统的AUTH方式做了改进,引入JWT。
JWT认证机制
什么是JWT?
Json web token (JWT), 是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
它的核心就是签名。比如我有一个字符串。
$str = "qq:792598794;name:sungod";
我该怎么验证这是我给的字符串呢?
方法很简单,对这个字符串和一个密钥,一起进行不可逆运算
echo md5($str . 'KEY');echo sha1($str . 'KEY');echo crypt($str, 'KEY');
假如我们使用sha1
算法对其进行不可逆运行,得到:
81a2453b89cb914c2208a37e3ca4e4f26c44fe43
然后我们将这个结果放入到$str
中
$str = "qq:792598794;name:sungod;auth=81a2453b89cb914c2208a37e3ca4e4f26c44fe43";echo base64_encode($str);
cXE6NzkyNTk4Nzk0O25hbWU6c3VuZ29kO2F1dGg9ODFhMjQ1M2I4OWNiOTE0YzIyMDhhMzdlM2NhNGU0ZjI2YzQ0ZmU0Mw==
这样,如果KEY
只有我知道(前提是肯定只有我知道),那么我敢说这个字符串一定是我给的。
利用这个,我们前人总结出了一个规范JWT。
JWT流程
客户端使用账户密码进行签名请求
服务器验证账户密码是否有效
通过验证服务器返回一个Token
客户端存储这个Token,并每次请求都携带
服务器接收到需要验证的请求,验证客户端发来的Token
这个Token可以放在请求头、Cookie、GET、POST,看具体的业务逻辑需要。
如何正确的构造JWT
在PHP中,我们需要一个数组,这个数组用来存储用户的主要信息
$data = [ 'uid' => 10000, 'exp' => time() + 3600, ];
uid
表示用户的ID,键值尽量不要取得太长uid
三个字符刚好。exp
表示这个Token什么时候失效,这里是当前时间的1小时后。
对于一个数组,我们不能把它进行不可逆运行,需要将其转换一下。
// 转换为json字符串$data = json_encode($data);// 转换为base64编码$data = base64_encode($data);echo $data;
最后我们数组成为了一个字符串,每次都不一样,因为有时间在变化
eyJ1aWQiOjEwMDAwLCJleHAiOjE1MDI2ODQ3MjF9
共同學習,寫下你的評論
評論加載中...
作者其他優質文章