JWT利用JSON Web署名 和 公钥加密 来确定其有效性。

JWT 的数据构造

HEADER.PAYLOAD.SIGNATURE

中间用点(.)分隔成三个部分。
把稳,JWT 内部是没有换行的。

Header(头部)Payload(负载)Signature(署名)

HEADER

基于php的jwtphp 实现 jwt React

{\"大众typ\公众: \"大众JWT\公众, \"大众alg\"大众:\公众RS256\"大众}

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

alg属性表示署名的算法(algorithm),默认是 HMAC SHA256(写成 HS256)typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

Payload

{ \公众id\"大众: \"大众394a71988caa6cc30601e43f5b6569d52cd7f6df\"大众, \"大众jti\"大众: \"大众394a71988caa6cc30601e43f5b6569d52cd7f6df\"大众, \"大众iss\"大众: \公众issuer_id\"大众, \公众aud\"大众: \"大众client_id\公众, \"大众sub\公众: \公众user_id\"大众, \公众exp\"大众: 1483711650, \"大众iat\"大众: 1483708050, \"大众token_type\"大众: \"大众bearer\公众, \"大众scope\"大众: \"大众onescope twoscope\"大众}​

Payload 部分也是一个 JSON 工具,用来存放实际须要通报的数据。
JWT 规定了7个官方字段,供选用。
除了官方字段,还可以在这个部分定义私有字段.

id - 令牌的内部idjti - 令牌的唯一令牌标识符iss - 发出令牌的做事器的IDaud - 要求令牌的客户真个IDsub - 开释令牌的用户的IDexp - 令牌过期时的UNIX韶光戳iat - 创建令牌时的UNIX韶光戳token_type - 那种令牌,将是持票人scope - 以空格分隔的范围列表,为其颁发令牌

Signature

是对前两部分的署名,防止数据修改。

须要指定一个密钥(secret)。
利用 Header 里面指定的署名算法(默认是 HMAC SHA256),按照下面的公式产生署名。

HMACSHA256(base64UrlEncode(header) + \"大众.\公众 +base64UrlEncode(payload),secret)

算出署名往后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用\"大众点\"大众(.)分隔,就可以返回给用户。

Base64URL

Header 和 Payload 串型化的算法是 Base64URL。
这个算法跟 Base64 算法基本类似,但有一些小的不同。

JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。
Base64 有三个字符+、/和=,在 URL 里面有分外含义,以是要被更换掉:=被省略、+更换成-,/更换成_ 。
这便是 Base64URL 算法。

JWT 的利用办法

客户端收到做事器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与做事器通信,都要带上这个 JWT。
你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,以是更好的做法是放在 HTTP 要求的头信息Authorization字段里面。

获取jwt,携带jwt获取资源,做事端进行鉴权。

JWT 的几个特点默认是不加密,但也是可以加密的。
天生原始 Token 往后,可以用密钥再加密一次。
不加密的情形下,不能将秘密数据写入 JWT。
不仅可以用于认证,也可以用于交流信息。
有效利用 JWT,可以降落做事器查询数据库的次数。
的最大缺陷是,由于做事器不保存 session 状态,因此无法在利用过程中破除某个 token,或者变动 token 的权限。
也便是说,一旦 JWT 签发了,在到期之前就会始终有效,除非做事器支配额外的逻辑。
本身包含了认证信息,一旦透露,任何人都可以得到该令牌的所有权限。
为了减少盗用,JWT 的有效期该当设置得比较短。
对付一些比较主要的权限,利用时该当再次对用户进行认证。
为了减少盗用,JWT 不应该利用 HTTP 协议明码传输,要利用 HTTPS 协议传输。

创建公钥和私钥对

mkdir keyscd keysopenssl genrsa -out privkey.pem 2048openssl rsa -in privkey.pem -pubout -out pubkey.pem

认证token做事

​<?php/ Created by PhpStorm. User: jinchunguang Date: 19-8-23 Time: 下午1:21 /​// token.php​// error reporting (this is a demo, after all!)ini_set('display_errors',1);error_reporting(E_ALL);​// Autoloading (composer is preferred, but for this example let's just do this)require_once('oauth2-server-php/src/OAuth2/Autoloader.php');OAuth2\Autoloader::register();​// your public key strings can be passed in however you like// (there is a public/private key pair for testing already in the oauth library)$publicKey = file_get_contents('./keys/pubkey.pem');$privateKey = file_get_contents('./keys/privkey.pem');​// create storage$storage = new OAuth2\Storage\Memory(array( 'keys' => array( 'public_key' => $publicKey, 'private_key' => $privateKey, ), // add a Client ID for testing 'client_credentials' => array( 'CLIENT_ID' => array('client_secret' => 'CLIENT_SECRET') ),));​$server = new OAuth2\Server($storage, array( 'use_jwt_access_tokens' => true,));$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage)); // minimum config​// send the response$server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();​​

启动做事

php -S localhost:3000 &

获取access_token

curl http://localhost:3000/token.php -u 'CLIENT_ID:CLIENT_SECRET' -d \"大众grant_type=client_credentials\"大众 |jq % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 755 0 726 100 29 27923 1115 --:--:-- --:--:-- --:--:-- 30200{ \"大众access_token\"大众: \公众eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6ImZiNzhiMmJjMmYyOGQwYzZlYTVhN2Y5YTZhN2Y0NjhhZmQxZWY0ZGIiLCJqdGkiOiJmYjc4YjJiYzJmMjhkMGM2ZWE1YTdmOWE2YTdmNDY4YWZkMWVmNGRiIiwiaXNzIjoiIiwiYXVkIjoiQ0xJRU5UX0lEIiwic3ViIjpudWxsLCJleHAiOjE1NjY1NDIzNjEsImlhdCI6MTU2NjUzODc2MSwidG9rZW5fdHlwZSI6ImJlYXJlciIsInNjb3BlIjpudWxsfQ.mSaXWNRQzFgPW1BJtxb8zM1Ktu0LkNru5Wzi1m6PTEy59yVZ3T6MbwlQzp3WmP0H-6eZhcQHPw1G-AHSNoR3Di_4umyvmcjCiHCixBWlcHy2ELZkeXOTrjjaoEJ-vpH33qfV7hh47QUHyJPEKHi-WMMoFfjCyhWxdRY-slV7oiWu69IaWLT8KmEY2FspjcUlWnd0jy4FWwA5jmyEY4qdke0ux2YHAwtKxT-y_i_2qQTK6T5AHe2GMyCy3Vk2dp2voX3igxpNmQ9zTCHI66Brz5OWWbG9SQVPB8udxLh_hLsLLrhuh1Q3DoaAjGho7Z8nZ0DV4vx2FPQDmnYbm5m4YA\"大众, \"大众expires_in\"大众: 3600, \"大众token_type\"大众: \"大众bearer\"大众, \"大众scope\公众: null}​

资源做事器认证

​<?php/ Created by PhpStorm. User: jinchunguang Date: 19-8-23 Time: 下午1:25 /​require_once('oauth2-server-php/src/OAuth2/Autoloader.php');OAuth2\Autoloader::register();/ for a Resource Server (minimum config) /$publicKey = file_get_contents('./keys/pubkey.pem');​// no private key necessary$keyStorage = new OAuth2\Storage\Memory(array('keys' => array( 'public_key' => $publicKey,)));​$server = new OAuth2\Server($keyStorage, array( 'use_jwt_access_tokens' => true,));​// verify the JWT Access Token in the requestif (!$server->verifyResourceRequest(OAuth2\Request::createFromGlobals())) { exit(\"大众Failed\"大众);}​// 正常业务逻辑echo \公众Success!\"大众;​​

cli访问

curl -i http://localhost:3000/resource.php\?access_token\=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpZCI6ImZiNzhiMmJjMmYyOGQwYzZlYTVhN2Y5YTZhN2Y0NjhhZmQxZWY0ZGIiLCJqdGkiOiJmYjc4YjJiYzJmMjhkMGM2ZWE1YTdmOWE2YTdmNDY4YWZkMWVmNGRiIiwiaXNzIjoiIiwiYXVkIjoiQ0xJRU5UX0lEIiwic3ViIjpudWxsLCJleHAiOjE1NjY1NDIzNjEsImlhdCI6MTU2NjUzODc2MSwidG9rZW5fdHlwZSI6ImJlYXJlciIsInNjb3BlIjpudWxsfQ.mSaXWNRQzFgPW1BJtxb8zM1Ktu0LkNru5Wzi1m6PTEy59yVZ3T6MbwlQzp3WmP0H-6eZhcQHPw1G-AHSNoR3Di_4umyvmcjCiHCixBWlcHy2ELZkeXOTrjjaoEJ-vpH33qfV7hh47QUHyJPEKHi-WMMoFfjCyhWxdRY-slV7oiWu69IaWLT8KmEY2FspjcUlWnd0jy4FWwA5jmyEY4qdke0ux2YHAwtKxT-y_i_2qQTK6T5AHe2GMyCy3Vk2dp2voX3igxpNmQ9zTCHI66Brz5OWWbG9SQVPB8udxLh_hLsLLrhuh1Q3DoaAjGho7Z8nZ0DV4vx2FPQDmnYbm5m4YA HTTP/1.1 200 OKHost: localhost:3000Date: Fri, 23 Aug 2019 05:41:36 GMTConnection: closeX-Powered-By: PHP/7.2.19-0ubuntu0.18.04.2Content-type: text/html; charset=UTF-8​Success!%

技能参考:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html