JWT利用JSON Web署名 和 公钥加密 来确定其有效性。
JWT 的数据构造HEADER.PAYLOAD.SIGNATURE
中间用点(.)分隔成三个部分。把稳,JWT 内部是没有换行的。
Header(头部)Payload(负载)Signature(署名)HEADER
{\公众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-8Success!%
技能参考:http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html