JWT Authentication in PHP
In this lesson: How JWT works and how to build token-based login in PHP — create, sign, verify and expire tokens with example code.
What is JWT
JWT (JSON Web Token) is a way to handle login for APIs. After a user logs in, the server creates a signed token and gives it to the client. The client sends this token with every future request to prove who it is — so the server does not need to store a session for each user.
The three parts of a token
A JWT looks like xxxxx.yyyyy.zzzzz — three parts split by dots.
| Part | Holds |
|---|---|
| Header | The signing algorithm (e.g. HS256) |
| Payload | The data — like user id and expiry |
| Signature | A check that the token was not tampered with |
The header and payload are just base64-encoded (readable), while the signature uses a secret key only the server knows.
How JWT login works
- The user logs in with email and password.
- The server checks them and, if correct, creates a signed JWT.
- The client stores the token and sends it in the header of each request.
- The server verifies the signature and reads the user id from the token.
- No server-side session is needed — the token carries the proof.
Using a JWT library
Do not build JWTs by hand — use a trusted library like firebase/php-jwt.
<?php
use Firebase\JWT\JWT;
$key = "your-secret-key";
$payload = ["user_id" => 5, "exp" => time() + 3600];
$token = JWT::encode($payload, $key, "HS256");
echo $token; // xxxxx.yyyyy.zzzzz
?>
JWT::encode signs the payload with your secret key. The exp field sets an expiry (here one hour), after which the token is no longer valid.
Verifying a token
<?php
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
try {
$decoded = JWT::decode($token, new Key($key, "HS256"));
echo "User id: " . $decoded->user_id;
} catch (Exception $e) {
echo "Invalid or expired token";
}
?>
On each protected request, decode and verify the token. If the signature is wrong or it has expired, decoding throws an error and you reject the request.
Common mistakes
- Putting secrets in the payload. It is readable — never store passwords or sensitive data there.
- Writing your own JWT code. Use a tested library to avoid forgeable tokens.
- No expiry. Always set
expso old tokens stop working. - Weak or exposed secret key. Keep the key strong and out of your code repository.
Summary
- JWT is token-based login, ideal for stateless APIs.
- A token has three parts: header, payload, signature.
- It is signed (tamper-proof) but not encrypted (readable).
- Use a library like firebase/php-jwt to encode and verify.
- Always set an expiry and keep the secret key safe.
Next, secure the data layer with prepared statements, or compare with sessions and cookies.
