이전에는 PHP에서 간단한 REST API를 만드는 방법을 배웠습니다. 데이터베이스 레코드 생성, 읽기, 업데이트 및 삭제 (CRUD 작업)는 우리 프로젝트에 유용했습니다.
오늘은 REST API와 JSON 웹 토큰 또는 JWT를 사용하여 사용자를 인증하는 방법을 배웁니다.
이 자습서에서는 기본 가입 또는 등록 양식, 로그인 및 로그 아웃 작업, 사용자 계정 업데이트 등을 다룹니다.
1.0 프로젝트 개요
1.1 JWT 란?
1.2 JWT 간단한 비유
1.3 JWT는 어떻게 생겼습니까?
1.4 JWT와 OAuth
2.0 최종 출력
3.0 파일 구조
4.0 데이터베이스 설정
4.1 데이터베이스 생성
4.2 테이블 생성
4.3 구성을 위한 디렉토리 생성
4.4 데이터베이스 연결 파일 만들기
5.0 사용자 등록을 위한 API 생성
5.1 사용자 생성을 위한 파일 생성
5.2 데이터베이스 및 사용자 테이블에 연결
5.3 제출 된 데이터를 개체 속성에 할당
5.4 create() 메서드 사용
5.5 사용자 개체 클래스 만들기
5.6 create() 메서드 추가
5.7 출력
6.0 사용자 로그인을 위한 API 생성
6.1 사용자 로그인을 위한 파일 생성
6.2 데이터베이스 및 사용자 테이블에 연결
6.3 이메일 존재 여부 확인
6.4 emailExists() 메서드 추가
6.5 JWT 인코딩을 위한 파일 포함
6.6 JSON 웹 토큰 생성
6.7 사용자 로그인 실패 알림
6.8 핵심 구성 파일 생성
6.9 GitHub에서 PHP-JWT 다운로드
6.10 출력
7.0 JWT 유효성 검사를 위한 API 생성
7.1 JWT 유효성 검사를 위한 파일 생성
7.2 JWT 디코딩을 위한 파일 포함
7.3 주어진 JWT 검색
7.4 존재하는 경우 JWT 디코딩
7.5 디코딩 실패시 오류 표시
7.6 JWT가 비어 있는 경우 오류 메시지 표시
7.7 출력
8.0 사용자 계정 용 API 생성
8.1 사용자 계정 업데이트를 위한 파일 생성
8.2 JWT 디코딩을 위한 파일 포함
8.3 데이터베이스 및 사용자 테이블에 연결
8.4 주어진 JWT 검색
8.5 JWT가 있는 경우 디코딩
8.6 디코딩 실패시 오류 메시지 표시
8.7 사용자 속성 값 설정
8.8 update() 메서드 사용
8.9 사용자 클래스에 update() 메서드 추가
8.10 JWT 재생성
8.11 JWT가 비어있는 경우 오류 메시지 표시
8.12 출력
9.0 사용자 등록을 위한 인터페이스 생성
9.1 인덱스 페이지 생성
9.2 탐색 모음 추가
9.3 콘텐츠 섹션 추가
9.4 부트 스트랩 4 및 사용자 정의 CSS 링크 추가
9.5 사용자 지정 CSS 파일 만들기
9.6 jQuery 및 Bootstrap 4 스크립트 링크 추가
9.7 가입 HTML 양식 표시
9.8 가입 양식 제출시 트리거
9.9 프롬프트 메시지 제거
9.10 serializeObject() 함수 추가
9.11 출력
10.0 로그인 페이지 만들기
10.1 로그인 메뉴 클릭시 트리거
10.2 로그인 HTML 양식 표시
10.3 setCookie() 함수 추가
10.4 메뉴 모양 변경
10.5 출력
11.0 로그인 응답 표시
11.1 제출 된 양식 트리거
11.2 HTTP 요청 생성
11.3 홈 페이지 HTML 표시
11.4 홈 페이지 HTML 추가
11.5 getCookie() 함수 추가
11.6 유효하지 않은 로그인에 대한 오류 표시
11.7 출력
12.0 홈 메뉴 클릭시
12.1 홈 페이지를 표시하는 트리거 추가
12.2 로그인 메뉴 설정
12.3 JWT가 유효하지 않은 경우 로그인 페이지 표시
12.4 출력
13.0 사용자 계정 페이지 표시
13.1 계정 양식을 표시하는 트리거 추가
13.2 JWT가 유효한지 확인
13.3 JWT가 유효한 경우 계정 양식 표시
13.4 JWT가 유효하지 않은 경우 로그인 페이지 표시
13.5 사용자 계정 업데이트를 위한 트리거 추가
13.6 양식 데이터 및 JWT 가져 오기
13.7 API로 데이터 보내기
13.8 오류 메시지 표시
13.9 출력
14.0 사용자 로그 아웃을 위한 JavaScript 추가
14.1 로그 아웃에 트리거 추가
14.2 출력
15.0 소스 코드 다운로드
16.0 다음은?
17.0 관련 튜토리얼
18.0 참고
https://codeofaninja.com/2018/09/rest-api-authentication-example-php-jwt-tutorial.html
1.0 프로젝트 개요
1.1 JWT 란?
기술적인 측면에서 JSON 웹 토큰 또는 JWT는 당사자 간에 정보를 JSON 개체로 안전하게 전송하기 위한 컴팩트하고 독립적인 방법을 정의하는 개방형 표준 (RFC 7519)입니다.
이 정보는 디지털 서명이 되어 있으므로 확인하고 신뢰할 수 있습니다. JWT는 비밀 (HMAC 알고리즘 사용) 또는 RSA 또는 ECDSA를 사용하는 공개 / 개인 키 쌍을 사용하여 서명 할 수 있습니다.
1.2 JWT 간단한 비유
다음은 내 자신의 간단한 비유입니다. 더 나은 것이 있다고 생각되면 이메일로 알려주십시오. 제 이메일 주소는 mike@codeofaninja.com입니다.
당신에게 유용 할 수 있는 또 다른 비유를 찾았습니다. 여기에서 읽으십시오.
아래 비디오는 비유를 설명하는 데 도움이 될 것입니다.
1.3 JWT는 어떻게 생겼습니까?
JSON 웹 토큰 또는 JWT는 점으로 구분 된 세 부분이 있는 문자열처럼 보입니다. 다음은 JWT의 예입니다.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDAsImRhdGEiOnsiaWQiOiI5IiwiZmlyc3RuYW1lIjoiTWlrZSIsImxhc3RuYW1lIjoiRGFsaXNheSIsImVtYWlsIjoibWlrZUBjb2Rlb2ZhbmluamEuY29tIn19.h_Q4gJ3epcpwdwNCNCYxtiKdXsN34W9MEjxZ7sx21Vs |
직렬화 된 형식의 JWT는 다음 형식의 문자열을 나타냅니다.
header.payload.signature
헤더 구성 요소에는 JWT 서명을 계산하는 방법에 대한 정보가 포함되어 있습니다. 페이로드 구성 요소는 JWT 내부에 저장되는 데이터입니다. 이것은 사용자 ID, 이름 및 이메일과 같은 사용자 정보 일 수 있습니다.
서명 구성 요소를 생성하려면 인코딩 된 헤더, 인코딩 된 페이로드, 비밀, 헤더에 지정된 알고리즘을 가져 와서 서명해야 합니다.
이 튜토리얼에서는 PHP-JWT라는 라이브러리를 사용할 것이기 때문에 JWT 생성, 인코딩 및 디코딩에 대해 걱정할 필요가 없습니다.
1.4 JWT와 OAuth
위의 JWT를 설명했습니다. JWT는 토큰 형식이며 간단한 인증 프로토콜이라고 말할 수 있습니다. OAuth는 JWT를 토큰으로 사용할 수 있는 인증 프레임 워크입니다.
OAuth는 인터넷 사용자가 웹 사이트 또는 애플리케이션이 다른 웹 사이트의 정보에 액세스 할 수 있도록 허용하지만 비밀번호는 제공하지 않는 방법으로 사용됩니다.
다음과 같은 경우 JWT를 사용합니다.
다음과 같은 경우 OAuth를 사용합니다.
2.0 최종 출력
2.1 LEVEL 1 소스 코드 출력
이 튜토리얼에서 달성하고자 하는 것을 시각화 하는 것이 중요합니다. 이 튜토리얼이 끝나면 아래 스크린 샷에서 볼 수 있는 레벨 1 소스 코드를 얻을 수 있습니다.
확대하려면 아래 사진을 클릭하고 슬라이드 쇼를 탐색하려면 화살표 아이콘을 사용하십시오.
2.2 LEVEL 2 소스 코드 출력
곧 스크린 샷이 제공됩니다! 아래 섹션 14.2의 기능 목록을 참조하십시오.
LEVEL 2 소스 코드는 LEVEL 1 소스 코드 공부를 마치면 배울 수 있는 더 놀라운 기능을 보여줍니다.
지금은 아래의 LEVEL 1 소스 코드에 대한 전체 자습서를 진행하겠습니다. 코딩하자!
3.0 파일 구조
이 튜토리얼이 끝나면 다음과 같은 폴더와 파일을 갖게 됩니다.
├─ rest-api-authentication-example/ - name of the project folder.
├─── api/ - main folder of the API.
├────── config/
├───────── core.php - file used for common settings or variables.
├───────── database.php - file used for connecting to the database.
├────── libs/
├───────── php-jwt-master/ - folder of the JWT library developed by Google.
├────── objects/
├───────── user.php - the class file that will handle the database queries.
├────── create_user.php - the file that will process the input of from "sign up" form.
├────── login.php - the file that will encode and generate a JSON web token.
├────── update_user.php - the file that will process the input of from "user account" form.
├────── validate_token.php - the file that will validate or decode the JSON web token.
├─── custom.css - contains any customization in the user interface.
├─── index.html - contains HTML and JavaScript that renders different user interfaces.
4.0 데이터베이스 설정
4.1 데이터베이스 생성
4.2 테이블 생성
4.3 구성을 위한 디렉토리 생성
4.4 데이터베이스 연결 파일 만들기
다음 코드를 넣으십시오.
<?php // used to get mysql database connection class Database{ // specify your own database credentials private $host = "localhost" ; private $db_name = "api_db" ; private $username = "root" ; private $password = "" ; public $conn ; // get the database connection public function getConnection(){ $this ->conn = null; try { $this ->conn = new PDO( "mysql:host=" . $this ->host . ";dbname=" . $this ->db_name, $this ->username, $this ->password); } catch (PDOException $exception ){ echo "Connection error: " . $exception ->getMessage(); } return $this ->conn; } } ?> |
5.0 사용자 등록을 위한 API 생성
5.1 사용자 생성을 위한 파일 생성
이 새 파일에 특정 URL의 JSON 데이터 만 허용하도록 헤더를 설정해야 합니다. 다음 코드를 넣으십시오.
<?php // required headers header( "Content-Type: application/json; charset=UTF-8" ); header( "Access-Control-Allow-Methods: POST" ); header( "Access-Control-Max-Age: 3600" ); header( "Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" ); // database connection will be here |
5.2 데이터베이스 및 사용자 테이블에 연결
사용자 등록 정보를 데이터베이스에 저장하고 있으므로 데이터베이스 연결이 필요합니다. 나중에 insert 쿼리를 만들기 때문에 user 테이블도 인스턴스화해야합니다.
// 데이터베이스 연결은 다음 코드로 create_user.php 파일의 주석입니다.
// files needed to connect to database
include_once
'config/database.php'
;
include_once
'objects/user.php'
;
// get database connection
$database
=
new
Database();
$db
=
$database
->getConnection();
// instantiate product object
$user
=
new
User(
$db
);
// submitted data will be here
5.3 제출 된 데이터를 개체 속성에 할당
사용자 정보는 HTML 양식과 JavaScript 코드를 통해 제출됩니다. 이 코드는 나중에 볼 것입니다.
제출 된 데이터를 이름, 성 등과 같은 개체 속성에 할당해야 합니다.
// 제출 된 데이터는 여기에서 create_user.php 파일의 주석이 다음 코드로 바뀝니다.
// get posted data
$data
= json_decode(
file_get_contents
(
"php://input"
));
// set product property values
$user
->firstname =
$data
->firstname;
$user
->lastname =
$data
->lastname;
$user
->email =
$data
->email;
$user
->password =
$data
->password;
// use the create() method here
5.4 create() 메서드 사용
아래 코드 중 하나는 사용자 데이터가 비어 있지 않은지 확인합니다. 또한 사용자 개체의 create() 메서드를 사용합니다. 사용자가 생성되었는지 여부를 사용자에게 알려줍니다.
// 여기서 create_user.php 파일의 create() 메서드를 다음 코드로 바꿉니다.
// create the user
if
(
!
empty
(
$user
->firstname) &&
!
empty
(
$user
->email) &&
!
empty
(
$user
->password) &&
$user
->create()
){
// set response code
http_response_code(200);
// display message: user was created
echo
json_encode(
array
(
"message"
=>
"User was created."
));
}
// message if unable to create user
else
{
// set response code
http_response_code(400);
// display message: unable to create user
echo
json_encode(
array
(
"message"
=>
"Unable to create user."
));
}
?>
5.5 사용자 개체 클래스 만들기
이전 섹션은 사용자 개체 클래스 없이는 작동하지 않습니다. 여기에서 데이터베이스 쿼리를 포함하는 모든 user 메서드를 배치합니다.
개인 또는 공용 범위에 익숙하지 않은 경우 이 리소스에서 배우십시오.
<?php
// 'user' object
class
User{
// database connection and table name
private
$conn
;
private
$table_name
=
"users"
;
// object properties
public
$id
;
public
$firstname
;
public
$lastname
;
public
$email
;
public
$password
;
// constructor
public
function
__construct(
$db
){
$this
->conn =
$db
;
}
// create() method will be here
}
5.6 create() 메서드 추가
아래 코드는 INSERT 쿼리, 데이터 위생 및 바인딩을 보여 주며, 데이터베이스에서 사용자의 암호를 보호하기 위해 내장 된 password_hash() 메서드를 사용했습니다.
실행이 성공하면 사용자 정보가 데이터베이스에 저장됩니다.
// create() 메서드를 user.php 파일의 주석으로 대체합니다.
// create new user record function create(){ // insert query $query = "INSERT INTO " . $this ->table_name . " SET firstname = :firstname, lastname = :lastname, email = :email, password = :password"; // prepare the query $stmt = $this ->conn->prepare( $query ); // sanitize $this ->firstname=htmlspecialchars( strip_tags ( $this ->firstname)); $this ->lastname=htmlspecialchars( strip_tags ( $this ->lastname)); $this ->email=htmlspecialchars( strip_tags ( $this ->email)); $this ->password=htmlspecialchars( strip_tags ( $this ->password)); // bind the values $stmt ->bindParam( ':firstname' , $this ->firstname); $stmt ->bindParam( ':lastname' , $this ->lastname); $stmt ->bindParam( ':email' , $this ->email); // hash the password before saving to database $password_hash = password_hash( $this ->password, PASSWORD_BCRYPT); $stmt ->bindParam( ':password' , $password_hash ); // execute the query, also check if query was successful if ( $stmt ->execute()){ return true; } return false; } // emailExists() method will be here |
5.7 출력
API를 테스트하려면 POSTMAN을 사용해야 합니다. 여기에서 POSTMAN 버전을 다운로드하십시오.
{ "firstname" : "Mike" , "lastname" : "Dalisay" , "email" : "mike@codeofaninja.com" , "password" : "555" } |
{ "message" : "User was created." } |
6.0 사용자 로그인을 위한 API 생성
6.1 사용자 로그인을 위한 파일 생성
아래 코드에서 요청이 어디에서 왔는지, 어떤 유형의 데이터가 허용되는지 알 수 있도록 파일 헤더를 설정했습니다.
<?php // required headers header( "Content-Type: application/json; charset=UTF-8" ); header( "Access-Control-Allow-Methods: POST" ); header( "Access-Control-Max-Age: 3600" ); header( "Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With" ); // database connection will be here |
6.2 데이터베이스 및 사용자 테이블에 연결
데이터베이스의 사용자 이메일과 비밀번호를 비교하므로 데이터베이스 연결이 필요합니다.
이메일이 존재하는지 확인하고 해시 된 암호를 읽을 수 있도록 사용자 테이블도 인스턴스화해야합니다.
// 데이터베이스 연결은 여기에 login.php 파일의 주석이 다음 코드로 바뀝니다.
// files needed to connect to database
include_once
'config/database.php'
;
include_once
'objects/user.php'
;
// get database connection
$database
=
new
Database();
$db
=
$database
->getConnection();
// instantiate user object
$user
=
new
User(
$db
);
// check email existence here
6.3 이메일 존재 여부 확인
아래 코드에서 사용자가 로그인 양식을 통해 제출 한 이메일을 받습니다. 이메일이 데이터베이스에 있는지 확인합니다.
// login.php 파일의 이메일 존재 확인 주석을 다음 코드로 바꿉니다.
// get posted data $data = json_decode( file_get_contents ( "php://input" )); // set product property values $user ->email = $data ->email; $email_exists = $user ->emailExists(); // files for jwt will be here |
6.4 emailExists() 메서드 추가
사용자 객체 클래스에 emailExists() 메서드를 추가합니다. 이 메서드는 제출 된 이메일이 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.
// emailExists() 메서드를 다음 코드로 /api/objects/user.php 파일의 주석으로 대체합니다.
// check if given email exist in the database
function
emailExists(){
// query to check if email exists
$query
= "SELECT id, firstname, lastname, password
FROM
" . $this->table_name . "
WHERE email = ?
LIMIT 0,1";
// prepare the query
$stmt
=
$this
->conn->prepare(
$query
);
// sanitize
$this
->email=htmlspecialchars(
strip_tags
(
$this
->email));
// bind given email value
$stmt
->bindParam(1,
$this
->email);
// execute the query
$stmt
->execute();
// get number of rows
$num
=
$stmt
->rowCount();
// if email exists, assign values to object properties for easy access and use for php sessions
if
(
$num
>0){
// get record details / values
$row
=
$stmt
->fetch(PDO::FETCH_ASSOC);
// assign values to object properties
$this
->id =
$row
[
'id'
];
$this
->firstname =
$row
[
'firstname'
];
$this
->lastname =
$row
[
'lastname'
];
$this
->password =
$row
[
'password'
];
// return true because email exists in the database
return
true;
}
// return false if email does not exist in the database
return
false;
}
// update() method will be here
6.5 JWT 인코딩을 위한 파일 포함
아래 코드는 JSON 웹 토큰을 생성하거나 인코딩하기 위해 포함해야 하는 필수 파일을 보여줍니다.
// 파일을 jwt로 바꾸면 여기에 login.php 파일의 주석이 다음 코드로 표시됩니다.
// generate json web token
include_once
'config/core.php'
;
include_once
'libs/php-jwt-master/src/BeforeValidException.php'
;
include_once
'libs/php-jwt-master/src/ExpiredException.php'
;
include_once
'libs/php-jwt-master/src/SignatureInvalidException.php'
;
include_once
'libs/php-jwt-master/src/JWT.php'
;
use
\Firebase\JWT\JWT;
// generate jwt will be here
6.6 JSON 웹 토큰 생성
아래 코드는 이메일이 존재하는지 그리고 암호가 데이터베이스에 있는 것과 일치하는지 확인합니다. 내장 된 password_verify () 함수를 사용하여 일치를 수행했습니다.
로그인이 유효하면 JSON 웹 토큰을 생성합니다.
// generate jwt는 login.php 파일의 주석이 다음 코드로 대체됩니다.
// check if email exists and if password is correct
if
(
$email_exists
&& password_verify(
$data
->password,
$user
->password)){
$token
=
array
(
"iat"
=>
$issued_at
,
"exp"
=>
$expiration_time
,
"iss"
=>
$issuer
,
"data"
=>
array
(
"id"
=>
$user
->id,
"firstname"
=>
$user
->firstname,
"lastname"
=>
$user
->lastname,
"email"
=>
$user
->email
)
);
// set response code
http_response_code(200);
// generate jwt
$jwt
= JWT::encode(
$token
,
$key
);
echo
json_encode(
array
(
"message"
=>
"Successful login."
,
"jwt"
=>
$jwt
)
);
}
// login failed will be here
6.7 사용자 로그인 실패 알림
이메일이 존재하지 않거나 비밀번호가 일치하지 않으면 사용자에게 로그인 할 수 없다고 알립니다.
// 로그인 실패는 다음 코드로 login.php 파일의 주석입니다.
// login failed
else
{
// set response code
http_response_code(401);
// tell the user login failed
echo
json_encode(
array
(
"message"
=>
"Login failed."
));
}
?>
6.8 핵심 구성 파일 생성
login.php 파일은 core.php 파일 없이는 작동하지 않습니다. 이 파일에는 애플리케이션의 공통 설정 또는 변수가 포함되어 있습니다.
토큰을 인코딩하고 디코딩 하기 위해 JWT 라이브러리에서 사용하는 변수가 있습니다. $key의 값은 고유하고 고유 한 비밀 키 여야 합니다.
나머지는 등록 된 클레임 이름이라고 합니다. iss (발급자) 클레임은 JWT를 발행 한 주체를 식별합니다.
aud (audience) 클레임은 JWT가 대상으로 하는 수신자를 식별합니다. iat (issued at) 클레임은 JWT가 발행 된 시간을 식별합니다.
nbf (이전 아님) 클레임은 JWT가 처리를 위해 허용되지 않아야 하는 시간을 식별합니다.
JWT가 처리를 위해 허용되지 않아야 하는 만료 시간 또는 그 이후의 만료 시간을 식별하는 exp (만료 시간)라는 또 다른 유용한 클레임 이름을 사용할 수 있습니다.
이러한 클레임을 포함하는 것은 선택 사항입니다. 여기에서 등록 된 클레임 이름에 대해 자세히 읽어보십시오.
<?php
// show error reporting
error_reporting
(E_ALL);
// set your default time-zone
date_default_timezone_set(
'Asia/Manila'
);
// variables used for jwt
$key
=
"example_key"
;
$issued_at
= time();
$expiration_time
=
$issued_at
+ (60 * 60);
// valid for 1 hour
?>
6.9 GitHub에서 PHP-JWT 다운로드
login.php 파일에 포함 된 파일은 이 라이브러리 없이는 작동하지 않습니다.
6.10 출력
성공적인 로그인을 테스트하려면 요청 URL로 다음을 입력하십시오.
{
"email"
:
"mike@codeofaninja.com"
,
"password"
:
"555"
}
7.0 JWT 유효성 검사를 위한 API 생성
7.1 JWT 유효성 검사를 위한 파일 생성
이 파일은 JSON 형식으로 출력을 반환하고 지정된 URL의 요청을 수락합니다. 올바른 헤더를 설정하겠습니다.
<?php
// required headers
header(
"Content-Type: application/json; charset=UTF-8"
);
header(
"Access-Control-Allow-Methods: POST"
);
header(
"Access-Control-Max-Age: 3600"
);
header(
"Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
);
// files for decoding jwt will be here
7.2 JWT 디코딩을 위한 파일 포함
아래 코드는 주어진 JSON 웹 토큰을 디코딩 하는 데 필요한 파일이 포함되어 있음을 보여줍니다.
// jwt 디코딩을 위한 파일을 다음 코드로 validate_token.php 파일의 주석으로 교체합니다.
// required to decode jwt
include_once
'config/core.php'
;
include_once
'libs/php-jwt-master/src/BeforeValidException.php'
;
include_once
'libs/php-jwt-master/src/ExpiredException.php'
;
include_once
'libs/php-jwt-master/src/SignatureInvalidException.php'
;
include_once
'libs/php-jwt-master/src/JWT.php'
;
use
\Firebase\JWT\JWT;
// retrieve gieve jwt here
7.3 주어진 JWT 검색
아래 코드는 JSON 웹 토큰의 값을 가져 오는 방법을 보여줍니다.
// validate_token.php 파일의 gieve jwt 주석을 다음 코드로 바꿉니다.
// get posted data
$data
= json_decode(
file_get_contents
(
"php://input"
));
// get jwt
$jwt
=isset(
$data
->jwt) ?
$data
->jwt :
""
;
// decode jwt here
7.4 존재하는 경우 JWT 디코딩
JWT가 주어 졌는지 확인하십시오. 참이면 디코딩 하십시오. 응답 코드 200을 반환하고 사용자 액세스가 허용되고 일부 사용자 정보를 알립니다.
// validate_token.php 파일의 jwt 디코딩 주석을 다음 코드로 바꿉니다.
// if jwt is not empty
if
(
$jwt
){
// if decode succeed, show user details
try
{
// decode jwt
$decoded
= JWT::decode(
$jwt
,
$key
,
array
(
'HS256'
));
// set response code
http_response_code(200);
// show user details
echo
json_encode(
array
(
"message"
=>
"Access granted."
,
"data"
=>
$decoded
->data
));
}
// catch will be here
}
// error if jwt is empty will be here
7.5 디코딩 실패시 오류 표시
JWT 디코딩에 실패하면 리소스에 대한 액세스가 거부되었음을 의미합니다. 응답 코드 401을 반환하고 사용자 액세스가 거부되었으며 오류에 대한 일부 정보를 알려야 합니다.
// catch는 validate_token.php 파일의 주석을 다음 코드로 교체합니다.
// if decode fails, it means jwt is invalid catch (Exception $e ){ // set response code http_response_code(401); // tell the user access denied & show error message echo json_encode( array ( "message" => "Access denied." , "error" => $e ->getMessage() )); } |
7.6 JWT가 비어있는 경우 오류 메시지 표시
JWT가 비어 있으면 액세스도 거부되었음을 의미합니다. 응답 코드 401을 반환하고 사용자 액세스가 거부되었음을 알려야 합니다.
// jwt가 비어있는 경우 오류를 교체하면 validate_token.php 파일의 주석이 다음 코드로 표시됩니다.
// show error message if jwt is empty
else
{
// set response code
http_response_code(401);
// tell the user access denied
echo
json_encode(
array
(
"message"
=>
"Access denied."
));
}
?>
7.7 출력
{
"jwt"
:
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDAsImRhdGEiOnsiaWQiOiI5IiwiZmlyc3RuYW1lIjoiTWlrZSIsImxhc3RuYW1lIjoiRGFsaXNheSIsImVtYWlsIjoibWlrZUBjb2Rlb2ZhbmluamEuY29tIn19.h_Q4gJ3epcpwdwNCNCYxtiKdXsN34W9MEjxZ7sx21Vs"
}
8.0 사용자 계정을 위한 API 생성
8.1 사용자 계정 업데이트를 위한 파일 생성
이 파일은 JSON 형식으로 출력을 반환하고 지정된 URL의 요청을 수락합니다. 올바른 헤더를 설정하겠습니다.
<?php
// required headers
header(
"Access-Control-Allow-Origin: *"
);
header(
"Content-Type: application/json; charset=UTF-8"
);
header(
"Access-Control-Allow-Methods: POST"
);
header(
"Access-Control-Max-Age: 3600"
);
header(
"Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
);
// files for decoding jwt will be here
8.2 JWT 디코딩을 위한 파일 포함
아래 코드는 주어진 JSON 웹 토큰을 디코딩 하는 데 필요한 파일이 포함되어 있음을 보여줍니다.
// jwt 디코딩을 위한 파일을 다음 코드로 update_user.php 파일의 주석으로 대체합니다.
// required to encode json web token
include_once
'config/core.php'
;
include_once
'libs/php-jwt-master/src/BeforeValidException.php'
;
include_once
'libs/php-jwt-master/src/ExpiredException.php'
;
include_once
'libs/php-jwt-master/src/SignatureInvalidException.php'
;
include_once
'libs/php-jwt-master/src/JWT.php'
;
use
\Firebase\JWT\JWT;
// database connection will be here
8.3 데이터베이스 및 사용자 테이블에 연결
데이터베이스에서 사용자 정보를 업데이트해야 합니다. 그렇기 때문에 데이터베이스 연결이 필요합니다.
// 데이터베이스 연결은 다음 코드로 update_user.php 파일의 주석입니다.
// files needed to connect to database
include_once
'config/database.php'
;
include_once
'objects/user.php'
;
// get database connection
$database
=
new
Database();
$db
=
$database
->getConnection();
// instantiate user object
$user
=
new
User(
$db
);
// retrieve given jwt here
8.4 주어진 JWT 검색
아래 코드는 주어진 JSON 웹 토큰의 값을 얻는 방법을 보여줍니다.
// update_user.php 파일의 jwt 주석을 다음 코드로 교체하십시오.
// get posted data
$data
= json_decode(
file_get_contents
(
"php://input"
));
// get jwt
$jwt
=isset(
$data
->jwt) ?
$data
->jwt :
""
;
// decode jwt here
8.5 JWT가 있는 경우 디코딩
JWT가 주어 졌는지 확인하십시오. 참이면 try 블록 내에서 디코딩 합니다.
// decode jwt here update_user.php 파일의 주석을 다음 코드로 바꿉니다.
// if jwt is not empty
if
(
$jwt
){
// if decode succeed, show user details
try
{
// decode jwt
$decoded
= JWT::decode(
$jwt
,
$key
,
array
(
'HS256'
));
// set user property values here
}
// catch failed decoding will be here
}
// error message if jwt is empty will be here
8.6 디코딩 실패시 오류 메시지 표시
JWT 디코딩이 실패하면 응답 코드 401을 설정하고 사용자 액세스가 거부되었음을 알리고 오류에 대한 정보를 표시해야 합니다.
// catch 실패 디코딩은 다음 코드로 update_user.php 파일의 주석입니다.
// if decode fails, it means jwt is invalid
catch
(Exception
$e
){
// set response code
http_response_code(401);
// show error message
echo
json_encode(
array
(
"message"
=>
"Access denied."
,
"error"
=>
$e
->getMessage()
));
}
8.7 사용자 속성 값 설정
제출 된 데이터 (HTML 양식을 통해)를 사용자 개체 속성으로 설정해야 합니다.
update_user.php 파일의 주석 // set user property values here을 다음 코드로 바꿉니다.
// set user property values $user ->firstname = $data ->firstname; $user ->lastname = $data ->lastname; $user ->email = $data ->email; $user ->password = $data ->password; $user ->id = $decoded ->data->id; // update user will be here |
8.8 update() 메서드 사용
아래 코드 중 하나는 사용자 객체의 create() 메서드를 사용합니다. true를 반환하면 사용자가 업데이트 되었음을 의미합니다. false를 반환하면 시스템이 사용자 정보를 업데이트 할 수 없습니다.
// update user는 update_user.php 파일의 주석이 다음 코드로 대체됩니다.
// update the user record if ( $user ->update()){ // regenerate jwt will be here } // message if unable to update user else { // set response code http_response_code(401); // show error message echo json_encode( array ( "message" => "Unable to update user." )); } |
8.9 사용자 클래스에 update() 메서드 추가
아래 코드는 UPDATE 쿼리, 데이터 위생 및 바인딩을 보여줍니다.
HTML 형식으로 암호를 입력 한 경우 내장 된 password_hash() 메서드를 사용하여 데이터베이스에서 사용자의 암호를 보호합니다.
실행이 성공하면 데이터베이스에서 사용자 정보가 업데이트 됩니다.
// update() 메서드를 api / objects / user.php 파일의 주석으로 대체합니다.
// update a user record
public
function
update(){
// if password needs to be updated
$password_set
=!
empty
(
$this
->password) ?
", password = :password"
:
""
;
// if no posted password, do not update the password
$query
=
"UPDATE "
.
$this
->table_name . "
SET
firstname = :firstname,
lastname = :lastname,
email = :email
{
$password_set
}
WHERE id = :id";
// prepare the query
$stmt
=
$this
->conn->prepare(
$query
);
// sanitize
$this
->firstname=htmlspecialchars(
strip_tags
(
$this
->firstname));
$this
->lastname=htmlspecialchars(
strip_tags
(
$this
->lastname));
$this
->email=htmlspecialchars(
strip_tags
(
$this
->email));
// bind the values from the form
$stmt
->bindParam(
':firstname'
,
$this
->firstname);
$stmt
->bindParam(
':lastname'
,
$this
->lastname);
$stmt
->bindParam(
':email'
,
$this
->email);
// hash the password before saving to database
if
(!
empty
(
$this
->password)){
$this
->password=htmlspecialchars(
strip_tags
(
$this
->password));
$password_hash
= password_hash(
$this
->password, PASSWORD_BCRYPT);
$stmt
->bindParam(
':password'
,
$password_hash
);
}
// unique ID of record to be edited
$stmt
->bindParam(
':id'
,
$this
->id);
// execute the query
if
(
$stmt
->execute()){
return
true;
}
return
false;
}
8.10 JWT 재생성
특히 사용자 정보가 변경된 경우 새 JSON 웹 토큰을 다시 생성하거나 가져와야 합니다. 아래 코드는 이를 수행하고 응답 코드를 200으로 설정하고 사용자에게 정보가 업데이트 되었음을 알려줍니다.
// regenerate jwt는 update_user.php 파일의 주석이 다음 코드로 대체됩니다.
// we need to re-generate jwt because user details might be different $token = array ( "iat" => $issued_at , "exp" => $expiration_time , "iss" => $issuer , "data" => array ( "id" => $user ->id, "firstname" => $user ->firstname, "lastname" => $user ->lastname, "email" => $user ->email ) ); $jwt = JWT::encode( $token , $key ); // set response code http_response_code(200); // response in json format echo json_encode( array ( "message" => "User was updated." , "jwt" => $jwt ) ); |
8.11 JWT가 비어있는 경우 오류 메시지 표시
JWT가 존재하지 않으면 액세스가 거부되었음을 사용자에게 알려야 합니다. 응답 코드 401도 설정했습니다.
JWT가 비어 있으면 // 오류 메시지를 다음 코드로 update_user.php 파일의 주석으로 대체합니다.
// show error message if jwt is empty
else
{
// set response code
http_response_code(401);
// tell the user access denied
echo
json_encode(
array
(
"message"
=>
"Access denied."
));
}
?>
8.12 출력
{
"firstname"
:
"Mike"
,
"lastname"
:
"Dalisay"
,
"email"
:
"mike@codeofaninja.com"
,
"password"
:
"555"
,
"jwt"
:
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImF1ZCI6Imh0dHA6XC9cL2V4YW1wbGUuY29tIiwiaWF0IjoxMzU2OTk5NTI0LCJuYmYiOjEzNTcwMDAwMDAsImRhdGEiOnsiaWQiOiI5IiwiZmlyc3RuYW1lIjoiVmluY2UiLCJsYXN0bmFtZSI6IkRhbGlzYXkiLCJlbWFpbCI6Im1pa2VAY29kZW9mYW5pbmphLmNvbSJ9fQ.3Sv65TVYACkNPo4HMr4NvreyZY16wxG-nSorLi_jykI"
}
9.0 사용자 등록을 위한 인터페이스 생성
9.1 인덱스 페이지 생성
HTML, CSS 및 JavaScript를 사용하여 만든 간단한 SPA (단일 페이지 응용 프로그램)에서 앞서 만든 API를 사용합니다.
모든 필수 코드는 이 단일 index.html 파일에 있습니다.
<! doctype html> < html lang = "en" > < head > <!-- Required meta tags --> < meta charset = "utf-8" /> < meta name = "viewport" content = "width=device-width, initial-scale=1, shrink-to-fit=no" /> < title >Rest API Authentication Example</ title > <!-- CSS links will be here --> </ head > < body > <!-- navigation bar will be here --> <!-- script links will be here --> </ body > </ html > |
9.2 탐색 모음(navigation bar) 추가
내비게이션 바는 홈 페이지, 계정 페이지, 로그인 페이지, 로그 아웃 및 가입 페이지와 같은 메뉴를 클릭하거나 트리거 할 수 있는 곳입니다.
index.html 파일의 <!-탐색 모음이 여기에 있습니다-> 주석을 다음 코드로 바꿉니다.
<!-- navbar -->
<
nav
class
=
"navbar navbar-expand-md navbar-dark bg-dark fixed-top"
>
<
a
class
=
"navbar-brand"
href
=
"#"
>Navbar</
a
>
<
button
class
=
"navbar-toggler"
type
=
"button"
data-toggle
=
"collapse"
data-target
=
"#navbarNavAltMarkup"
aria-controls
=
"navbarNavAltMarkup"
aria-expanded
=
"false"
aria-label
=
"Toggle navigation"
>
<
span
class
=
"navbar-toggler-icon"
></
span
>
</
button
>
<
div
class
=
"collapse navbar-collapse"
id
=
"navbarNavAltMarkup"
>
<
div
class
=
"navbar-nav"
>
<
a
class
=
"nav-item nav-link"
href
=
"#"
id
=
'home'
>Home</
a
>
<
a
class
=
"nav-item nav-link"
href
=
"#"
id
=
'update_account'
>Account</
a
>
<
a
class
=
"nav-item nav-link"
href
=
"#"
id
=
'logout'
>Logout</
a
>
<
a
class
=
"nav-item nav-link"
href
=
"#"
id
=
'login'
>Login</
a
>
<
a
class
=
"nav-item nav-link"
href
=
"#"
id
=
'sign_up'
>Sign Up</
a
>
</
div
>
</
div
>
</
nav
>
<!-- /navbar -->
<!-- content section will be here -->
9.3 콘텐츠 섹션 추가
콘텐츠 섹션은 HTML 양식 및 메시지 프롬프트와 같은 콘텐츠가 렌더링 되는 곳입니다.
index.html 파일의 <!-content section will be here-> 주석을 다음 코드로 바꿉니다.
<!-- container --> < main role = "main" class = "container starter-template" > < div class = "row" > < div class = "col" > <!-- where prompt / messages will appear --> < div id = "response" ></ div > <!-- where main content will appear --> < div id = "content" ></ div > </ div > </ div > </ main > <!-- /container --> |
9.4 부트 스트랩 4 및 사용자 지정 CSS 링크 추가
우리는 사용자 인터페이스를 보기 좋게 만들기 위해 Bootstrap 4를 사용하고 있습니다. 전체 라이브러리를 다운로드 할 필요가 없도록 CDN 링크를 사용할 것입니다.
다음 섹션에서 사용자 정의 CSS 파일 사용을 살펴 보겠습니다.
index.html 파일의 <!-CSS 링크는 여기에 있습니다-> 주석을 다음 코드로 바꿉니다.
<!-- Bootstrap 4 CSS and custom CSS -->
<
link
rel
=
"stylesheet"
href
=
"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity
=
"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin
=
"anonymous"
/>
<
link
rel
=
"stylesheet"
type
=
"text/css"
href
=
"custom.css"
/>
9.5 사용자 지정 CSS 파일 만들기
우리는 구현하려는 모든 모양 및 느낌 사용자 정의에 사용자 정의 CSS를 사용합니다.
body { padding-top : 5 rem; } .starter-template { padding : 3 rem 1.5 rem; } #logout{ display : none ; } |
9.6 jQuery 및 Bootstrap 4 스크립트 링크 추가
이 튜토리얼에서는 jQuery 라이브러리를 사용하여 인터페이스를 렌더링하고 HTTP 요청을 작성합니다.
Bootstrap 4가 작동하도록 하려면 자체 JavaScript도 포함해야 합니다.
index.html 파일의 <!-script links will be here-> 주석을 다음 코드로 바꿉니다.
<!-- jQuery & Bootstrap 4 JavaScript libraries -->
<
script
src
=
"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity
=
"sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin
=
"anonymous"
></
script
>
<
script
src
=
"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity
=
"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin
=
"anonymous"
></
script
>
<!-- jquery scripts will be here -->
9.7 가입 HTML 양식 표시
내비게이션 바에서 가입 메뉴를 클릭하면 가입 또는 등록 양식이 표시됩니다.
아래 코드는 클릭 트리거와 HTML 양식을 보여줍니다.
index.html 파일의 <!-jquery 스크립트가 여기에 있습니다-> 주석을 다음 코드로 바꿉니다.
<script> // jQuery codes $(document).ready( function (){ // show sign up / registration form $(document).on( 'click' , '#sign_up' , function (){ var html = ` <h2>Sign Up</h2> <form id= 'sign_up_form' > <div class = "form-group" > <label for = "firstname" >Firstname</label> <input type= "text" class = "form-control" name= "firstname" id= "firstname" required /> </div> <div class = "form-group" > <label for = "lastname" >Lastname</label> <input type= "text" class = "form-control" name= "lastname" id= "lastname" required /> </div> <div class = "form-group" > <label for = "email" >Email</label> <input type= "email" class = "form-control" name= "email" id= "email" required /> </div> <div class = "form-group" > <label for = "password" >Password</label> <input type= "password" class = "form-control" name= "password" id= "password" required /> </div> <button type= 'submit' class = 'btn btn-primary' >Sign Up</button> </form> `; clearResponse(); $( '#content' ).html(html); }); // trigger when registration form is submitted here // show login form trigger will be here // clearResponse() will be here }); </script> |
9.8 가입 양식 제출시 트리거
제출할 때 양식 데이터를 처리해야 합니다.
여기에 index.html 파일의 주석 등록 양식이 제출되면 트리거를 다음 코드로 교체하십시오.
// trigger when registration form is submitted
$(document).on(
'submit'
,
'#sign_up_form'
,
function
(){
// get form data
var
sign_up_form=$(
this
);
var
form_data=JSON.stringify(sign_up_form.serializeObject());
// submit form data to api
$.ajax({
url:
"api/create_user.php"
,
type :
"POST"
,
contentType :
'application/json'
,
data : form_data,
success :
function
(result) {
// if response is a success, tell the user it was a successful sign up & empty the input boxes
$(
'#response'
).html(
"<div class='alert alert-success'>Successful sign up. Please login.</div>"
);
sign_up_form.find(
'input'
).val(
''
);
},
error:
function
(xhr, resp, text){
// on error, tell the user sign up failed
$(
'#response'
).html(
"<div class='alert alert-danger'>Unable to sign up. Please contact admin.</div>"
);
}
});
return
false
;
});
9.9 프롬프트 메시지 제거
clearResponse() 메서드는 이전 섹션에서 사용되었습니다. 유일한 목적은 화면에 표시되었을 수 있는 모든 프롬프트 메시지를 제거하는 것입니다.
// clearResponse()는 index.html 파일의 주석이 될 것입니다. 다음 코드로 대체하십시오.
// remove any prompt messages function clearResponse(){ $( '#response' ).html( '' ); } // showLoginPage() will be here // serializeObject will be here |
9.10 serializeObject 함수 추가
serializeObject 함수는 양식 데이터를 JSON 형식으로 변환합니다. HTML 양식에서 API로 값을 보내려면 이 함수가 필요합니다.
// serializeObject는 index.html 파일의 주석이 될 것입니다. 다음 코드로 대체하십시오.
// function to make form values to json format
$.fn.serializeObject =
function
(){
var
o = {};
var
a =
this
.serializeArray();
$.each(a,
function
() {
if
(o[
this
.name] !== undefined) {
if
(!o[
this
.name].push) {
o[
this
.name] = [o[
this
.name]];
}
o[
this
.name].push(
this
.value ||
''
);
}
else
{
o[
this
.name] =
this
.value ||
''
;
}
});
return
o;
};
9.11 출력
사용자가 탐색 모음에서 가입 링크를 클릭 할 때.
사용자가 양식을 작성하고 제출 한 후.
10.0 로그인 페이지 만들기
10.1 로그인 메뉴 클릭시 트리거
내비게이션 바에서 로그인 메뉴를 클릭하면 로그인 양식이 표시됩니다.
아래 코드는 클릭 트리거와 showLoginPage(); 로그인 양식을 표시하는 함수.
// show login form trigger는 여기에 index.html 파일의 주석이 될 것임을 다음 코드로 바꿉니다.
// show login form
$(document).on(
'click'
,
'#login'
,
function
(){
showLoginPage();
});
// login form submit trigger will be here
10.2 로그인 HTML 양식 표시
아래 함수는 사용자가 로그인 할 수 있는 HTML 양식을 보여줍니다.
// showLoginPage()는 index.html 파일의 주석이 될 것임을 다음 코드로 바꿉니다.
// show login page
function
showLoginPage(){
// remove jwt
setCookie(
"jwt"
,
""
, 1);
// login page html
var
html = `
<h2>Login</h2>
<form id=
'login_form'
>
<div
class
=
'form-group'
>
<label
for
=
'email'
>Email address</label>
<input type=
'email'
class
=
'form-control'
id=
'email'
name=
'email'
placeholder=
'Enter email'
>
</div>
<div
class
=
'form-group'
>
<label
for
=
'password'
>Password</label>
<input type=
'password'
class
=
'form-control'
id=
'password'
name=
'password'
placeholder=
'Password'
>
</div>
<button type=
'submit'
class
=
'btn btn-primary'
>Login</button>
</form>
`;
$(
'#content'
).html(html);
clearResponse();
showLoggedOutMenu();
}
// setCookie() will be here
// showLoggedOutMenu() will be here
10.3 setCookie() 함수 추가
setCookie() 함수는 쿠키에 JWT를 저장하는 데 도움이 됩니다.
// setCookie()는 index.html 파일의 주석이 될 것입니다. 다음 코드로 대체하십시오.
// function to set cookie
function
setCookie(cname, cvalue, exdays) {
var
d =
new
Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var
expires =
"expires="
+ d.toUTCString();
document.cookie = cname +
"="
+ cvalue +
";"
+ expires +
";path=/"
;
}
10.4 메뉴 모양 변경
showLoggedOutMenu() 함수는 이전 섹션에서 사용되었습니다.
이 함수는 메뉴가 로그아웃한 사용자를 위한 옵션처럼 보이게 합니다.
// showLoggedOutMenu()는 index.html 파일의 주석이 여기에 다음 코드로 바뀝니다.
// if the user is logged out
function
showLoggedOutMenu(){
// show login and sign up from navbar & hide logout button
$(
"#login, #sign_up"
).show();
$(
"#logout"
).hide();
}
// showHomePage() function will be here
10.5 출력
11.0 로그인 응답 표시
11.1 제출 된 양식 트리거
아래 코드는 로그인 양식에 대한 제출 트리거를 보여줍니다.
양식에서 데이터를 가져 와서 form_data 변수에 저장합니다.
// 로그인 양식 제출 트리거는 index.html 파일의 주석이 될 것입니다. 다음 코드로 바꿉니다.
// trigger when login form is submitted
$(document).on(
'submit'
,
'#login_form'
,
function
(){
// get form data
var
login_form=$(
this
);
var
form_data=JSON.stringify(login_form.serializeObject());
// http request will be here
return
false
;
});
// trigger to show home page will be here
11.2 HTTP 요청 생성
아래 코드는 HTTP 요청, 특히 제출 된 이메일과 비밀번호가 유효한지 확인하기 위한 AJAX 요청을 만드는 방법을 보여줍니다.
유효하면 JWT를 localStorage에 저장하고 홈 페이지를 표시하고 사용자에게 로그인 성공을 알립니다.
// http 요청이 여기에 있는 index.html 파일의 주석을 다음 코드로 바꿉니다.
// submit form data to api
$.ajax({
url:
"api/login.php"
,
type :
"POST"
,
contentType :
'application/json'
,
data : form_data,
success :
function
(result){
// store jwt to cookie
setCookie(
"jwt"
, result.jwt, 1);
// show home page & tell the user it was a successful login
showHomePage();
$(
'#response'
).html(
"<div class='alert alert-success'>Successful login.</div>"
);
},
// error response will be here
});
11.3 홈 페이지 HTML 표시
showHomePage() 함수에서 홈 페이지 HTML을 표시하기 전에 저장된 JWT의 유효성을 검사해야 합니다.
// showHomePage() 함수는 index.html 파일의 주석이 됩니다. 다음 코드로 대체합니다.
// show home page function showHomePage(){ // validate jwt to verify access var jwt = getCookie( 'jwt' ); $.post( "api/validate_token.php" , JSON.stringify({ jwt:jwt })).done( function (result) { // home page html will be here }) // show login page on error will be here } // getCookie() will be here // showLoggedInMenu() will be here |
11.4 홈 페이지 HTML 추가
JWT가 유효하면 홈 페이지 HTML을 표시하고 showLoggedInMenu() 함수를 호출합니다.
// home page html will be here 주석 index.html 파일을 다음 코드로 대체합니다.
// if valid, show homepage var html = ` <div class = "card" > <div class = "card-header" >Welcome to Home!</div> <div class = "card-body" > <h5 class = "card-title" >You are logged in .</h5> <p class = "card-text" >You won 't be able to access the home and account pages if you are not logged in.</p> </div> </div> `; $(' #content').html(html); showLoggedInMenu(); |
11.5 getCookie() 함수 추가
getCookie() 함수는 이전에 저장 한 JWT를 읽는 데 도움이 됩니다.
// getCookie()는 index.html 파일의 주석이 될 것입니다. 다음 코드로 대체하십시오.
// get or read cookie
function
getCookie(cname){
var
name = cname +
"="
;
var
decodedCookie = decodeURIComponent(document.cookie);
var
ca = decodedCookie.split(
';'
);
for
(
var
i = 0; i <ca.length; i++) {
var
c = ca[i];
while
(c.charAt(0) ==
' '
){
c = c.substring(1);
}
if
(c.indexOf(name) == 0) {
return
c.substring(name.length, c.length);
}
}
return
""
;
}
11.6 유효하지 않은 로그인에 대한 오류 표시
제출 된 이메일과 비밀번호가 유효하지 않은 경우 사용자 로그인 실패를 알리고 로그인 양식을 비웁니다.
// error response will be here comment of index.html 파일을 다음 코드로 바꿉니다.
error:
function
(xhr, resp, text){
// on error, tell the user login has failed & empty the input boxes
$(
'#response'
).html(
"<div class='alert alert-danger'>Login failed. Email or password is incorrect.</div>"
);
login_form.find(
'input'
).val(
''
);
}
11.7 출력
12.0 홈 메뉴 클릭시
12.1 홈 페이지를 표시하는 트리거 추가
아래 코드는 showHomePage(); 함수.
여기에 index.html 파일의 주석이 될 홈 페이지를 표시하는 // 트리거를 다음 코드로 바꿉니다.
// show home page
$(document).on(
'click'
,
'#home'
,
function
(){
showHomePage();
clearResponse();
});
// trigger to show account form will be here
12.2 로그인 메뉴 설정
showLoggedInMenu() 함수는 로그인 한 사용자를 위한 메뉴처럼 보이도록 메뉴 옵션을 변경합니다.
showLoggedInMenu()를 index.html 파일의 주석으로 대체합니다.
// if the user is logged in
function
showLoggedInMenu(){
// hide login and sign up from navbar & show logout button
$(
"#login, #sign_up"
).hide();
$(
"#logout"
).show();
}
// showUpdateAccountForm() will be here
12.3 JWT가 유효하지 않은 경우 로그인 페이지 표시
JWT가 유효하지 않은 경우 로그인 페이지를 표시하고 사용자에게 로그인을 요청합니다.
// show login page on error will be here be comment of index.html file을 다음 코드로 바꿉니다.
// show login page on error
.fail(
function
(result){
showLoginPage();
$(
'#response'
).html(
"<div class='alert alert-danger'>Please login to access the home page.</div>"
);
});
12.4 출력
13.0 사용자 계정 페이지 표시
13.1 계정 양식을 표시하는 트리거 추가
아래 코드는 showUpdateAccountForm();을 사용한 클릭 트리거를 보여줍니다. 함수.
계정 양식을 표시하는 // 트리거를 여기에 index.html 파일의 주석으로 다음 코드로 바꿉니다.
// show update account form
$(document).on(
'click'
,
'#update_account'
,
function
(){
showUpdateAccountForm();
});
// trigger for updating user account will be here
13.2 JWT가 유효한지 확인
사용자 계정을 업데이트하기 위해 HTML 양식으로 렌더링 하려면 showUpdateAccountForm() 함수가 필요합니다.
먼저 JWT가 유효한지 확인해야 합니다. 우리는 getCookie('jwt'); JWT를 가져와 jQuery $.post 메소드를 통해 validate_token.php로 보내는 함수입니다.
// showUpdateAccountForm()은 index.html 파일의 주석이 될 것입니다. 다음 코드로 바꿉니다.
function
showUpdateAccountForm(){
// validate jwt to verify access
var
jwt = getCookie(
'jwt'
);
$.post(
"api/validate_token.php"
, JSON.stringify({ jwt:jwt })).done(
function
(result) {
// html form for updating user account will be here
})
// error message when jwt is invalid will be here
}
13.3 JWT가 유효한 경우 계정 양식 표시
JWT가 유효하면 아래 코드를 사용하여 HTML 양식을 표시합니다.
사용자 계정을 업데이트하기 위한 // html 양식을 다음 코드로 바꾸십시오.
// if response is valid, put user details in the form
var
html = `
<h2>Update Account</h2>
<form id=
'update_account_form'
>
<div
class
=
"form-group"
>
<label
for
=
"firstname"
>Firstname</label>
<input type=
"text"
class
=
"form-control"
name=
"firstname"
id=
"firstname"
required value=
"` + result.data.firstname + `"
/>
</div>
<div
class
=
"form-group"
>
<label
for
=
"lastname"
>Lastname</label>
<input type=
"text"
class
=
"form-control"
name=
"lastname"
id=
"lastname"
required value=
"` + result.data.lastname + `"
/>
</div>
<div
class
=
"form-group"
>
<label
for
=
"email"
>Email</label>
<input type=
"email"
class
=
"form-control"
name=
"email"
id=
"email"
required value=
"` + result.data.email + `"
/>
</div>
<div
class
=
"form-group"
>
<label
for
=
"password"
>Password</label>
<input type=
"password"
class
=
"form-control"
name=
"password"
id=
"password"
/>
</div>
<button type=
'submit'
class
=
'btn btn-primary'
>
Save Changes
</button>
</form>
`;
clearResponse();
$(
'#content'
).html(html);
13.4 JWT가 유효하지 않은 경우 로그인 페이지 표시
JWT가 유효하지 않은 경우 사용자를 로그 아웃하고 로그인을 요청합니다.
jwt가 유효하지 않을 때 // 오류 메시지는 여기에 index.html 파일의 주석이 다음 코드로 대체됩니다.
// on error/fail, tell the user he needs to login to show the account page
.fail(
function
(result){
showLoginPage();
$(
'#response'
).html(
"<div class='alert alert-danger'>Please login to access the account page.</div>"
);
});
13.5 사용자 계정 업데이트를 위한 트리거 추가
제출 버튼을 클릭 한 경우 아래 코드를 사용하여 해당 트리거를 포착합니다.
양식 핸들과 JWT도 얻을 수 있습니다.
사용자 계정 업데이트를 위한 // 트리거는 여기에 index.html 파일의 주석이 될 것입니다.
// trigger when 'update account' form is submitted
$(document).on(
'submit'
,
'#update_account_form'
,
function
(){
// handle for update_account_form
var
update_account_form=$(
this
);
// validate jwt to verify access
var
jwt = getCookie(
'jwt'
);
// get form data and jwt here
return
false
;
});
// trigger to logout will be here
13.6 양식 데이터 및 JWT 가져 오기
아래 코드에서 양식 값을 가져와 여기에 JWT를 추가합니다. API로 보낼 수 있도록 stringify() 함수를 통해 양식 값을 JSON으로 변환합니다.
index.html 파일의 // get form data 및 jwt here 주석을 다음 코드로 바꿉니다.
// get form data
var
update_account_form_obj = update_account_form.serializeObject()
// add jwt on the object
update_account_form_obj.jwt = jwt;
// convert object to json string
var
form_data=JSON.stringify(update_account_form_obj);
// send data to api here
13.7 API로 데이터 보내기
jQuery AJAX 메서드를 사용하여 양식 값을 update_user.php로 보냅니다. 응답이 성공하면 사용자에게 계정이 업데이트 되었음을 알립니다.
새로운 JWT도 localStorage에 저장합니다.
index.html 파일의 // send data to api here 주석을 다음 코드로 바꿉니다.
// submit form data to api
$.ajax({
url:
"api/update_user.php"
,
type :
"POST"
,
contentType :
'application/json'
,
data : form_data,
success :
function
(result) {
// tell the user account was updated
$(
'#response'
).html(
"<div class='alert alert-success'>Account was updated.</div>"
);
// store new jwt to coookie
setCookie(
"jwt"
, result.jwt, 1);
},
// errors will be handled here
});
13.8 오류 메시지 표시
시스템이 사용자를 업데이트 할 수 없는 경우 사용자에게 이를 알립니다.
JWT가 유효하지 않고 액세스가 거부 된 경우 사용자를 로그 아웃하고 로그인을 요청합니다.
// 오류는 여기에서 index.html 파일의 주석을 다음 코드로 처리합니다.
// show error message to user
error:
function
(xhr, resp, text){
if
(xhr.responseJSON.message==
"Unable to update user."
){
$(
'#response'
).html(
"<div class='alert alert-danger'>Unable to update account.</div>"
);
}
else
if
(xhr.responseJSON.message==
"Access denied."
){
showLoginPage();
$(
'#response'
).html(
"<div class='alert alert-success'>Access denied. Please login</div>"
);
}
}
13.9 출력
14.0 사용자 로그 아웃을 위한 JAVASCRIPT 추가
14.1 로그 아웃에 트리거 추가
아래의 클릭 트리거는 사용자가 메뉴에서 로그 아웃 링크를 클릭 할 때 사용됩니다.
우리는 showLoginPage(); 사용자를 로그아웃 하는 방법. 우리는 그가 로그 아웃되었다고 말합니다.
// 트리거를 로그 아웃하려면 여기에 index.html 파일의 주석을 다음 코드로 바꿉니다.
// logout the user
$(document).on(
'click'
,
'#logout'
,
function
(){
showLoginPage();
$(
'#response'
).html(
"<div class='alert alert-info'>You are logged out.</div>"
);
});
14.2 출력
15.0 소스 코드 다운로드
먼저 위의 잘 설명 된 단계별 자습서를 따르고 공부하는 것이 좋습니다. 학습에 있어 경험을 능가하는 것은 없습니다.
하지만 최종 소스 코드도 볼 수 있다면 더 빨리 배울 수 있을 것입니다. 추가 가이드로 간주합니다.
16.0 다음은 무엇입니까?
AJAX CRUD Tutorial에서 데이터베이스 레코드 (사용자 인터페이스 포함)를 생성, 읽기, 업데이트 및 삭제하는 방법을 배웁니다.
등록된 댓글이 없습니다.