일:JWT 소개:전칭 JSON Web Token, JSON의 오픈 표준(RFC 7519)에 근거해, Token 방식으로 전통적인 Cookie-Session 모드를 대체하고, 각 서버, 클라이언트의 정보 전달 서명 검증에 사용합니다.
2: JWT의 장점:
1: 서비스 측에서 기존 세션 정보를 저장할 필요가 없으며, 도메인 간 전송 문제가 없으며, 서버 오버헤드를 줄일 수 있습니다.
2:jwt는 간단한 구성으로 적은 바이트를 차지해 전송이 용이하다.
3:json 포맷이 통용되어 서로 다른 언어 간에 사용할 수 있습니다.
3. JWT 구성
1:jwt는 세 부분으로 구성된다.
헤더(header)
payload에는 정의 정보와 사용자 정의 정보가 들어 있습니다
비자(signature)
2:구체적 구성:
헤더:
{
"typ": "JWT", //선언 형식jwt
"alg": "HS256" //서명 알고리즘은 다음과 같습니다SHA256
}
페이로드(payload)
{
"iss": "http://www.helloweba.net",
"aud": "http://www.helloweba.net",
"iat": 1525317601,
"nbf": 1525318201,
"exp": 1525318201,
"data": {
"userid": 1,
"username": "리샤오룽"
}
}
하중은 표준 및 기타 선언의 두 부분으로 구성된다.
표준성명: JWT 표준규격에 규정된 성명, 그러나 아니다.반드시 기입해야 한다.
표준 선언 필드:
이 JWT를 받는 쪽
iss: jwt 발급자
sub: jwt 대상 사용자
aud:jwt를 받는 쪽
exp: jwt의 만료 시간, 만료 시간 필수발급 시간보다 커야 함
nbf: 정의하기 전, 시간점호 후에야 접속할 수 있다
iat: jwt 발급 시간
jti: jwt의 고유 아이덴티티, 주로 사용일회용 토큰으로 하겠습니다.
기타 성명: 자신이 정의한 필드. 이 부분은 풀 수 있으므로 민감한 정보를 넣지 말 것을 권고합니다. 여기서 data는 내가 정의한 성명입니다.
세 부분을 각각 쉼표로 구분하다
4:사용:PHP가 많다jwt 가방, 예를 들어 lobucci/jwt, 나는 여기서 firebase를 사용한다.git 주소에서 다운로드할 수 있습니다
1: 코드를 뽑아내라
composer require firebase/php-jwt
2:서비스측발급 토큰
<?php
use \Firebase\JWT\JWT; //가져오기JWT
class MainController extends Controller
{
//발급하다Token
public function lssue()
{
$key = '344'; //key
$time = time(); //현재 시간
$token = [
'iss' => 'http://www.helloweba.net', //발급자 선택 가능
'aud' => 'http://www.helloweba.net', //해당 JWT를 수신하는 측, 옵션
'iat' => $time, //발급시기
'nbf' => $time , //(Not Before):time+30을 설정하면 현재 30초 후에 사용할 수 있습니다.
'exp' => $time+7200, //유통기한 경과시간, 여기에서 2시간을 설정한다.
'data' => [ //사용자 정의 정보, 중요한 정보를 정의하지 않음
'userid' => 1,
'username' => '리샤오룽'
]
];
echo JWT::encode($token, $key); //출력Token
}
3: 토큰을 해석하고, 프레젠테이션을 위해 여기에 직접 적습니다.
<?php
use \Firebase\JWT\JWT; //가져오기JWT
class MainController extends Controller
{
public function verification()
{
$key = '344'; //key발급할 때랑 똑같아야 돼
$jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuaGVsbG93ZWJhLm5ldCIsImF1ZCI6Imh0dHA6XC9cL3d3dy5oZWxsb3dlYmEubmV0IiwiaWF0IjoxNTI1MzQwMzE3LCJuYmYiOjE1MjUzNDAzMTcsImV4cCI6MTUyNTM0NzUxNywiZGF0YSI6eyJ1c2VyaWQiOjEsInVzZXJuYW1lIjoiXHU2NzRlXHU1YzBmXHU5Zjk5In19.Ukd7trwYMoQmahOAtvNynSA511mseA2ihejoZs7dxt0"; //발급받은Token
try {
JWT::$leeway = 60;//현재 시간에서 60을 빼면, 시간을 좀 남겨두어라
$decoded = JWT::decode($jwt, $key, ['HS256']); //HS256방식, 여기 발급 시 대응
$arr = (array)$decoded;
print_r($arr);
} catch(\Firebase\JWT\SignatureInvalidException $e) { //서명이 잘못되었습니다.
echo $e->getMessage();
}catch(\Firebase\JWT\BeforeValidException $e) { // 사인은 어느 시점 이후에나 사용할 수 있습니다.
echo $e->getMessage();
}catch(\Firebase\JWT\ExpiredException $e) { // token기한이 지나다
echo $e->getMessage();
}catch(Exception $e) { //기타 오류
echo $e->getMessage();
}
//Firebase여러 개를 정의했습니다 throw new,우리는 여러 개를 잡을 수 있다.catch문제를 정의하다,catch자신의 업무에 가입하다,예를 들어token기한이 지나면 현재로 쓸 수 있다Token새로 고침Token
}
}
src 디렉터리에 있는 JWT.php에 있는 메서드 decode에서 여러 개의 사용자 정의 throw new를 통해 이상을 던지는 것을 볼 수 있습니다.
그래서 우리는 서로 다른 throw new에 따라 여러 개의 catch를 설치하여 포획할 수 있다.
출력 데이터:
Array
(
[iss] => http://www.helloweba.net
[aud] => http://www.helloweba.net
[iat] => 1525340317
[nbf] => 1525340317
[exp] => 1525347517
[data] => stdClass Object
(
[userid] => 1
[username] => 리샤오룽
)
)
5:실전 시뮬레이션
1: 시나리오: 클라이언트아이디 패스워드로 로그인한 후, 서비스 측에서 클라이언트에 두 개의 토큰(access_token)과 refresh_token)을 반환한다.
access_token: 인터페이스를 요청하는 토큰
refresh_token: 새로 고침access_token
예를 들면 access_token 설정 2시간 만료, refresh_token 설정 7일 만료, 2시간 후 access_token 만료, 단 refresh_token 아직 7일 이내면 클라이언트가 통과refresh_token 서비스 측에서 a를 새로 고칩니다ccess_token; refresh_token도 7일 이상 경과하면 클라이언트는 다시 로그인하여 access_token과 refresh_token을 얻어야 합니다.
두 개의 to를 구분하기 위해서ken, 페이로드(payload)에 scopes: 도메인 필드를 추가합니다.
access_token에서 설정: scopes: role_access
refresh_token에서 설정: scopes: role_refresh
어떤 분들은 t를 하나 쓰시는데oken, 긴 시간 만료로 설정하거나, 몇 시간 만료로 설정하거나, 만료되면 만료된 토큰을 새 토큰과 교환하는 것은 문제가 있습니다. 일부 사람들은 문제가 있습니다.토큰에는 두 개의 시간이 있다고 합니다. 하나는 만료 시간이고 하나는 새로 고침입니다.시간, 리프레시 시간만 있으면 새 토큰으로 교환할 수 있다.만약 다른 사람이 너를 가졌다면이 토큰도, 만약 유통기한 내에 있다면, 마찬가지로 토큰을 갱신할 수 있지 않을까요?두 개의 토큰을 다 얻지 않는 한 상대적으로 두 번째 아이템이 더 안전하다.
직접 코드:
<?php
use \Firebase\JWT\JWT; //가져오기JWT
class MainController extends Controller
{
public function authorizations()
{
$key = 'ffdsfsd@4_45'; //key
$time = time(); //현재 시간
//공용 정보
$token = [
'iss' => 'http://www.helloweba.net', //발급자 선택 가능
'iat' => $time, //발급시기
'data' => [ //사용자 정의 정보, 중요한 정보를 정의하지 않음
'userid' => 1,
]
];
$access_token = $token;
$access_token['scopes'] = 'role_access'; //tokenID, 인터페이스 요청token
$access_token['exp'] = $time+7200; //access_token유통기한 경과시간, 여기에서 2시간을 설정한다.
$refresh_token = $token;
$refresh_token['scopes'] = 'role_refresh'; //token표시, 새로 고침access_token
$refresh_token['exp'] = $time+(86400 * 30); //access_token만료일, 여기 30일을 설정합니다.
$jsonList = [
'access_token'=>JWT::encode($access_token,$key),
'refresh_token'=>JWT::encode($refresh_token,$key),
'token_type'=>'bearer' //token_type:토큰 유형을 나타냅니다. 이 값은 대소문자가 민감하지 않습니다. 여기서 사용합니다bearer
];
Header("HTTP/1.1 201 Created");
echo json_encode($jsonList); //클라이언트 토큰으로 메시지 보내기
}
}
출력은 다음과 같습니다.
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuaGVsbG93ZWJhLm5ldCIsImlhdCI6MTUyNTQxNzg5NywiZGF0YSI6eyJ1c2VyaWQiOjF9LCJzY29wZXMiOiJyb2xlX2FjY2VzcyIsImV4cCI6MTUyNTQyNTA5N30.Nxp1yutwt8Fxj5XEzes4j-X4tCBQwE0htEV3Msm2D8s",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC93d3cuaGVsbG93ZWJhLm5ldCIsImlhdCI6MTUyNTQxNzg5NywiZGF0YSI6eyJ1c2VyaWQiOjF9LCJzY29wZXMiOiJyb2xlX3JlZnJlc2giLCJleHAiOjE1MjgwMDk4OTd9.YY8Lid3nk3bnV-ZnAYneKJxGiaD73waqTpC3bHz3wsY",
"token_type": "bearer"
}
HTTP 헤더 응답은 토큰 클라이언트 2개가 저장되고, 하나는 인터페이스를 취하고, 하나는 인터페이스를 새로 고치는 것이다.
클라이언트가 요청할 때 HTTP 헤더에 Authorization: bearer token,베어러 뒤에 공간이 있으니 주의하세요.PHP로 시뮬레이션을 해보세요.
요청 정보는 다음과 같습니다. PHP는 Authorization 정보를 획득하여 판단합니다.
이것은 단지 하나의 생각일 뿐이다.여러분은 자신의 생각대로 할 수 있다.이런 생각의 서비스는 토큰을 보존할 필요가 없다.토큰은 만료되지 않지만 토큰을 로그아웃하려면 레디스(redis)에 등록할 수 있다.
'개발 꿀팁 > PHP' 카테고리의 다른 글
PHP+Mysql 구현 첨삭 수정 조사 (0) | 2022.06.30 |
---|---|
CentOS 7 시스템에 PHP 7.4 버전을 설치하는 방법 (0) | 2022.06.29 |
php-i 또는 phpinfo()를 사용하여 php 설치, 설정 정보 보기 (0) | 2022.06.29 |
윈도7 PHP 7.1 개발 환경 구축 (0) | 2022.06.29 |
IDEA 2019 PHP 프로젝트 실행 (0) | 2022.06.29 |