JWT 多网站单点登录,放弃session
多个网站之间的登录信息共享, 基于cookie - session的登录认证方式跨域等比较复杂。采用基于算法的认证方式, JWT(json web token)的方式。
------------------------------------------------------------------------------------------
参考:
http://www.tuicool.com/articles/IRJnaa
https://coderwall.com/p/8wrxfw/goodbye-php-sessions-hello-json-web-tokens
在JavaScript前端技术大行其道的今天,我们通常只需在后台构建API提供给前端调用,并且后端仅仅设计为给前端移动App调用。用户认证是Web应用的重要组成部分,基于API的用户认证有两个最佳解决方案 —— OAuth 2.0 和JWT(JSON Web Token)。
1、JWT定义及其组成
JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
载荷(Payload)
我们先将用户认证的操作描述成一个JSON对象。其中添加了一些其他的信息,帮助今后收到这个JWT的服务器理解这个JWT。
{
"sub": "1",
"iss": "http://localhost:8000/auth/login",
"iat": 1451888119,
"exp": 1454516119,
"nbf": 1451888119,
"jti": "37c107e4609ddbcc9c096ea5ee76c667"
}
这里面的前6个字段都是由JWT的标准所定义的。
- sub: 该JWT所面向的用户
- iss: 该JWT的签发者
- iat(issued at): 在什么时候签发的token
- exp(expires): token什么时候过期
- nbf(not before):token在此时间之前不能被接收处理
- jti:JWT ID为web token提供唯一标识
这些定义都可以在 标准 中找到。
将上面的JSON对象进行base64编码可以得到下面的字符串:
eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ
这个字符串我们将它称作JWT的Payload(载荷)。
如果你使用Node.js,可以用Node.js的包base64url来得到这个字符串:
var base64url = require('base64url')
var header = {
"from_user": "B",
"target_user": "A"
}
console.log(base64url(JSON.stringify(header)))
注:Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程。
头部(Header)
JWT还需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象:
{
"typ": "JWT",
"alg": "HS256"
}
在这里,我们说明了这是一个JWT,并且我们所用的签名算法(后面会提到)是HS256算法。
对它也要进行Base64编码,之后的字符串就成了JWT的Header(头部):
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
签名(签名)
将上面的两个编码后的字符串都用句号.连接在一起(头部在前),就形成了:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ
最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret):
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
这样就可以得到我们加密后的内容:
wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqcCJDENNfnaT4
这一部分又叫做签名。
最后将这一部分签名也拼接在被签名的字符串后面,我们就得到了完整的JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiaXNzIjoiaHR0cDpcL1wvbG9jYWx
ob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDUxODg4MTE5LCJleHAiOjE0NTQ1MTYxMTksIm5iZiI6MTQ1MTg4OD
ExOSwianRpIjoiMzdjMTA3ZTQ2MDlkZGJjYzljMDk2ZWE1ZWU3NmM2NjcifQ.wyoQ95RjAyQ2FF3aj8EvCSaUmeP0KUqc --------------------------------------
Goodbye PHP Sessions, Hello JSON Web Tokens
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!
You can get the PHP JWT class as a single file from: https://github.com/rmcdaniel/angular-codeigniter-seed/blob/master/api/application/helpers/jwt_helper.php
as it is used by the AngularJS CodeIgniter Seed project:
https://github.com/rmcdaniel/angular-codeigniter-seed
or the original code from:
Written by Richard McDaniel
JWT 多网站单点登录,放弃session的更多相关文章
- Spring Security整合JWT,实现单点登录,So Easy~!
前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...
- JWT&RSA实现单点登录(详细介绍)
今天给大家讲一下基于JWT&RSA的单点登录(Single Sign On,简称SSO)解决方案 概念 首先要了解几个概念 单点登录(Single Sign On) JWT RSA 背景 为什 ...
- 看图理解JWT如何用于单点登录
单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...
- 基于JWT机制的单点登录
使用JWT实现单点登录时,需要注意token时效性.token是保存在客户端的令牌数据,如果永久有效,则有被劫持的可能.token在设计的时候,可以考虑一次性有效或一段时间内有效.如果设置有效时长,则 ...
- 单点登录,session,jsonp(待更新)
单点登录理解: 单点登录系统设计: ajax跨域:
- 使用JWT来实现单点登录功能
出处: https://www.cnblogs.com/zexin/p/10389541.html 我们平时自己开发项目,分布式的结构时,访问量不大,但是又不想搭建redis服务器,这时我觉得jwt不 ...
- 如何使用JWT来实现单点登录功能
我们平时自己开发项目,分布式的结构时,访问量不大,但是又不想搭建redis服务器,这时我觉得jwt不错. 个人理解,jwt就是类似于一把锁和钥匙,客户来租房(登录),我们需要给他进来(第一次登录)登记 ...
- 使用JWT+RSA完成SSO单点登录
无状态登录原理 1.1.什么是有状态? 有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session. 例如登录:用户登 ...
- 编程界失传秘术,SSO单点登录,什么是单点,如何实现登录?
单点登录 多系统,单一位置登录,实现多系统同时登录的一种技术. 常出现在互联网应用和企业级平台中. 如:京东. 单点登录一般是用于互相授信的系统,实现单一位置登录,全系统有效的. 三方登录:某系统,使 ...
随机推荐
- .net中获取图像缩略图的函数GetThumbnailImage
关于.net中获取图像缩略图的函数GetThumbnailImage的一些认识. 在很多图像软件中,打开一幅图像的时候都会显示其缩略图,在看图软件中这样的需求更为常见.如何快速的获取缩略图的信息并提供 ...
- Arduino 各种模块篇 粉尘传感器 dust sensor 空气质量检测
Testing a sensor from here. http://www.seeedstudio.com/wiki/Grove_-_Dust_Sensor It's a dust sensor. ...
- Python 3语法小记(五)字符串
Python 3 的源码的默认编码方式为 UTF-8 在Python 3,所有的字符串都是使用Unicode编码的字符序列. utf-8 是一种将字符编码成字节序列的方式.字节即字节,并非字符.字符在 ...
- Dreamer 框架 比Struts2 更加灵活
winter 改名为Dreamer. 这次发布第二个版本. 这次修复了很多BUG 和完善了部分功能. 1.改进用户服务层 以后在服务层中只需要继承BaseSupport 泛型类 就可以实现对对象进行增 ...
- 开源中文分词工具探析(三):Ansj
Ansj是由孙健(ansjsun)开源的一个中文分词器,为ICTLAS的Java版本,也采用了Bigram + HMM分词模型(可参考我之前写的文章):在Bigram分词的基础上,识别未登录词,以提高 ...
- office全系列激活脚本-改良版
@ECHO OFFTITLE office 全版本系统激活@echo offfor /l %%a in (8,1,16) do (for /f "tokens=*" %%i in ...
- <span>什么意思
<span> 在CSS定义中属于一个行内元素,在行内定义一个区域,也就是一行内可以被 <span> 划分成好几个区域,从而实现某种特定效果. <span> 本身没有 ...
- sublime vue 语法高亮插件安装
默认情况下,Vue.js 的单文件组件(*.vue)在 sublime 编辑器中是不被识别的.若要想高亮显示,需要安装插件 Vue Syntax Hightlight.安装步骤如下: 第一,在 s ...
- Docker集群实验环境布署--swarm【5 容器启动组件--node】
10.40.100.143 docker-node0.venic.com 10.40.100.144 docker-node1.venic.com 原用swarm镜像 直接启动 1 ...
- 解决了IE8不支持数组的indexOf方法
ie在过去给我们添了很多坑. if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/ ) { ...