23 Oct 2015
jwt 不仅可用于验证用户还可用于 server 间通信验证
传统验证方式(目前大部分网站使用的方式):
现代网页应用验证用户时面临的困难
- app server 可能是分布式的, 有很多 server, 在一个 server 上登录了,
其他的没登陆, 需要额外工具来解决这个问题(sticky sessions) - app 使用 RESTfull api 来获取数据, RESTful api 的原则是 stateless, 但使用 session, 使用 session 和 cookies 会引入 state; 另外, 当 API server 与 app server
可能是两个 server, 需要 允许 CORS(Cross-Origin Resource Sharing), 但是 cookies 只能在同一个 domain 中使用 - app 可能需要下游服务, 每个 server 都要处理 cookie(???)
解决办法: 使用 JWT 方式来验证用户
JWT 方案不使用 session 基于 token.
用户注册之后, 服务器生成一个 JWT token返回给浏览器, 浏览器向服务器请求
数据时将 JWT token 发给服务器, 服务器用 signature 中定义的方式解码
JWT 获取用户信息.
一个 JWT token包含3部分:
1. header: 告诉我们使用的算法和 token 类型
2. Payload: 必须使用 sub key 来指定用户 ID, 还可以包括其他信息
比如 email, username 等.
3. Signature: 用来保证 JWT 的真实性. 可以使用不同算法
Session方式存储用户id的最大弊病在于要占用大量服务器内存,对于较大型应用而言可能还要保存许多的状态。一般而言,大型应用还需要借助一些KV数据库和一系列缓存机制来实现Session的存储。
而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如该用户是否是管理员、用户所在的分桶(见[《你所应该知道的A/B测试基础》一文](/2015/08/27/introduction-to-ab-testing/)等。
##1.
REST API's are meant to be stateless. What that means is that each request from a client should include all the information needed to process the request.In other words, if you are writing a REST API in PHP then you should not be using $_SESSION to store data about the client's session. But then how do we remember if a client is logged in or anything else about their state?The only possibility is that the client must be tasked with keeping track of the state.How could this ever be done securely? The client can't be trusted!
Enter JSON web tokens. A JSON web token is a bit of JSON, perhaps something that looks like this:
{
"user": "alice",
"email": "test@nospam.com"
}
Of course, we can't just give this to a client and have them give it back to us without some sort of assurance that it hasn't been tampered with. After all, what if they edit the token as follows:
{
"user": "administrator",
"email": "test@nospam.com"
}
The solution to this is that JSON web tokens are signed by the server. If the client tampers with the data then the token's signature will no longer match and an error can be raised.
The JWT PHP class makes this easy to do. For example, to create a token after the client successfully logs in, the following code could be used:
$token = array();
$token['id'] = $id;
echo JWT::encode($token, 'secret_server_key');
And then on later API calls the token can be retrieved and verified by this code:
$token = JWT::decode($_POST['token'], 'secret_server_key');
echo $token->id;
If the token has been tampered with then $token will be empty there will not be an id available. The JWT class makes sure that invalid data is never made available. If the token is tampered with, it will be unusable. Pretty simple stuff!
1. http://www.slideshare.net/derekperkins/authentication-cookies-vs-jwts-and-why-youre-doing-it-wrong
所有评论(0)